/edj

Pronounced "edge". Tiny subset of unix ed(1) in Java.

Primary LanguageJavaBSD 2-Clause "Simplified" LicenseBSD-2-Clause

Fork of Ian Darwin’s Edj for Data Structures and Algorithms Final Project

My Data Structures and Algorithms project is meant to give me an opportunity to better explore data structures as they may be used in real software. I’ve always found stacks to be interesting, and I felt that a great example of their use could be in dealing with edit histories, which lead me to look into writing a text editor since that would likely give me a few more structures to work with as well.

I came across Ian Darwin’s excellent article about building a text editor in Java when I was deciding on what to do for this project. I found his article to be a great read and I would highly recommend reading his series on building edj if you are interested in learning more about building a text editor.

I noticed that Ian writes about implementing an undo feature and provides some code that implements an undo feature. I thought that it would be a bit of an interesting challenge to reimplement the undo feature in a way that also supports redoing. I decided to make this my main focus instead of writing an entire editor from scratch for my project. The general idea here involves dealing with tracking changes through a sort of dual-stack system using an undo and a redo stack, which I thought could be abstracted into it’s own sort of data structure/class as well. Building this dual-stack undo/redo structure is the focus of my project.

edj, sedj, and vedj

Edj (pronounced like the English word "edge") is the skeleton of a simple line editor patterned after Unix ed(1). sedj is the stream editor - a tiny subset of Unix sed(1). vedj is - wait for it - the visual edj. The names all rhyme.

It was not created to be a useful editor - you cannot yet save your work! - but to provide a platform for some demonstrations of Design Patterns and related issues, particularly in the Java language, including the "undo" command. If someone (or even me) tries to turn it into a useful line editor, you’ll know that CLI fans have regained the upper hand in geekdom. Or not.

It was also written to show that you can, in fact, do something small and (possibly) useful in Java without dragging in 47 different add-on JAR files. This project has zero external run-time dependencies and only one test-time dependency (JUnit).

Note that the BufferPrims code has changed slightly from the version shown in Part 1 of the article, appearing in the July/August issue of Java Magazine, due to the need to support a screen editor as well. If you want that exact version, use git checkout edj_article.

Usage

  • Compile and package:

	mvn package
  • Copy the edj and vedj scripts to a directory on your path (for MS-DOS-derived systems, somebody needs to write DOS bat files to do the same thing).

  • Copy the JAR file from target/ to someplace like $HOME/lib/

  • Hack the scripts script to find the jar file there.

Invoke with a filename argument, or, start with an 'r' (read file) command.

Commands are single lower-case letters (or '.' or '=') Command lines are of the form start,endCOMMANDoperands

The line range start,end is optional; if omitted altogether the current line (most recently added or modified, or clicked on in vedj) is meant. If only one line is intended, omit the comma and the second number. A command line that consists only of a line number will move the current line to that number.

The original ed's special line number '$' (dollar sign) meaning 'last line' is not yet implemented. Line numbers beginning with '+' or '-' are not implemented. The special filename syntax beginning with '!' ('bang' or exclamation mark) will not be implemented.

The following commands are implemented so far:

Table 1. Implemented Commands
Name Stands for Notes

.

Current

Print the current line

=

Line numbers

What are current and dollar(last-line) equal to?

a

append

Type lines, end with "." on line by itself

d

delete

e

edit

load a new file and make it the current file

f

filename

Print or set the current filename

p

print

Print the line or lines

q

quit

Does not currently prompt for unsaved changes

r

read

read named file into buffer

s

substitute

[linerange]s/old/new/[g][p] - replace old (regex) with new (text), once per line unless g

u

undo

Undoes last modify command

The following are not implemented:

Table 2. Unimplemented Commands
Name Stands for Notes

b

-

c

change

combines delete with append

g

global

Not implemented, but g/RE/p is the origin of the grep command’s name.

h

-

i

insert

Like 'a' but inserts before current line

j

join

merge current line and next line into one line

k

marK

l

list

Like p but expands unprintable characters

m

move

n

-

o

-

t

transfer

Copy lines

v

inVert

like g but does non-matching lines

w

write

write to current file if any, or named file

x

?

encrypt file

y

-

z

-

:

extension

That would start down the path from ed to ex, and then vi. Not on my watch.

History

When computers were very young, there were no graphics systems for them, no touchscreens, no mice, only "terminals" that read from a keyboard and printed on paper. It was in this era that line editors were the dominant way of editing text for program source code, emails, instant messages, and so on.

An ed command that is recognizably the origin of this family of tools appeared in Version 1 of AT&T Bell Labs Research UNIX around 1970.

Versions of ed have been in every flavor of Unix (including *BSD and Mac OS X), and in every Unix-like system (Linux etc.), since then. Berkeley Unix mutated ed into ex, and then added visual editing mode, which became the vi editor, in the late 1970’s. Vi still has ex (and hence ed) line mode editing built in.

So this project is a months-young implementation of a fifty-year-old specification.