Reviving ex in 20202020-08-05
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
Doing this with an existing editor requires me to do:
- Find the function
- Find the line that return starts on
- Select the whole expression (how this is done depends on the editor, but I don't think any of them have a text object to select an expression)
- Wrap it in a function (probably with a keyboard shortcut)
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:
- Find the function
- Find the return expression
- Wrap it in a function
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.
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
- Move the current working selection(s) to everything concerning the feature you are working on
- Bring up a couple of views to see what the current state of affairs is
- Make semantic changes
- If the feature still needs work save the views and working selections to a register while you work on something else, then come back later
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.
- No runtime overhead
- No limits on what is possible
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.
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.
- Getting a cursor to behave in a way usable by people is really hard.
- A data structure that can hold a large text file and update it quickly is quite complex, although xi managed it.
- The complexity of semantic features is massively increased by having the document checked on every keystroke, most of which will be while it is in an invalid state.
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.
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.
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, shtanton at shtanton.xyz