As of late I’ve been thinking up ideas about a potential future text-editor of mine. One standard feature of nearly all text editors worth their salt is windowing: the ability to have two-or-more files open side-by-side or in other configurations. At a surface level this might seem like a no-brainer feature — and one which can substantially increment on the user-experience — but I think we can do better …by removing it all together.
What I am not suggesting is that people should remove windowing from their workflows entirely — windows are incredibly useful and even more so on larger monitors. I instead suggest that we begin delegating the task of windowing to the tool that does windowing best: the window manager.
Window managers come in all sorts of shapes and sizes. Most computer users will be using floating window managers; these are the window managers where you open a window and the window pops up somewhere random on your screen. As the user it’s your job to resize the window, move the window where you want it, etc. This is the standard behaviour on the classic MacOS or Windows system, along with most mainstream Linux systems.
There are also other forms of window managers such as tiling window managers. These are more popular in the Linux space although you can find these for other systems too. The idea behind a tiling window manager is that you delegate the positioning and sizing of windows to your window manager. The methods that tiling window managers use to cut up the screen varies but typically you can expect that launching an application will cause it to take up the full width and height of the screen, while launching a second application will cause the screen to be segmented into two halves, with one window taking up 50% of the screen on the left and another taking up 50% of the screen on the right1.
Why do I mention all of this? I mention this because I want to emphasize the fact that window management is not an easy task, and we all have different preferences for how we want it done. This means that unless you implement an entire window management solution into your text editor complete with tiling- and floating window management options, some large subset of your users are going to be having an experience that is suboptimal compared to what they could be having. Not only is it suboptimal, but it differs from the standard behaviour of their system.
Where’d My Code Go?
There is a second issue that implementing windowing in your editor results in, specifically this is an issue that is extremely prevalent if you use a tiling window manager: it is the issue of your code disappearing, allow me to explain in three pictures.
The problem here is quite clear: because I use a tiling window manager, opening Firefox to read some documentation caused my screen to be split into two halves — one for Emacs and one for Firefox — rendering my Emacs buffers unreadable. This is completely correct behaviour from my window manager and I don’t expect it to behave any differently, but it is clearly not ideal. The result we want is the result seen in the third image, where the window is split into 3 parts allowing me to more easily read my Emacs-lisp code while simultaneously reading documentation in my browser.
So how do we go from the second image to the third image? The answer is obvious: we used three windows. Instead of having one dedicated Emacs window that itself manages two sub-windows, by simply breaking it up into two separate Emacs instances each displaying only a single file, I allowed my window manager to make a more informed decision about where to place my web browser. Intuitively this should make sense; if we have two files in one Emacs window our window manager will have no idea that we want to see three different things when we launch Firefox; it will only be aware that we want to see Emacs and Firefox side-by-side.
Now we need to keep in mind the usability issues that windowing in text editors attempt to solve; it is unreasonable to expect the user to need to manually and laboriously open a new instance of their text editor, navigate to the project they’re working on, open a file, etc., all just to view two related files side-by-side. The reason we all use windowing in our editors is because of how convenient it is to be able to simply click a button or execute a key-binding and instantly have a second buffer of text appear on our screen.
The Solution
This is not as difficult of a problem as we might imagine though, and as I’ll discuss it’s actually not even an unsolved problem. The first potential solution is to just make your text editor not slow. We live in the 21st century with hardware that is unbelievably fast; there is absolutely no reason why your editor should not so instantly open that it’s done before your finger has left the enter key or the left-click mouse button. Of course most software doesn’t do this, but we are living in a world of never-before-seen inefficient and slow software.
The second solution is a more technically involved one, but one that has seen real success: the server-client model. The idea here is that when you use your editor it spins up a server (or dæmon) with which the editor (the client) will connect to and communicate with. When you want to open a new file in a second window, your client can simply launch a second instance of itself that connects to the same dæmon process. This should in theory also help to improve startup times as little initialization will need to be done, most of it will need to instead be done by the server which after the first client has spawned will already be complete.
This server-client model also solves a second important usability issue I have yet to mention in this presentation, and that is shared state between your windows. Many editors such as Vim or Emacs have their own clipboards, bookmarks, and registers which the user can create, store information to, etc., during regular usage of the program. When a user stores data in their clipboard in one window that data should be accessible in the other (but not in a totally unrelated editor session where you’re working on an unrelated project). By using the client-server model all this information can be stored on the server, and connecting clients simply use the server as a middle-man to broadcast changes to this shared state between other clients.
As mentioned earlier, this is not a new novel concept and has seen actual success in practice. Emacs is perhaps the best example of this where many users will spawn an Emacs dæmon on their system and then connect to that dæmon via the Emacsclient client program. This allows for both dramatically improved startup performance, and shared state between client instances.
Another editor that uses such as idea is Kakoune. Kakoune in fact was designed with a philosophy that I find myself deeply aligned with; it doesn’t even have the editor windowing support that I rail against in this presentation. If a user wants to open multiple buffers in a Kakoune session they must actually spawn multiple Kakoune clients which will communicate with a server. All window management is delegated to specialized tools such as Tmux or your window manager.