My dream text editor
I’ve been using Vim as my main text editor for a long time. I also tried to use Emacs for around one year (With Evil mode) and I appreciate some of the ways that Emacs deal with text editing and customization. For the most part my workflow remained the same and I liked both editors. Ultimately I found Emacs slow and unresponsive in many cases where Vim was blazing through it, and in pursuit of simplicity I just ended up using Vim full time once again.
I would say I feel comfortable with Vim, but from time to time I run into annoyances and minor frustrations. I’ve tried to solve some of these but never quite manage to get where I wanted to get. Neither Vim 8 or NeoVim (my current Vim implementation of choice) addresses these issues.
My dream editor
For a while I’ve fantasized with creating my own hobby text editor tailored to my preferences and idiosyncrasy and if I were to do that, here are some things I would like to have, in no particular order:
- A modal approach to text editing (Normal, Insert, Visual, Replace). A subset of Vim’s commands should be implemented for movement and editing.
- The program should be implemented so that it would be trivial to implement a frontend in any way we wished. For example, I mostly edit text in the terminal with tmux, but sometimes I would like to have access to a graphics implementation that could work in multiple operating systems, supporting things like smooth scrolling and other goodies. Likewise, I would like to be able to integrate this editor as a library in any project, so that it could be used with custom tools (i.e. debug tools in graphical applications).
- No server/client distinction. The code is compiled into a binary object, this can be linked with the frontend or the tools we want either dynamically or statically.
- Because of the previous items, we should consider to work with text buffers in a similar way as Emacs, dealing with buffers and commands.
- Fuzzy search for opening files. This should be project aware, so
that we only look at the files in the
.git
or version control repository or we could choose to recursively search all directories up to a maximum depth. There should be a way of searching by exact matches, for example by prepending a quote, like in thefzf
utility (fzzy 'exact-search
). - Document and project-wise search and replace with support to regular expressions.
- Context aware or specific selection of autocompletion.
- Default support for version control operations (like Magit in Emacs or Fugitive in Vim). This should be limited to the common operations that involve editing text and perhaps for resolving merge conflicts.
- All search/completion operations should be non-blocking. Interactivity and responsiveness is king.
- Support for editor commands (
C-x
in emacs or:
in Vim) which will get auto-completed as we type. - Support for spellchecking, grammar and/or thesaurus search.
- Support smart auto-indentation in specific languages
- The editor could be configured with a simple .ini text file or via recompilation.
- Plugins could be added as C modules, either dynamically loaded or statically compiled.
- Fast syntax highlighting. I use it very slightly but at least I like my comments and imports to be highlighted.
- Should be able to open gigantic files. By default, large files will be opened in read only mode (Which could be more efficient) but if desired we can jump into read-write with a command. Operating in these files should be fast, including searching them.
- Support for macro recording. They should be easier to use than in
Vim and work with the
.
repeat command. - Undo/Redo tree (Quite obvious). There is some considerations about permanently keeping track of these undo/redo trees per file up to a maximum. Note that this could pose a security risk, although we could try to encrypt it in some way.
- Compilation and compilation messages in compilation buffers. For
example, I should be able to run
:make
or the appropriate shortcut and the compilation should start. If there are any errors, we should have direct jumps to those in the code (copen
in Vim). As mentioned before, this should be done in parallel if possible. - We should be able to pipe commands to the editor and buffers to commands. Also, we should be able to run shell commands from the editor directly to paste the output there. This can be tricky for multiplatform support, however.
- Unicode support by default please.
- Possible to switch easily from binary/hex to text, including editing.
- Command search supports fuzzy-find parameters.
- Potential integration with GDB or other debuggers.
- Async when needed (Important for responsiveness).
Algorithms and data structures
Here are some algorithms that would be interesting to explore for the implementation of the internal structure:
- Emacs style “gap buffer” algorithm.
- Rope data structures as used in Xi editor.
- Piece table data structure
- Piece table method
Piece table conerns
This doesn’t seem like a big deal to me to be honest but here is the opinion of someone who clearly knows what they are doing:
There’s one other important concern with piece tables I didn’t see addressed. It depends on the file contents on disk not changing. If your file system supported locking or the ability to get a read-only snapshot, this would be fine, but in practice most don’t. It’s very common, say, to checkout a different git branch while the file is open in the editor. Thus, the editor must store its own copy to avoid corruption. In the long term, I would like to see this solved by offering read-only access to files, but that’s a deeper change that can be made piecewise. - Raph Linus
Resources
- The Craft of Text Editing (or Emacs for the Modern World)
- Data structures used in text editors
- Data structures in the Andrew text editor