I’ve written before about how I’m not happy with the code editors available today. I think they can be improved upon, so I’ve started experimenting with making my own. I don’t think this will ever be the shiny new code editor on the block, but I’m hoping it’ll at least be something I’d prefer over other editors.
I’m currently calling this project Qode, but I might change that further down the line—especially since I’ve already seen other similar projects with the same name.
I’m not sure how far I’ll take this, and might not even make this a huge thing, but I want to outline part of the vision for this editor. I think doing so will help me stay focused on what to work on next, and whether I’m spending too much time digging into something I don’t need to think about.
So, without further ado, let’s get into it.
Graphical interface please!
I dislike the limitations of terminal editors, and as such I want the editor to have a graphical interface (GUI). That said, I also want this interface to be minimalistic. Most of the time it shouldn’t be showing you anything beyond what a terminal editor would show you.
What I mean by this is that most of the time the only thing visible in the editor should be the text editing window itself. No toolbars, no sidebars, no fluff.
That doesn’t mean those won’t be available, mind you! Just that they shouldn’t be visible by default. Instead, you should be able to bring them to focus with a keyboard shortcut (e.g. double-tap tab, hold shift, etc.) or a single mouse-click/hover action.
I want the editor to get out of the way when you’re writing code, and I think modern editors fail when it comes to this, what with all their sidebars and toolbars.
I want the GUI to be fully accessible with just a keyboard. Or at the very least, you should be able to control every aspect of the editor with a keyboard.
I’m not really talking about navigating menus with a keyboard (although that should be possible either way), instead I’m thinking of a sort of command mode, similar to Vim, Emacs, and Kakoune. The commands should allow you to do anything you might otherwise do by navigating through a bunch of GUI menus.
Taking Vim as an example here, you enter command mode by typing
: while in normal mode. You can then type
write and hit the return key, and that’s how you save the file you’re currently working on; by typing
Yes! Also fully mouse driven!
I want to be able to fully navigate the editor with only my mouse. Sometimes I like doing that, e.g. when I’m just browsing through the codebase, or messing with some settings.
At other times I’d like to be able to use the keyboard, e.g. when I’m already working on some code and I want to quickly switch to a different file, jump to a definition, etc.
And sometimes I have one hand on the keyboard and the other on my mouse. That should limit me as little as possible.
The whole goal here is to make the editor equally accessible with multiple input methods.
Functionality driven by plugins
This is probably the most difficult part to design and implement. I want to allow plugins to control every aspect of the editor; rebind keys and actions, open/close dialogs, add configuration options, etc.
The editor should have default functionality relevant to the core usage of a code editor, but every aspect of that default functionality should be extendable with plugins. The system should even allow you to completely re-implement how some things work.
The example that’s at the forefront of my mind all the time is rebinding keys. Or rather, changing the input handling. It should be easy for plugins to create modal editing modes, like what Vim and Kakoune do. That means you’re not just rebinding keys, the plugin should be able to change the whole input handling for the editor.
Another example of a plugin would be a frontend for debuggers. Allowing the user to set breakpoints, step through code, etc.
Aside from the ambitious scope of this plugin system I also want plugin support to be programming language agnostic. If you want to write a plugin in Java, go for it. Haskell? No problem. C? You got it boss!
This, of course, essentially means that plugins must be standalone executables or scripts. There’s no other way to make this happen unless you rebuild the editor. As a result, the plugins need to communicate with the editor somehow, and I think I’ll use the json-rpc protocol to achieve this.
What I’ve outlined here is already pretty ambitious, and would take a long time to implement properly. Because of that I want to limit the scope to a sort of minimally usable editor for myself:
- Syntax highlighting.
- Support for TextMate/VSCode color themes.
- Auto-completion via the language server protocol (LSP).
- Project overview bar.
- Support for basic plugins
- The benchmark here is to support plugins that change the input handling.
I haven’t yet decided what will be part of the core editor and what will be implemented through plugins. Especially the syntax highlighting and LSP support. I guess that’s something I’ll need to find out along the way!
What’s happening with this now?
Despite the fact that Electron apps work fine most of the time, I dislike the idea of Electron when it’s not required (hint: it almost never is). As such I chose to find a suitable GUI framework that’s closer to being native, and that doesn’t leave me with many options.
I chose to go with C++ and Qt. The Qt framework is mature, looks nice on all platforms, comes with a lot of good stuff, and I’ve worked with Qt before.
At the time of writing I have a working proof of concept available built with QScintilla as the editor widget. Input handling is managed with a plugin, and so is syntax highlighting and TextMate theme support.
Right now I’m looking into whether I should continue to use QScintilla, or whether I should use Scintilla or KTextEditor. My main gripe with QScintilla is that it’s based on a relatively outdated version of Scintilla. QScintilla is based on Scintilla v3.10.1, which was released in October 2018. That version of Scintilla is the LTS version, but it’s still several LTS versions behind, the latest one being 3.11.2.
I’m leaning towards using KTextEditor since that gives me a bunch of nice things out of the box, but that will really only work if there’s an easy way to include that in the project.
Once I’ve explored what it’s like to use some of the different editor widgets, and made up my mind as to which one I’ll use, I’ll work on LSP support and re-evaluate how far I want to take this after that.
Here’s to hoping this project isn’t way too ambitious.