A modern UNIX ed (line editor) clone written in Go

ed (the awesome UNIX line editor)

CodeCov Go Report Card CodeBeat GitHub license

ed is a clone of the UNIX command-line tool by the same name ed a line editor that was nortorious for being and most unfriendly editor ever created.

This is a modern take on that editor writtein in the Go language for portability with all the basic ed commands, a modern readline line editor with vi bindings and friendly error messages when things go wrong.

Quick Start

Install ed with a valid Go environment using go get:

$ go get github.com/prologic/ed

Or install from published binaries for your platform from the Releases page.

And edit files to your heart's cntent :)

$ ed
> a
Hello World!
.
> ,p
Hello World!
> q
WARN[0025] buffer has modifications not written
> Q

For help on how to use ed in general please refer to this excellent guide:

Or the GNU ed manual

NOTE: This port/clone does not implement all ed commands, only a subset.

Example

Here is an example ed session:

$ ed
> a
Start typing a few lines.
Anything you want, really.
Just go right ahead.
When you're done, just type a period by itself.
.
> p
When you're done, just type a period by itself.
> n
4    When you're done, just type a period by itself.
> .n
4    When you're done, just type a period by itself.
> 3
Just go right ahead.
> .n
3    Just go right ahead.
> a
Entering another line.
.
> n
4    Entering another line.
> i
A line before the current line.
.
> n
4    A line before the current line.
> c
I decided I like this line better.
.
> n
4    I decided I like this line better.
>

Commands

This implementation supports the following commands: (not all commands from the original ed are supported nor the GNU ed)

Command Description Notes
`` newline Null command. An address alone prints the addressed line. A alone is equivalent to '+1p'. The current address is set to the address of the printed line.
!shell exec shell Executes a shell command with sh(1).
= print index Prints the line number of the addressed line. The current address is unchanged.
a append text Appends text to the buffer after the addressed line. Text is entered in input mode. The current address is set to the address of the last line entered or, if there were none, to the addressed line.
c change lines Changes lines in the buffer. The addressed lines are deleted from the buffer, and text is inserted in their place. Text is entered in input mode. The current address is set to the address of the last line entered or, if there were none, to the new address of the line after the last line deleted; if the lines deleted were originally at the end of the buffer, the current address is set to the address of the new last line; if no lines remain in the buffer, the current address is set to zero.
d delete lines Deletes the addressed lines from the buffer. The current address is set to the new address of the line after the last line deleted; if the lines deleted were originally at the end of the buffer, the current address is set to the address of the new last line; if no lines remain in the buffer, the current address is set to zero.
e file edit file Edits file, and sets the default filename. If file is not specified, then the default filename is used. Any lines in the buffer are deleted before the new file is read. The current address is set to the address of the last line in the buffer.
E file force edit Edits file unconditionally. This is similar to the 'e' command, except that unwritten changes are discarded without warning.
f file set filename Sets the default filename to file. If file is not specified, then the default unescaped filename is printed.
`g /re/command global Global command. The global command executes command for every matching line matching the regular expression re.
i insert text Inserts text in the buffer before the addressed line. The address '0' (zero) is valid for this command; it places the entered text at the beginning of the buffer. Text is entered in input mode. The current address is set to the address of the last line entered or, if there were none, to the addressed line.
j . join lines . Joins the addressed lines, replacing them by a single line containing their joined text. If only one address is given, this command does nothing. If lines are joined, the current address is set to the address of the joined line. Else, the current address is unchanged.
m n move lines Moves lines in the buffer. The addressed lines are moved to after the right-hand destination address. The destination address '0' (zero) is valid for this command; it moves the addressed lines to the beginning of the buffer. It is an error if the destination address falls within the range of moved lines. The current address is set to the new address of the last line moved.
n numbered Number command. Prints the addressed lines, preceding each line by its line number and a . The current address is set to the address of the last line printed.
p print lines Prints the addressed lines. The current address is set to the address of the last line printed.
q quit Quits ed. A warning is printed if any changes have been made in the buffer since the last 'w' command that wrote the entire buffer to a file.
Q force quit Quits ed unconditionally. This is similar to the q command, except that unwritten changes are discarded without warning.
r file read file Reads file and appends it after the addressed line. If file is not specified, then the default filename is used. If there is no default filename prior to the command, then the default filename is set to file. Otherwise, the default filename is unchanged. The address '0' (zero) is valid for this command; it reads the file at the beginning of the buffer. The current address is set to the address of the last line read or, if there were none, to the addressed line. If file is prefixed with a bang (!), then it is interpreted as a shell command whose output is to be read, (see shell escape command '!' below). In this case the default filename is unchanged.
R replace line Puts the editor in replace mode putting the currently addressed line in the input buffer permitting modifications to the line and replacing it.
s /re/replacement search and replace Search and replace command. Replaces all occurances of re with replacement on the first matched line in the address range.
t n transfer text Copies (i.e., transfers) the addressed lines to after the right-hand destination address. If the destination address is '0' (zero), the lines are copied at the beginning of the buffer. The current address is set to the address of the last line copied.
v /re/command inverse global This is similar to the 'g' command except that it applies command-list to each of the addressed lines not matching the regular expression re.
w file write file Writes the addressed lines to file. Any previous contents of file is lost without warning. If there is no default filename, then the default filename is set to file, otherwise it is unchanged. If no filename is specified, then the default filename is used. The current address is unchanged.
wq file write & quit Writes the addressed lines to file, and then executes a 'q' command.
x put text Copies (puts) the contents of the cut buffer to after the addressed line. The current address is set to the address of the last line copied.
y yank text Copies (yanks) the addressed lines to the cut buffer. The cut buffer is overwritten by subsequent 'c', 'd', 'j', 's', or 'y' commands. The current address is unchanged.
z n scroll Scroll n lines of text from the addressed line.

Why?

If you've gotten this far and wondering "Why?":

  • For fun primarily :)
  • As a learning exercise
    • I wanted to learn how ed works

And just to prove this version of ed is actually a useful editor; the following commits were made with this ed:

Differences between GNU Ed

Some of the of the main differences between this implemtnation (written in Go) and GNU Ed or even the traditiaional UNIX Ed are is the way I've handled parsing. In tranditional UNIX / GNU Ed you can do things like:

  • Better error handling by default
  • Syntax highlighting
  • Not all ed commands are implemented
  • Being written in Go the binary is a bit fatter than the ones written in C :)
  • Probably other minor differences and quirks...

License

ed is licensed under the terms of the MIT License

Owner
James Mills
"Problems are solved by method." 📕 Follow me on https://twtxt.net/user/prologic
James Mills
Similar Resources

A go library for easy configure and run command chains. Such like pipelining in unix shells.

go-command-chain A go library for easy configure and run command chains. Such like pipelining in unix shells. Example cat log_file.txt | grep error |

Dec 27, 2022

Pack a Go workflow/function as a Unix-style pipeline command

Pack a Go workflow/function as a Unix-style pipeline command

tpack Pack a Go workflow/function as a Unix-style pipeline command. Wiki In Unix-like computer operating systems, a pipeline is a mechanism for inter-

Nov 9, 2022

Pty is a Go package for using unix pseudo-terminals.

PTY interface for Go

Jan 6, 2023

PickleShell - best shell for unix-like os

PickleShell - best shell for unix-like os

🥒 PickleShell shell for super users Compilation Windows go build -o PickleShell.exe

Nov 8, 2021

NYAGOS - The hybrid Commandline Shell between UNIX & DOS

NYAGOS - The hybrid Commandline Shell between UNIX & DOS

The Nihongo Yet Another GOing Shell English / Japanese NYAGOS is the commandline-shell written with the Programming Language GO and Lua. There are som

Dec 30, 2022

Modern ls command with vscode like File Icon and Git Integrations. Written in Golang

Modern ls command with vscode like File Icon and Git Integrations. Written in Golang

logo-ls modern ls command with beautiful Icons and Git Integrations . Written in Golang Command and Arguments supported are listed in HELP.md Table of

Dec 29, 2022

A better way to clone, organize and manage multiple git repositories

A better way to clone, organize and manage multiple git repositories

git-get git-get is a better way to clone, organize and manage multiple git repositories. git-get Description Installation macOS Linux Windows Usage gi

Nov 16, 2022

😎 Yet Another yes clone but in Golang

Yeah Output a string repeatedly until killed. Yet Another yes clone but in Golang. Usage Just like yes: yeah This will print "y" until the process is

Apr 7, 2022

Spotify clone server for golang

Spotify clone server for golang

Spotify-clone-server Written by 💪 rasulov-emirlan 💅 sultanaliev-s 🧠 Howe to use this server 🤷 create repository called "database" right next to th

Aug 31, 2022
A command line tool for quickly converting Unix timestamps to human readable form.

stamp A command line tool to quickly format a Unix timestamp in a human-readable form. Installation Go is required to build this software. To just bui

Oct 30, 2021
A command line utility that automagically replaces UNIX timestamps with human interpretable timestamps.

Unfy unfy is a command line utility that automagically identifies and translated UNIX timestamps (since epoch) to human readable timestamps. Example B

Oct 22, 2022
Pure Go line editor with history, inspired by linenoise

Liner Liner is a command line editor with history. It was inspired by linenoise; everything Unix-like is a VT100 (or is trying very hard to be). If yo

Jan 3, 2023
Command line editor for Discourse

Edit Discourse topics locally The discedit tool allows you to edit Discourse topics in your favourite local text editor. It works by pulling a topic f

Nov 15, 2021
go-editor is the clean go module that refractors from Kubernetes to help you edit resources in a command-line way.

go-editor The source code of go-editor comes from Kubernetes and refractor as the clean Go module. You can embed go-editor in your command-line tool l

Dec 5, 2021
Basic CLI save editor for Medieival Dynasty written in Go.
Basic CLI save editor for Medieival Dynasty written in Go.

Medieival-Dynasty-save-editor Basic CLI save editor for Medieival Dynasty written in Go. Windows binaries Usage Backup your saves first. Made for GOG

Apr 12, 2022
🚀 goprobe is a promising command line tool for inspecting URLs with modern and user-friendly way.

goprobe Build go build -o ./bin/goprobe Example > goprobe https://github.com/gaitr/goprobe > cat links.txt | goprobe > echo "https://github.com/gaitr/

Oct 24, 2021
Package command provide simple API to create modern command-line interface

Package command Package command provide simple API to create modern command-line interface, mainly for lightweight usage, inspired by cobra Usage pack

Jan 16, 2022
Sipexer - Modern and flexible SIP (RFC3261) command line tool

sipexer Modern and flexible SIP (RFC3261) command line tool. Overview sipexer is

Jan 1, 2023
The slightly more awesome standard unix password manager for teams
The slightly more awesome standard unix password manager for teams

gopass Introduction gopass is a password manager for the command line written in Go. It supports all major operating systems (Linux, MacOS, BSD) as we

Jan 4, 2023