So… Atom is in zombie state. Almost everything kinda works but not 100% works so the idea of a “Hackable Text Editor for the 21st Century” is almost dead. LightTable is buried, and it was not as hackable as Atom. And there’s VSCode – a closed-source, telemetry enabled, Microsoft controlled editor based on an open-source model that’s kinda the Webkit model – you have to fork the editor and make your changes, because they control the available APIs, the way that the editor is going, etc.
So what we have now? To be honest, not much. There’s emacs and Vim/NeoVim, but these are all text-based and have both people that love them and people that hate. It’s also not that easy to make plug-ins and configurations (one you have to learn elisp, and the other you can use a mix of multiple languages like VimL, Lua, Node.JS, Python, but they all feel “out-of-place”.
Let’s try to make a new editor? Maybe that’s insanity, so let me tell you what I have in mind:
Let’s not start from scratch
Starting for scratch is the recipe for failure. Most people want things that we take for granted on our editors: Vim Mode, Keymaps, Goto Var Definition (even if it’s not that good or reliable, like it depends on CTags or other thing), autocomplete (again, don’t need to be perfect, but at least get a text that you already typed, sorting by how close your cursor is in, etc) Syntax Highlight, etc. If we don’t have these things, not even the author of the editor will use it. One of the most interesting things about Chlorine, for example, is that I use it to develop itself, so I can guarantee that’s working.
To not start from scratch, we have some options: LightTable, Atom, Code-OSS (the open-source, telemetry enabled version of VSCode), NeoVim (and maybe NyaoVim), Theia, Nightcode, Salza λiquid, etc. I would prefer to go to more “feature rich” editors, so not Nigthcode or λiquid.
Plug-ins all the way down
Atom got something right: almost everything that appears on the editor is a plug-in. So even tabs, the project manager, files, fuzzy-finder and command palette are plug-ins. This would be the best way to go: if we go to this route, the contribution for the editor is also smaller: one can just fork the plug-in, add his contribution, and then make a PR on a smaller (maybe 1.000 lines at most) codebase and that’s it.
It’s also more hackable: you don’t need to fork the editor, you can just add your contribution and that’s done. So you can disable a “core” plug-in and enable a “customized” plug-in and everything works the same.
But, if you look at Atom’s memory usage, you’ll see that the memory goes up the more plug-ins you have. That’s because they wrongly decided to use the Node.JS ecosystem fully – so if you install a plug-in, it’ll npm install
dependencies. This will clutter your .atom/packages
folder, and also will add these dependencies to the Node.JS JIT, etc, making it consume more memory. There’s also another problem: there is a way to only start the plug-in when you open a specific source file, or when you run a specific command, but most plug-ins don’t do that – they are loaded all the time. So it’s completely feasible to do an editor 100% based on plug-ins that’s lower on memory.
There’s also a thing that Atom did wrong: they could expand more into plug-ins. For example, the Text Editor itself could be a plug-in; the menu, the “var definition” (well, nowadays it don’t matter anymore because Language Server Protocol is a thing), etc. But anyway…
Not reinvent the wheel
When you look at Atom, there’s LOTS of internal packages. Theres @atom/nsfw
, @atom/watcher
, etch
, etc. To be sustainable, it’s better to use community packages as much as we can.
One great idea is to make the whole editor hot-reloadable. I’m not sure how to do this without ClojureScript, so maybe that’s the way to go. This could also ease a lot of development time, and make it possible to have a smaller team working on this project. Obviously, this means that more and more code will be ported to ClojureScript, so we’ll have to take extra caution on code quality (and tests) so that new teams can handle that.
The current state of editors
Now, maybe we can look at each editor (and I’m trying REALLY HARD to not be biased – I’ll even sort the list in alphabetical order!) and see what we can use, re-use, etc:
Atom editor
The idea of plug-ins is great. There are lots of things that already are done in Atom, and are just plug-ins, not parts of the editor: tree view, command palette, fuzzy finder for files, etc. Atom is also quite easy to read – there’s no “internal API protection” (I’ll show in a next editor what this means).
The trouble with Atom is it precedes Electron – so there’s LOTS of strange things like calling APIs that don’t exist in modern Electron versions, and things like importing Electron that don’t play well with newer versions. It also uses internal packages for things that we today have better alternatives: for UI, etch
, for watching files, it uses nan
with some internal Node.JS elements, etc, and these are slow alternatives that what we have today.
CodeMirror
One idea could be use CodeMirror to have the editor, and construct a somewhat IDE over it. This also means that most things need to be constructed “from scratch” and we probably will have to add a way for plug-ins to talk to CodeMirror.
Eclipse Theia / VSCode (Code-OSS)
Code-OSS is stable, it’s written in Typescript, and there’s a huge company behind it (Microsoft). Eclipse Theia is kinda a clone of Code-OSS, to the point that one probably can’t see the difference. VSCode is the proprietary version of Code-OSS (it’s a merge of a private Microsoft repository with the public, MIT source). Using Code-OSS would benefit from the HUGE amount of extensions that exist today, and the stable nature of the editor. Code is filled with telemetry, but there’s a script of VSCodium github that disables it. The other interesting thing is that there’s already a public marketplace (OpenVSX from Eclipse) where we can publish and get extensions.
The problem with Code-OSS is that it’s not modular, so the idea would be to fork the editor, “patch” it so it becomes more programmable/hackable, and then keep the changes on the codebase to a minimum (otherwise we’ll loose all the benefits of using Code in the first place). The other problem is that Code is not a hackable editor – the API is used to allow the user to add some kind of customizations, but also to “protect the editor” from misbehaved plug-ins. What you can do and what you can’t is completely controlled by Microsoft, so there’s no way to “bypass” limitations. Yes, it’s written in Typescript, but the code is made in a way that’s hard to “monkey patch” the editor so you can bypass these limitations. This also means that the code is really complicated to read – both Code and Theia.
For example, Atom have 1,400 lines of CoffeeScript code, and 54,134 lines of JS. Code have 33,736 lines of Javascript code, and a whooping 879,840 lines of Typescript.
LightTable
LighTable is a dead editor. It was written in ClojureScript, but a really old version. So, to use it, we would need to at least convert to Shadow-CLJS and make it compile. I have no idea what’s the code quality and how easy would be to do it.
The problem with LightTable is mostly documentation and how to make plug-ins. They decided to use (or invent, I’m not sure) a new way of communicating between elements: they call it Behaviors, Objects, Tags. There’s few to no documentation on how this works, and if we decide to use LightTable we probably will need to migrate this concept to, maybe, re-frame or something more modern that people know how to use.
One trouble is the lack of plug-ins. It’s also not clear how stable it is (I remember having trouble trying to create the Parinfer plug-in for it).
Monaco
Monaco is the VSCode / Code-OSS editor, that works for web. It is JUST the editor, no “ide elements” or anything. This could be used in place of CodeMirror, for example, and maybe construct the other “IDE elements” over it. I remember seeing that Monaco had some kind of support for LSP, so maybe we could even re-use VSCode plug-ins on it. Monaco is also less “constricted” – for example, we can add decorations between lines, so it may be even better to hack.
NeoVim / NyaoVim
NeoVim is not graphical, but NyaoVim is – it runs on Electron and it offers a webview API. It’s hard to think on how to modernize both, because we’ll need to somewhat add lots of translation layers for NeoVim to work better with new users. It’s also complicated because both Vim and Emacs users are quite passionate about their editors, so we tend to not see the problems we have (I know that – I’m on Vim team myself). The idea for a hackable editor needs to be to allow users to adapt everything to their workflows, so maybe it’s not a good idea to use NeoVim.
Things that I would LOVE to have
Queryable editors! I mean, APIs are great and all, but a great idea could be to simply make everything query-able by default. So instead of remembering lots of APIs, maybe it’s better to just query for the info. I mean, a = atom.workspace.getActiveTextEditor; [a.getText(), a.getCurrentCursorRange()]
works, but maybe it’s simply better to have (query [{:editor/active [:text/contents :text/range]}]
. It may be better because we can handle things more easily: (query [{:editor/all [:text/contents :file/full-path]}])
is easier to remember, we don’t have to cycle between editors, and it’s WAY easier to just make things work.
One neat idea could be to also have a “Facade / Adapter” over most plug-ins. This means that a user could change completely the look, and even the behavior, of the editor and we somewhat would be able to keep the same API (for example, maybe the user could completely replace the editor for another thing, and for plug-ins, the editor itself, etc this will be transparent).
Other things are structural editing (not the “lisp one” – more like “edit this function on this file, this other function on this other file and give me two editors side-by-side”). Something like CodeBubbles, or a way to allow users to define their own layout.
One incredible feature we could have is Smalltalk-like envs. For example, instead of trying to edit text files, we could somehow parse (with LSP, or whatever the language offers) the whole source files and then show all functions/classes/methods/any structure inside the editor, and then edit then individually, in a group, or maybe even see a graph of dependencies. Obviously, this also means that the editor should be 100% configurable so any user could design a new widget for the editor, but that’s kinda what we’re aiming here, so it’s inside these ideas.
Let’s get real?
So, the first release should at least do what a VSCode / Atom version already do, without any plug-ins. This, I believe, is the minimum acceptable – otherwise, people will not jump into the boat and keep using their own editors. In fact, I’m quite inclined to say – if we don’t use this editor to develop itself, we failed.
Will I do it? I don’t know. I’m kinda trying a call for arms. This could be a big project, and I’m sure a single person is not able to handle everything. I’ll probably keep updating this post with new info and new editors we can use to bootstrap the project, and even show progress (or failure of).
So… let’s do it?