introduction
I’ll say it upfront: I’m a text–editor nerd. I’m in love with this strange and wonderful niche of the internet. It’s interesting that it even is a “niche”, considering that writing text is something many of us do for a living. You’d think people, especially writers and programmers, would care more about it; but they don’t, and it is what it is.
I’m not here to judge the people that don’t care as much. Frankly, it makes some
sense: text is the means to an end. We aren’t interested in the individual }
and " characters that make up a program, we’re interested in the program.
And the text–editor; well, that’s just the tool we use to get the job done,
and nothing more. It’s entirely valid to think that way.
However, that’s not a perspective I share.
I care a lot about the mechanics and semantics of writing and editing text digitally, and that’s what I want to discuss here today. However, it’s nearly impossible to talk about the cutting edge stuff in the text editing community without an understanding of what modal editing is.
My goal here is to explain and justify modal editing, step–by–step, such that you can truly understand it conceptually: what problem it exists to solve, how it implements the solution, and why that solution is so elegant.
an editor agnostic discussion
I’ll be keeping this article as editor agnostic as possible.
Vim is often seen as the quintessential modal editor. Thus, modal editing is overwhelmingly discussed and understood within the context of, or in comparison to, Vim.
However, I think we do ourselves a disservice by participating in this. Firstly, modal editing, as an editing paradigm, is general enough that we can discuss it without needing to refer to Vim. Imagine if we discussed functional programming as merely “Haskell” and “Haskell–like” languages.
Furthermore, the Vim–centric worldview can impose limits on perceived possibilities within the modal editing paradigm. For example, some evangelists may consider the “verb -> motion” grammar to be an essential component of modal editing — not merely as one possible expression of modal editing.
For these reasons, I’ll be avoiding references to Vim in this article. I believe that the concepts discussed below can, and should, be understood on their. Since I intend to later tackle Kakoune (my editor of choice) in an essay series, developing these concepts from scratch will serve us very well.
keys as commands
Let’s begin by talking about why we call them text editors and not text writers. Even though we do write text using these tools, I think that by framing their primary function as editing, we can better understand the problem that modal editing sets out to fix.
Imagine a typical editing experience, the kind we’re all surely acquainted with. The easiest thing to do is write. We often do this without thinking about it: I type on my keyboard, and text appears on the screen.
But let’s zoom out, and really think about what’s happening here.
How is the text appearing on my screen? What happens if we try breaking down the mechanics of this seemingly simple action?
“Well, it’s because I typed it!”, I hear you say. And, uh… Yeah, I guess that’s correct. But I think there’s more to it. How does my editor take my inputs and turn them into text in a file?
terminology: buffers and characters
When you write text in an editor, what you’re interacting with isn’t a file, it’s a buffer. It’s the program’s working memory of the text you’re working on. When you write stuff, the program adds it to this buffer. When you save, the buffer is just written to the disk. Opening a file later just means loading its content into the buffer.
A character is a single unit of text. A sequence of characters is what makes
up a buffer. The most common characters are letters. But although every letter
is a character, not every character is a letter. Here are some examples of
characters: a f z ` " ∴
Thus, the act of typing can be thought of as pressing a sequence of keys that denote the characters we want to put in the buffer. But I’m going to suggest an alternative framing: think of the keys not as characters to be inserted, but as instructions to the editor.
When you press w, you’re not just picking a character to insert. What you’re
really doing is issuing a command to the editor: “insert the character w
into the buffer at the cursor’s position”.
As such, the process of writing is really just about constructing a sequence
of these commands that will eventually compose words and sentences. It just so
happens that every key we press is instructing the editor to “insert this
character now”, typing flows together, and it feels like we’re writing. Even
the return key fits this paradigm: when we press enter, the editor inserts a
literal newline character (\n) at our cursor. It then visually shows us a
line break; but that’s just a trick of the light.
It’s crucial to remember this framing. It may feel like we’re just typing letters that form words, but really we’re issuing commands that instruct the editor to insert characters into the buffer. So, why does this even matter? Am I not just being pedantic and overthinking it?
What happens when you press backspace?
Unlike return, there’s no character called “backspace” that gets added to the
buffer, and then fancily rendered visually to trick us into thinking a letter
was deleted. Instead, the character before the cursor was actually deleted.
… Damn. We’ve violated the rule we established earlier! Not every key seems to be sending the “insert this” command! So really, this is why it’s so important to remember that every key is a command, and that it just happens that most of them insert characters: we need some way to understand the keys that do more than mere character insertion.
the problem of key exhaustion
As a thought experiment, imagine that we’re designing a new text editor. In that context, let’s brainstorm some potential “editing actions”.
One of the most common actions seems like moving the cursor, right? Since the cursor tells the editor where to do things (insert, delete…), having an intuitive way for the user to position it seems essential.
Okay, the arrow keys seem like a logical choice for this. Pressing one of them should move the cursor one step in that direction. Seems easy enough.
How about an action called “delete the current sentence”? Sometimes, while we’re writing, we may be in the middle of drafting a sentence and realize the whole thing is bogus. Sure, we could just repeatedly press backspace, but that’s going to be annoying if we do this often.
Surely, a “delete current sentence” key would be super convenient. The question is what key to bind it to. Well, uhhh… we don’t actually have many free keys left.
We’ve barely gotten started, and we’re already running out of keys. To
rectify the issue, we could use modified keys. For example, what if pressing
a inserted the character a, but holding down control and pressing a did
something else?
This editing paradigm is so common that we barely even notice. After all, if this is why keyboards have modifier keys in the first place, it can’t be so bad, right?
However, imagine that we got way too carried away with brainstorming, for our
new editor, and now we have a massive list of “editing actions” to add. Imagine
things like “select around current word”, “move this line to the end of the next
paragraph”, etc. Highly specific and numerous! Eventually, we start running out
of keys to press with Control and need to introduce Alt, then Shift!
This can get messy really fast… and the worst part is that we’ll still
eventually run out of keys. The more editing actions we have, the more
modifiers we need to use, and the quicker we start running out of sensible key
combinations. Ergonomics die a painful death as soon as we ask the user to press
three keys at once, or to remember what control + alt + shift + d does.
To summarize the problem, there will always be more editing actions than sensible key combinations.
So, what can we do about it?
editing modes
If the issue is that we don’t have enough keys… what if there was a way to get more mileage from a single key? What if the same key performed a different action depending on the context?
This is where we meet our new best friend, modal editing.
Returning to our hypothetical editor, let’s finally address the pesky running–out–of–keys problem. Recall that there are a lot of “insert this” commands — nearly every key on the keyboard is currently tied to one of these.
That feels like a waste of space, doesn’t it? Imagine if we could free all of these up; then, we could bind a lot of commands to single keys before even dipping into modifiers.
Sure, but we don’t want to sacrifice those insertion commands. After all, we do still need to actually insert characters. Instead, let’s make the keys behave differently depending on whether we’re writing, or editing.
Conceptually, we can understand this like a mode that we put our editor into. Say we switch it to “insert mode”: then, the keys will all insert characters. But if we switch back to “editing mode”, then those same keys can perform a different set of editing actions.
Suppose that we dedicate just one key for toggling between our two modes. Now, we can use our “normal mode” to move the cursor around the document, making small edits as we go along. When we want to write something, we can press the special key to enter insert mode.
While in this mode, we can feel confident that pressing a key will always type that character. No need to keep special shortcuts in mind. When we’re done, we simply toggle back out of insert mode, and continue editing just as before.
If you’re new to the modal editing concept, this may feel quite unintuitive. Needing to enter a special “mode” just to write text could seem like an unnecessary distraction.
However, you’d be surprised at how ergonomic using this method actually is. For one thing, remaining in the normal editing mode, and only dipping into insert mode when we actually need to, encourages us to be mindful about our writing. You’ll quickly realize that writing only makes up a small portion of what we do in our editors.
And, of course, using this method, we can seriously extend the number of commands we can express using the keyboard. In fact, we don’t even need to stop at giving keys a dual–function. A single key can do as many things as modes we dare to define.
editing as a language
I’m going to propose another paradigm through which to understand editing as a whole: language. I posit that by seeing editing through the lenses of words and grammar, we unlock the ability to express nuanced edits in a simple way.
Returning to our hypothetical editor, let’s design a super simple editing language. Like any language, we need words. We’re going to define a grammar with roughly a dozen words, which are of three grammatical types: verb, subject, and relator.
Let us begin with verbs. Consider some basic actions: insert, cut, and
paste. These are all something we do in the editor. Some verbs may accept
arguments: for example, insert(Hello, world!) specifies what is to be
inserted, while paste(before) and paste(after) indicate the direction of
the paste.
That’s simple enough, but a verb needs a subject: if the verb describes the
action, the subject describes what’s being acted on. Consider some basic
targets: word, sentence, paragraph, cursor, line, etc....
Finally, let’s introduce relators: a compass that situates the subject
relative to the cursor. This answers which instance of the noun is meant:
next, previous, current, before, after, etc…
In terms of grammar, to keep it simple, we posit that one verb, one noun, and one relator, in any order, is a valid sentence. Already, we have a suprisingly expressive language. Let’s take a look at some edits that we can describe:
delete this wordnext sentence cut, thenpaste(after) cursorcut previous paragraphinsert(TODO:) before current sentence
More complex concepts, such as “move” or “swap”, can be broken up into simpler
parts. For example, given a buffer that contains foo bar, with our cursor on
foo, how might we express “swap the next word with the current one”?
cut next wordpaste(before) current wordinsert(SPACE) after previous word
You might be wondering what this has to do with modal editing. Sure, we’ve established that modal editing can address key exhaustion, but it doesn’t necessarily create the structure that’s required for an expressive editing language.
That may be true, but by increasing the number of commands we can conveniently
access, modal editing makes the language easier to speak. Imagine that every
“word” in our editing language corresponds to a single keystroke in our “editing
mode”: delete to d, insert to i, and so on.
Thus, modal editing is not only a way to reclaim keyspace, it can also help us to compose editing actions semantically. Its real strength is that by increasing keyspace, it provides a larger vocabulary of single–stroke “words” to use in editing languages.
If you learn the language of your editor, (and thanks to modal editing, words are single keystrokes), you can pretty much edit text at the speed of thought.
That won’t necessarily make you a better programmer or author (speed != quality), but it’s satisfying as all hell. And let’s face it, if you edit text for a living, wouldn’t you want it to be a bit more fun and engaging?
I don’t care about the mouse
If you’re a modal editing enjoyer, you’re probably wondering how I’ve made it this far without mentioning the mouse. You’ve likely heard the standard argument: using the mouse is inefficient because moving your hand away from the keyboard is expensive.
I don’t disagree — I avoid the mouse myself, too. For those of us with hand/wrist problems, frequent mouse usage can cost more than just time!
But honestly, the mouse argument isn’t what excites me about modal editing. It may be correct, but it’s also been said a thousand times, and I don’t even think it’s the most convincing argument.
Sure, going mouse–free is nice, but it’s a side effect, not the point. The real win is semantic density: more meaning per keystroke.
conclusion
We started with a simple observation: every key is a command, yet many editors only let one command fit on each key. Modal editing is a way to reframe the keyboard. One physical key can mean many logical things, so we never run out of “shortcuts”.
The payoff is breathing room: more commands than keys, fewer control–alt–shift yoga poses. Furthermore, the surplus of commands lets us speak to the editor in sentences, and express our edits semantically.
Thus, whether you adopt modal editing or not, recognizing commands as a language rather than a list of hot-keys has the potential to change how you engage with any editing tool.