Vim Keybind Entropy
Quantifying keybind efficiency using information theory 2026-08-28
keyinputpre.vim • process.vim • surprisal.c
For a few days I collected Vim keypress data using a small script keyinputpre.vim that logs KeyInputPre events to a file. KeyInputPre is triggered late in the input pipeline—after mappings are applied to the typeahead buffer and after commands are translated into the stuff buffer—so the data needed cleaning. I did this using another Vim script process.vim and the result is a file where every byte roughly corresponds to a key event:

From here I wrote a C program surprisal.c that estimates the information content of each key event given the last few key events, and then averages information content to estimate entropy. The first line of output contains some statistics:
- The information content of the key events file, in bits;
- The number of key events in the file;
- The entropy of the key events, in bits;
- The entropy of the last 1024 key events, in bits;
and the remaining lines are a visualization of the information content of each key event:

Key events from Vim bindings are a code for sequences of semantic actions carried out by the editor. Information theory tells us that such a code is efficient when the coded data looks like uniform random noise—its entropy is maximal and the information content of its outcomes is constant. This means:
- Key sequences with high information content should be remapped to longer ones, so as to dilute information and free up our codeword budget.
- Key sequences with low information content should be remapped to shorter ones, so as to concentrate information and reduce the size of the coded data.
I began with dilution of high information content. We can tweak the parameters of the visualization to focus on key events with high information content:

But there was a problem: the regions of lighter shade I was supposed to lengthen were either inserted text or typos like ;×§:§sy (semicolon, escape, shift in, colon, shift out, s, y, space) or §:§dau«·doa (shift in, colon, shift out, d, a, u, backspace, backspace, backspace, d, o, a, space). Apart from perhaps remapping K to a longer key sequence, there wasn’t much to be done. Well, it turns out that’s okay. In truth, there’s little need to “free up our codeword budget” because Vim bindings are not a complete code—that is to say, there’s no need to free up key sequences to be used elsewhere because there already are plenty of unused key sequences in Vim.
With this established, I moved on to concentration of low information content. We can tweak the parameters of the visualization to focus on key events with low information content:

Scrolling though the output I saw that many regions of darker shade began halfway into the key sequences §:§ (shift in, colon, shift out) and §:§w¢ (shift in, colon, shift out, w, carriage return). In other words, when I use the shift key I tend to enter command-line mode next, and when I do I always release the shift key, and then I tend to write the buffer. I had heard of people remapping ; to : and vice-versa, so I tried that. I added the following line to process.vim to retroactively apply the mapping to the keypress data and I measured entropy:
s/[@fFtT]\@<!;/␚/g|s/[@fFtT]\@<!:/;/g|s/␚/:/g

Indeed, entropy went up 0.164935 bits. I’ve since added this mapping to my vimrc and the improvement is noticeable. I repeated the same analysis with §:§w¢ by retroactively remapping <Tab> to :w<CR>:
s/:w<CR>/<Tab>/g

And entropy is up another 0.164255 bits. I won’t be adding this mapping to my vimrc though, because the inefficiency comes less so from the length of the binding but more so from my habit of writing buffers unnecessarily often. Out of curiosity I also estimated the impact of training myself to use ZQ instead of :q!<CR>:
s/:q!<CR>/ZQ/g

But it was almost negligible, with entropy creeping up 0.005463 bits. I’m guessing this is because I use :q!<CR> much less often than : or :w<CR>—about 50–80× less often, in fact—so an improvement can only ever nudge overall entropy so far.