Emacs vs vi: How to Compute Keybinding's Efficiency?

By Xah Lee. Date: . Last updated: .

spontaneous random thoughts on keyboarding!

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 Caps Lock 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 Ergodox, Kinesis, Maltron, Truly Ergo. )

you have 2 options for utilizing a good key spot:

the question is, which 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!

O, but, there are 10 other commands, although less frequently used than your completion, but these are also frequently used, and when counting their frequency of use together, might beat the completion command.

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

well, let's just use another convenient key on keyboard. NO, the point is, for each 1 convenient 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[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:

frequency[xCmd] * key_ease_score[get_key[xCmd]] ≻
sum[frequency[yCmds[i]] * key_ease_score[ get_key[yCmds[i]]],{i, 1, n}] 

so, in order to know, you actually have to have a sense of the score of each and every yCmds[i].

How to Compute a Keybinding's Efficiency?

let's go about this scientifically.

in general, efficiency can be computed thus:

let freq[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 cmd 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 ⌫ Backspace key would have a very low score. (also, note that this scoring of keys is dependent on specific physical keyboard layout. For example, even standardish PC keyboard from Microsoft Keyboards or Logitech Keyboards differ slightly in their physical key layout a bit, such as the exact position and the size of Alt and Ctrl keys, shape of Return ↩ key.))

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

Cooler Master Storm QuickFire Rapid Keyboard SGK-4000-GKCL1-US
“Cooler Master Storm QuickFire Rapid Keyboard” Buy at amazon

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
workman layout key difficulty score. (img src http://www.workmanlayout.com/blog/)

(note: the workman score is a score of difficulty, lower is better. But the score for our context is score of ease, higher is better. We can convert workman score to ours by just 1/x)

we need to give a score for all keys, including {Return ↩ Caps Lock Alt Ctrl 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 on github).

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

it is this:

freq[cmd] * key_ease_score[key]

what about key chord such as {【Ctrl+x】, 【⇧ Shift+t】} or key sequences such as {【Caps Lock t Caps Lock】, 【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, …} 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

keybinding_score[cmd, keyboard_shotcut] := freq[cmd] * key_ease_score[keyboard_shotcut]

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