Emacs vs vim, Compute Keybinding Efficiency

By Xah Lee. Date: . Last updated: .

This article is about how to determine the efficiency of two keyboard shortcut sets. For example, answer the question of, whether emacs or vim is more efficient.

keys on keyboard are precious. There are only a few good spots, and ten times more commands.

so, i have now one key, i want to set it to one frequently used command. Let's say the key is Tab, and it's positioned either under your thumb or someplace very easy to hit (such as CapsLock or Return position on PC keyboard)

(we are using PC keyboard to illustrate for simplicity here, but the principle here applies to any fancy keyboard such as Kinesis Advantage2 or Microsoft Sculpt. )

you have 2 options for utilizing a good key spot:

  1. set it to one very frequently used command. (e.g. keyword completion)
  2. set it as a prefix key of key sequences for often used commands. (For example, copy → Tab j, cut → Tab k, paste → Tab l, etc. [see Ban Key Chords] )

the question is, which use of the Tab key is more efficient?

such a precious key. If you set it to one most used command, how wonderful, just one single key right under your thumb!

Oh, but, there are 10 other commands, although less frequently used than the completion command, but when counting their frequency of use together, might be twice higher than the completion command.

But if you use tab as in Tab key for these commands, but then you lose your so super easy single key for the super important completion command! what can you do??

well, let's just use another easy key on keyboard. NO, the point is, for each 1 easy key, there are 10 commands wanting to use it. Can't fit 10 pigeons in 1 hole, the pigeon hole principle!

so, which is more efficient?

the short answer is:

keybinding score of a set of keybindings is the sum of each's score.

and how to compute a keybinding's score? it's this:

frequency(cmd) * key_ease_score(get_key_shortcut(cmd))

so, back to our question, of using Tab for completion is better, or is Tab as prefix key for a bunch of commands better? It can be computed this way:

// the ease score of a given command "completion" and its keybinding
frequency("completion") * key_ease_score( get_key_shortcut("completion") );

The above formula says, to get the ease score for command xCmd, you get its frequency of use, and get the ease score of its keybinding, and multiply them together.

vs

// the ease score of a given command list commandList and their keybindings

// list of commands
commandList = [
  "copy",
  "paste",
  "cut",
  "undo",
  "redo",
  "open",
  "new_tab",
  "close_tab",
  "next_tab",
  "prev_tab",
];

// list of its scores
const scores = commandList.map((
  x,
) => (frequency(x) * key_ease_score(get_key_shortcut(x))));

// total
const total = scores.reduce((a, b) => (a + b));

To get the ease score for a list of commands, simply compute each and sum them up.

Then, compare them. The higher ease score means more efficient.

so, in order to know, you actually have to have a sense of the score of each and every yCmds's frequency, and their keybinding, and each's keybinding score.

wow, that's non-trivial. No wonder i have a hard time deciding on the Tab keybinding.

How to Compute a Keybinding's Efficiency?

let's go about this in more tech detail.

Let's say we want to find the keyboard efficiency of 2 apps. Let's say, the apps are emacs and vim.

Given:

in general, efficiency can be computed this way:

let freq_weight(cmd) be a function that returns the frequency of a command named “cmd”. It returns a value from 0 to 1. (like percentage) It is the ratio of the count of command call over the count of all command calls (during a period, say, a month. (and, let's say it's derived from the average of 100 person's command log of emacs)) [see Emacs's Command Frequency Statistics]

then, we need to assign a score for each physical key on keyboard. Each key should have a ease-of-press score, from 0 to 1. With 1 meaning the easiest. (the Space bar key would have score of 1. The key d (of qwerty layout) would have a score something like 0.9. The key z would have a low score, something like 0.2. The Backspace ⌫ on PC keyboard layout would have a very low score, something like 0.1.)

for simplicity, let's assume this fairly standard keyboard and with QWERTY layout:

Filco Camo Majestouch-2 Tenkeyless keyboard
Filco Majestouch-2 Tenkeyless [see Keyboards without Numeric Keypad]

assigning scores to keys is a bit hard. But basically, home row keys would have high score, keys using index finger and pointing finger would have higher score than using pinky finger. And keys on top row usually have higher score than bottom row (at least for pointing finger and index finger keys).

this has been studied before. For example, here's what the Workman layout designer OJ Bucao's thought about key score.

workman layout keyboard key score
Key difficulty score of workman layout. Scored by OJ Bucao. https://workmanlayout.org/

Note: the workman score is a score of difficulty, from 1 to 5, with 5 being the most difficult. Lower is better. But the score for our context is score of ease, higher is better, and runs from 0 to 1. We can convert workman score to ours by key_ease_score = (5-1)/workman_key_difficulty_score.

we need to give a score for all keys, including {Return CapsLock Alt Ctrl Tab F1 …}.

how to derive the key score? One way is by one-person's experience and logical analysis, such as OJ Bucao has done here. Another way is to let a group of keyboard layout designers to come up with a score that we all roughly agree on (This can be done as a open source project).

once we have a score of keys, then we can compute the efficiency of a keybinding.

it is this:

freq_weight(cmd) * key_ease_score( get_key_shortcut(cmd) );

what about key chord such as {Ctrl+x, Shift+t} or key sequences such as {CapsLock t CapsLock, Alt e c}?

score of keyboard shortcut involving chord such as Ctrl+x can be computed as score of Ctrl and score of x multiplied by some multiplier factor. Something like:

chord_key_score =
((modifier, key) => ((key_ease_score(modifier) * c1 + key_ease_score(key) * c2) + c3) * c4);

where the {c0, c1, c2, etc} are constants.

similar for more complicated chord such as Ctrl+Alt+x.

score of key sequences can be computed similarly. And same for sequences that involves chord.

so now, we have a score for any type of keyboard shortcut.

then, the formula for a keybinding is

const keybinding_score =
((cmd) => freq_weight(cmd) * key_ease_score(get_key_shortcut(cmd)));

the efficiency of a system such as GNU emacs or vi/vim is then the sum of keybinding score of top 100 most frequently used commands.

for the most efficient keybinding for emacs, see Emacs: Xah Fly Keys

Keybinding Design is a Linear Programing Problem

Keybinding Design is a Linear Programing Problem

Keybinding and Input-System