Reviving ex in 2020

2020-08-05 15:27:08

I think programming oriented text editors in 2020 still feel like they’re missing a lot, and I think that a modern editor more like ex could fix most or all of these problems. Here’s why.

Minimise the brain to editor gap

The way I tell my editor what to do, should closely match the way I think about what to do.

For example: I think I want to pass the return expression of a function through another function, return expr; to return modified(expr);.

Doing this with an existing editor requires me to do:

The really annoying part here is selecting the expression, which either has me using a mouse (eurgh) or using a keyboard shortcut that will work here but wouldn’t in other places. Here I could jump forward one word to get to the start of expr and then go to the end of the work, or until the ;, but these couldn’t handle an expr spanning multiple words or one that contained a ;.

This is work my brain does which the editor could do, the process should be:

I’m not thinking about text when I think about a code change, I’m thinking about semantics, so the operations I’m dictating to the editor should be semantic.

Edit code not text

Editors have drifted towards more semantic features for ages now, with language server protocol, paredit and ctags being excellent examples of the demand for semantic editors. Even with these, the editor feels like a text editor with semantic features and not a semantic editor.

If ex is a line editor, we should aim for an AST editor.

Instead of printing ranges of lines, we could print function signatures, or globally defined types, or construction sites of a struct. This feature doesn’t necessarily require an editor like ex, but the large number of motions available with this system would likely require at least a modal editor, so why go even further and abandon the whole visual interface?

A cursor only makes sense for inserting

This is something that I think is obvious now I’ve realised it, but because of its universal use, I hadn’t considered before.

Why do I need a cursor while I’m viewing/moving/deleting code?

Obviously for just looking at the code, a cursor is pointless and losing it allows for the more customisable views I mentioned earlier, but for doing anything other than inserting in a modal editor it boils down to moving the cursor roughly to the site of the edit and then specifying the text object and the action. This means that the sequence to do a change often relies on where the cursor is now, as that dictates which motion you use to get it where the change is happening. This is more unnecessary brain work, but globally specifying the site of an edit relative to the project root is worse. Ideal is in between.

A shell for code

How about instead of a working position (cursor), a working area, much like the current working directory in a shell. With this idea comes the realisation that what we’re approaching is fundamentally a shell for manipulating code instead of a file system, which is a brilliant idea. I used to use a graphical file browser to work with file systems, but having got so proficient with the shell, it’s now faster for me to use that. It is also vastly more powerful. Only focusing on a single code object at a time would also be cumbersome, but why not have a working selection be many objects, and have registers for these selections to be saved to and loaded from? File systems and code are both trees, but files basically just have names, and you aren’t really concerned with the contents while browsing. Not so with code. So again a middle ground is needed.

The display

Ex requires if you want to see some code you specify which code you want to see using some line numbers or regex etc. The new editor can have more advanced ways of selecting what to see, but it is still not gonna be usable if you are constantly printing the same bit to see your changes. I propose printing creates a window with that view of the code, and it updates with any changes you do, as you do them.

To clarify, it is only displaying, no cursors allowed. The option for the simpler printing should still be there, as it would be useful for shell scripts or editing over ssh.

The theoretical workflow

Customisation

These days everything has a massive config file and an API to allow you to bend the software to your will. Being able to configure software is certainly a good thing, but config files, GUI settings menu, an extra program to send messages over sockets, an entire interpreted language etc. these are not the way to do config. Suckless gets this right. Their software is configured by modifying the source code.

A lot of people might think

Modern text editors are highly complex! How could I possibly tweak the source code?

This problem has 2 solutions, don’t tweak the source code, or make the code simpler and more understandable. Pretty much everyone took the wrong path here.

In June of 2019, I fixed a tiny bug in vim, PR 4584. It took me over 4 hours to figure out how the code worked, and vim is maybe the simplest editor usable for day to day programming.

Simplicity

Up until now I’d understand if thought I just needed an IDE, but here’s why you’re wrong. If you haven’t already, maybe read Text Editing Hates You Too which highlights some of the pains of making modern text editing software.

Ex doesn’t have a cursor which removes pretty much all of this complexity. To insert text you select where it’s going to go, then enter it all in as a block. Checks only happen once when the block is actually inserted, meaning structures and algorithms for handling the text and semantic features can be slightly slower and much simpler. Plus, the cursor when working on a block can be simple, just typing and backspace. A mistake too big for backspace can be fixed with another command. This will allow for a much simpler codebase.

Also special mention to electron apps which get around this complexity by being unacceptably sluggish.

Learning curve

Although the source code will be a lot simpler than most projects, it’s still an editor drastically different from every other currently in use.

Being usable by everyone, for everything, is not a goal.

It would be suited for power users who are happy to invest significant time into learning to use it fully before being productive, and even then probably will at best make you marginally more productive. But that would be enough for me!

Why aren’t these features already being used?

Most of them just because this whole idea is crazy outlandish. The one that could is the semantic features, but these features tend to be incredibly hard to implement in a way independent of the language being edited. The best we have currently is LSP which is language and editor agnostic, but not even close to what I want out of a new editor. This new editor would have to be (at least initially) specific to a language as finding abstractions that allow it to work on any language would be incredibly difficult. Only once it has a foothold would that be worth pursuing, maybe as semantic features in other editors grow, this issue will be solved though.

Conclusion

This is mostly just me playing with ideas. I don’t know how this would actually look and feel in a real editor, but I plan on finding out. Maybe there’ll be a another post one day with details of a working usable editor, based on ex that I’ll have written. Maybe someone else will see these ideas and agree with one or two of them and build something new and impressive. Maybe all my ideas suck and I’m completely dillusional. Either way I’d appreciate you letting me know any thoughts this has provoked via my email, charlie@shtanton.com