Emacs: Command Frequency Statistics
This page lists emacs's commands in the order of their frequency of use.
In emacs, each key press invokes a command. For example, pressing a invokes the command self-insert-command
. Pressing Ctrl+f invokes the command forward-char
. Pressing Alt+x invokes execute-extended-command
.
Pressing the → invokes forward-char
. Scrolling the mouse wheel invokes the command mwheel-scroll
.
The motivation of this study, is in designing a Ergonomic Keybinding. I need to know what commands are more frequently used, in order to give it a easier-to-press key.
Command Frequency Table
Total number of command calls: 4661763
Total number of data entry (char insert) command calls: 2234669
Percent of data entry command calls: 48%
rank | Command Name | Count | % of Total | % of None Data Entry |
---|---|---|---|---|
0 | insert char | 2182320 | 46.81 | N/A |
1 | ↓ | 415004 | 8.90 | 17.10 |
2 | ↑ | 375600 | 8.06 | 15.48 |
3 | →w | 150224 | 3.22 | 6.19 |
4 | → | 125017 | 2.68 | 5.15 |
5 | ←w | 114045 | 2.45 | 4.70 |
6 | ← | 78465 | 1.68 | 3.23 |
7 | ⌫ | 75657 | 1.62 | 3.12 |
8 | isearch-→ | 64477 | 1.38 | 2.66 |
9 | ↵ | 52349 | 1.12 | 2.16 |
10 | |← | 43684 | 0.94 | 1.80 |
11 | ⌫w | 40684 | 0.87 | 1.68 |
12 | paste | 32972 | 0.71 | 1.36 |
13 | save-buffer | 31310 | 0.67 | 1.29 |
14 | ⌦l | 28569 | 0.61 | 1.18 |
15 | ▼ | 26389 | 0.57 | 1.09 |
16 | ⌦ | 21173 | 0.45 | 0.87 |
17 | minibuffer-complete | 19336 | 0.41 | 0.80 |
18 | other-window | 19256 | 0.41 | 0.79 |
19 | →| | 19004 | 0.41 | 0.78 |
20 | find-file | 18021 | 0.39 | 0.74 |
21 | scroll-up-1 | 17528 | 0.38 | 0.72 |
22 | handle-switch-frame | 17327 | 0.37 | 0.71 |
23 | isearch-other-meta-char | 17276 | 0.37 | 0.71 |
24 | comint-send-input | 17032 | 0.37 | 0.70 |
25 | forward-sexp | 16045 | 0.34 | 0.66 |
26 | execute-extended-command | 15996 | 0.34 | 0.66 |
27 | close-current-buffer | 15788 | 0.34 | 0.65 |
28 | ▲ | 15408 | 0.33 | 0.63 |
29 | set mark | 15281 | 0.33 | 0.63 |
30 | ⌦w | 15017 | 0.32 | 0.62 |
31 | isearch-← | 12717 | 0.27 | 0.52 |
32 | c-forward-subword | 12645 | 0.27 | 0.52 |
33 | undo | 12296 | 0.26 | 0.51 |
34 | move-cursor-next-pane | 12183 | 0.26 | 0.50 |
35 | copy | 11949 | 0.26 | 0.49 |
36 | switch-to-buffer | 11941 | 0.26 | 0.49 |
37 | forward-block | 11759 | 0.25 | 0.48 |
38 | shrink-whitespaces | 11355 | 0.24 | 0.47 |
39 | ✂ | 10680 | 0.23 | 0.44 |
40 | isearch-other-control-char | 10213 | 0.22 | 0.42 |
41 | comint-previous-input | 10058 | 0.22 | 0.41 |
42 | ↓¶ | 9669 | 0.21 | 0.40 |
43 | |◀ | 8764 | 0.19 | 0.36 |
44 | backward-block | 8243 | 0.18 | 0.34 |
45 | ▶| | 8001 | 0.17 | 0.33 |
46 | dired-advertised-find-file | 7803 | 0.17 | 0.32 |
47 | scroll-down-1 | 7733 | 0.17 | 0.32 |
48 | backward-sexp | 7476 | 0.16 | 0.31 |
49 | delete-other-windows | 6968 | 0.15 | 0.29 |
50 | set-mark-command | 6406 | 0.14 | 0.26 |
51 | next-error | 6235 | 0.13 | 0.26 |
52 | ↑¶ | 6110 | 0.13 | 0.25 |
53 | switch-to-next-frame | 5513 | 0.12 | 0.23 |
54 | isearch-yank-word-or-char | 5508 | 0.12 | 0.23 |
55 | yas/expand | 4921 | 0.11 | 0.20 |
56 | mark-sexp | 4806 | 0.10 | 0.20 |
57 | tj-newline-and-indent-command | 4695 | 0.10 | 0.19 |
58 | iswitchb-buffer | 4658 | 0.10 | 0.19 |
59 | nonincremental-repeat-search-forward | 4474 | 0.10 | 0.18 |
60 | extend-selection | 4424 | 0.09 | 0.18 |
61 | c-backward-subword | 4420 | 0.09 | 0.18 |
62 | minibuffer-keyboard-quit | 4355 | 0.09 | 0.18 |
63 | exit-minibuffer | 4295 | 0.09 | 0.18 |
64 | revert-buffer | 4205 | 0.09 | 0.17 |
65 | tcl-electric-char | 4162 | 0.09 | 0.17 |
66 | iswitchb-exit-minibuffer | 4102 | 0.09 | 0.17 |
67 | split-window-vertically | 4035 | 0.09 | 0.17 |
68 | search-forward-regexp | 4021 | 0.09 | 0.17 |
69 | jabber-chat-buffer-send | 3833 | 0.08 | 0.16 |
70 | kill-buffer | 3731 | 0.08 | 0.15 |
71 | rgb-doublespace-maybe | 3691 | 0.08 | 0.15 |
72 | scroll-down-2 | 3448 | 0.07 | 0.14 |
73 | comint-beginning-of-line | 3365 | 0.07 | 0.14 |
74 | back-to-indentation-or-beginning | 3273 | 0.07 | 0.13 |
75 | select-text-in-quote | 3250 | 0.07 | 0.13 |
76 | toggle-letter-case | 3235 | 0.07 | 0.13 |
77 | c-electric-star | 3226 | 0.07 | 0.13 |
78 | c-electric-backspace | 3196 | 0.07 | 0.13 |
79 | scroll-bar-toolkit-scroll | 2941 | 0.06 | 0.12 |
80 | scroll-up-2 | 2923 | 0.06 | 0.12 |
81 | c-indent-line-or-region | 2886 | 0.06 | 0.12 |
82 | c-backward-kill-subword | 2846 | 0.06 | 0.12 |
83 | abort-recursive-edit | 2832 | 0.06 | 0.12 |
84 | beginning-of-visual-line | 2828 | 0.06 | 0.12 |
85 | recenter | 2779 | 0.06 | 0.11 |
86 | gnus-summary-next-unread-article | 2772 | 0.06 | 0.11 |
87 | isearch-exit | 2730 | 0.06 | 0.11 |
88 | gnus-topic-read-group | 2718 | 0.06 | 0.11 |
89 | exchange-point-and-mark | 2690 | 0.06 | 0.11 |
90 | ignore | 2627 | 0.06 | 0.11 |
91 | gnus-group-get-new-news | 2519 | 0.05 | 0.10 |
92 | insert-tag | 2486 | 0.05 | 0.10 |
93 | cua-cancel | 2480 | 0.05 | 0.10 |
94 | end-of-code-or-line | 2479 | 0.05 | 0.10 |
95 | c-electric-slash | 2440 | 0.05 | 0.10 |
Interesting Highlights
Some interesting highlights from the stat, organized by common editing operations.
pictograph | Command Name | % |
---|---|---|
↑ | previous-line | 15.48 |
↓ | next-line | 17.10 |
← | backward-char | 3.23 |
←w | backward-word | 4.70 |
←¶ | backward-paragraph | 0.25 |
|← | move-beginning-of-line | 1.80 |
→ | forward-char | 5.51 |
→w | forward-word | 6.19 |
→¶ | forward-paragraph | 0.40 |
→| | move-end-of-line | 0.78 |
▲ | scroll-down (page up) | 0.63 |
▼ | scroll-up (page down) | 1.09 |
|◀ | beginning-of-buffer | 0.36 |
▶| | end-of-buffer | 0.33 |
⌫ | delete-backward-char | 3.12 |
⌫w | backward-kill-word | 1.68 |
|⌫ | kill-line-backward | 0.00 |
⌦ | delete-char | 0.87 |
⌦w | kill-word | 0.62 |
⌦| | kill-line | 1.18 |
copy | kill-ring-save | 0.49 |
cut | kill-region | 0.44 |
paste | yank | 1.36 |
paste previous | yank-pop | 0.00 |
set-mark | set-mark | 0.63 |
undo | undo | 0.51 |
M-x | execute-extended-command | 0.66 |
Open | find-file, dired-advertised-find-file | (0.74+0.32)/2 |
Close | kill-buffer, close-current-buffer | (0.15+0.65)/2 |
Save | save-buffer | 1.29 |
Save As | write-file | 0.00 |
† Percentage with Respect to Non Data Entry Commands Count
Explanations
This report's data are from the following people:
Name | Percentage | Number of Command Call |
---|---|---|
Alan Mackenzie | 0 | 3170 |
Marc Shapiro | 1 | 27259 |
Rick Bielawski | 4 | 166178 |
[David Capello] | 18 | 817127 |
Trey Jackson | 37 | 1736697 |
Xah Lee | 41 | 1911332 |
Total number of command calls: 4661763.
Data Entry Commands vs Non Data Entry Commands
For this report, emacs commands are divided into one of 2 categories:
- data entry
- none data entry
“data entry” commands are commands that are typing, such as pressing any of letter keys, number keys, or Enter key. Emacs command name for these are: {self-insert-command
, newline
, org-self-insert-command
, isearch-printing-char
, org-return
, etc}.
All other commands are considered “none data entry”.
This division is important for our study because commands that insert characters do not need a keyboard shortcut, they already correspond to each key on the keyboard. But also, we can tell what percentage keystroke in emacs is spend on typing.
Name | Percentage of Data Entry Commands |
---|---|
Rick Bielawski | 19 |
David Capello | 35 |
Xah Lee | 50 |
Alan Mackenzie | 54 |
Trey Jackson | 54 |
Marc Shapiro | 75 |
Average: 48%
A higher percentage of data entry probably indicates that the person is doing a lot tasks that are mostly continuous fast typing, such as writing email, study notes, diary, irc chat.
Command Groups
Commands that are executed by the same shortcut key are grouped together.
For example, the commands {delete-backward-char
,
backward-delete-char-untabify
,
python-backspace
,
cperl-electric-backspace
} are all just the Backspace ⌫ key.
The following is the complete list of commands that are merged, and or represented by a glyph for clarity of reading.
Emacs Command Name | Merged Name or Glyph |
---|---|
self-insert-command | insert char |
org-self-insert-command | insert char |
isearch-printing-char | insert char |
newline | ↵ |
org-return | ↵ |
org-return-indent | ↵ |
next-line | ↓ |
dired-next-line | ↓ |
next-history-element | ↓ |
previous-line | ↑ |
dired-previous-line | ↑ |
previous-history-element | ↑ |
delete-backward-char | ⌫ |
backward-delete-char-untabify | ⌫ |
python-backspace | ⌫ |
cperl-electric-backspace | ⌫ |
org-delete-backward-char | ⌫ |
cua-scroll-up | ▼ |
scroll-up | ▼ |
scroll-down | ▲ |
cua-scroll-down | ▲ |
isearch-forward | isearch-→ |
isearch-repeat-forward | isearch-→ |
isearch-backward | isearch-← |
isearch-repeat-backward | isearch-← |
backward-char | ← |
forward-char | → |
backward-word | ←w |
forward-word | →w |
backward-sentence | ←s |
forward-sentence | →s |
backward-paragraph | ↑¶ |
forward-paragraph | ↓¶ |
org-beginning-of-line | |← |
move-beginning-of-line | |← |
move-end-of-line | →| |
org-end-of-line | →| |
beginning-of-buffer | |◀ |
end-of-buffer | ▶| |
delete-char | ⌦ |
org-delete-char | ⌦ |
cua-delete-region | ⌦ |
kill-word | ⌦w |
backward-kill-word | ⌫w |
kill-line | ⌦l |
org-kill-line | ⌦l |
kill-sentence | ⌦s |
kill-ring-save | copy |
cua-copy-region | copy |
yank | paste |
cua-paste | paste |
kill-region | ✂ |
cua-cut-region | ✂ |
set-mark | set mark |
cua-set-mark | set mark |
How the Report is Compiled
Here we describe how the report is generated.
Each person, installs this emacs package:
command-frequency.el.
(A new version, by
David Capello [https://davidcapello.com/], renamed as keyfreq.el
, is available at
https://github.com/dacap/keyfreq.
You should use this new version.
)
The package will accumulate a key/value list of all commands the user calls in emacs. The key is command name and the value is the number of times that command has been called. After some time, the user calls “command-frequency-display”. This will write the stat into a buffer, then the user save it to file.
The raw data files used in this report are here: command-frequency_data_files.tgz
A Python program
command-frequency.py, is used to parse these raw data files. The program aggregate all user's raw data, discard some commands such as mwheel-scroll
, “nil”, keyboard macros, etc, then groups some commands together as described in this report, and replace some command names by a corresponding glyph, then computes the various statistics used for this report, and print them in HTML. Commands used less than 0.1% of total none data entry commands are not reported
Currently, this report is not normalized. For example Xah Lee (me)'s data is 41% of the whole. So, that means my usage pattern has major influence. You can use the Python program to select which file or group of files to use for generating the stat. The overall pattern does not change much. For comparison, see this version of report without Xah Lee (me)'s data, see: Emacs's Command Frequency Sans Xah Lee's Data. For the previous version of this report, made in 2007 with much less data, see: Emacs's Command Frequency (Old).
If you like to participate in this research, please download command-frequency.el and send me the output. I will incorporate your data into the next report update. Thank you.
Files people have sent to me for report but i haven't had time to process:
- .emacs.keyfreq.Daniel_Hackney_2012-05-18.el
- Fabrice_Niessen2,,2010-05-04.el
- erik_winkels_2010-06-21.txt
- Xue_Fuqiao_2013-05-01.txt
- Xah_Lee_2013-09-04.txt
2013-06-06, 2013-08-06 addendum: i didn't have time to work on this. This project needs to be automated. The keyfreq.el package should automatically send user's results to a server (such as github, and with user's consent in a preference), and automatically generate statistics. If you are interested, get in contact with David Capello, the author of keyfreq.el, or, you can join the ergoemacs-mode developement at https://ergoemacs.github.io/, led by Matthew Fidler.
Acknowledgment
Ryan Yeske hacked up a quick elisp code that count commands for the current session. Michal Nazarewicz made it into a full featured minor mode, with the ability to read and write to a file to accumulate log across sessions, and print percentages in report. David Capello added a feature to also log the mode the command is from.
Thanks to Katsumi Yamaoka for pointing out the problem of “this-command”. Thanks to Stefan Guath for pointing out “real-last-command”. Thanks to all the people who provided me their data.