A Lost Bit

Keybinds as a DSL

As a heads up I will say that I am writing this in the context of using a tool like emacs, or some kind of fictional unified interactive environment focused on a text interfaces. So pull up a pew.

When I think of editing or doing pretty much any kind of interactive text munching. I tend to think just dump it in an emacs buffer and get evil with it. Which leads me to the title of this talk.

Keybinds are a DSL, or at least could be a DSL.

As an evil enjoyer, when editing in emacs I tend to pop in and out of INSERT mode as I hop around a page and do my thing. Recently I've been thinking of attempting to write a text first programmable environment, and as part of this I've been brainstorming the UX part of it.

I was thinking about how I tend to navigate text with evil mode, and the main thing that came to mind is the composability of the keybinds. For example a common key motion (what do you even call this? A riff?) that I use is, c i (. When pressed in normal mode this will delete the contents of the next matching parentheses and leave the cursor just after the ( in insert mode. Instead of moving over to the mouse and hunting around for things, which interrupts my flow I just play my little key riff thingie and I can carry on with whatever I was attempting to do.

The great thing about these key riffs is that when you figure out the language of the key presses, you can start to compose your own little riffs to help speed up your editing.

So what would a UI that is built around this paradigm look like?

Well in vim and evil we have the following kind of sentence structure:

For example we could write the prior example of c i ( like Change Inside Parentheses.

Sometimes we omit the context in our riffs, and just use the command and object like in c w (Change Word), which will delete to the end of the word from the cursor and then leave the cursor in insert mode.

So if we take this idea of Commands, Contexts and Objects, and create a structure way of manner of utilising them like the normal mode vim riff thingie. We can create a unified interface for interacting with various types of objects across a set of commands.

So what are commands, contexts and objects?

A command is just an operation to be applied to the text. This could be copying, pasting or deleting.

A object is a view of the underlying text. This could be a single character, or a word, or even the inside of a pair of parentheses.

And a context is a way of further describing how the object should be used. An example would be the inside context which could be used for selecting only the contents of the parentheses and not the parentheses themselves.

Not every object requires a context. For example the character object, there is no need to imply anything here. A character will always be a single character point. I am not mentioning encoding here and that is left to be decided by the file / environment.

Here are a list of commands, contexts and objects that could be useful.

Commands:

Objects (objects prefixed with * are special and don't have keybinds):

Contexts:

We can then use these and out sentence structure to compose commands in a DSL-esque way. Here are some example ways we could do this.

The great thing about this way of thinking is it gives us a structured way around thinking of editing. We can always add more contexts, objects or commands. As well as being able to bind a longer riff to a single key press if needed via a macro recorder or a scriptable interface if one is present.

The only problem is that it requires a model editing paradigm or a activation key to trigger the command mode. so that we don't have to worry about overloading keys that are used for typing like the alphas.