Page
ReadView sourceView history

Design philosophies of Vim vs Emacs

From Issawiki (static archive)

Modal vs chording

Unix as IDE vs Emacs as OS

Vim tries to just be a text editor, and tries to play nice with the other tools on your computer, using commands like :!command (runs external command) or :w !command (pipes text to external command via stdin) or :r !command (reads from external command via stdout).

...with some exceptions

Vim has a built-in spellchecker, whereas Emacs doesn't (it does come with flyspell, which works with an external spellchecker like hunspell or aspell). (Emacs comes with tetris, an RPN calculator, an email client, etc., but not a spell-checker!)

Session management: per project vs single instance

The "right way" to use Vim is to have one instance of Vim open per "project". Each Vim instance maintains its own current directory, so you can e.g. open files relative to that current directory.

In Emacs, the expectation is that you will have a single Emacs instance open. Emacs itself doesn't maintain its current directory, and instead all file-open actions are relative to the buffer's directory.

Vim can do the Emacs thing with :set autochdir, but this is disabled by default.

See this blog post for more details.

Line-based vs character-based

Vim comes from a lineage of line-based editors. Registers can be linewise or characterwise, which means that actions like pasting text can act on entire lines or on characters. Some commands, like :substitute or :global, only work linewise. This is even reflected in the motion to move up or down a line: by default, j and k move down or up by logical lines instead of screen lines. However, due to this lineage, Vim does not deal well with long lines of text. Recent version of Vim have :set smoothscroll, but this only partially works.

Emacs is like most other text editors in that it has no concept of linewise. Ctrl-n and Ctrl-p move by screen-lines, not logical lines, which makes sense when you think of the buffer of text as a stream of characters rather than an array of lines.

Mappings: keystroke based vs function-based

In Vim, commands like "copy text" don't have a "name"; they are simply the keystroke that is used to perform that action. So if you want to "program" Vim to repeat some action, such as when defining a mapping, you simply tell Vim which keystrokes you want to repeat.

In Emacs, every keystroke, even entering a single character, has a function that is associated with it. Emacs is simply an interpreter that runs the function associated with the keystroke. You can always do Ctrl-h k followed by the keystroke to find which function is bound to that particular keystroke.

I think that being keystroke-based is one of the reasons Vim is so conservative about default keybindings (even when they are terrible, like Ctrl-b to go to the beginning of the line in command-line mode, or Y to copy the entire line instead of copying to the end of the line), because if you change the default keybinding inside of the C source code, it actually breaks all user mappings and scripts that rely on replaying keystrokes. So then eventually Vim came up with defaults.vim, which is not implemented on the level of C, but instead implemented on the level of Vimscript. By implementing it in Vimscript, it functions like user configuration, so it doesn't change what the original keybindings mean. But doing this also means now you have to reason about multiple levels, the "base layer C keybindings" vs the "default keybindings that you actually interact with". And at that point you've kind of reinvented the thing that Emacs does.

Actions: commands vs keybindings

Vim often uses the command-line for even common actions, e.g. :w to save a file [1]. Emacs relies more on keybindings, e.g. Ctrl-x Ctrl-s to save a file.

But there are some exceptions. To open the file that the cursor is on, Vim has various keybindings, including gf, gF, Ctrl-w f, etc., but Emacs only has M-x ffap.

Tree-based undo vs stack-based undo

(I think the mark ring in Emacs is also stack-based.)

Multiple similar commands vs single repeated command

This one is a bit hard to explain, but there is a definite pattern where Vim prefers to give the user multiple similar commands, while Emacs prefers to give a single command that you can then repeat or use creatively. The best way to explain is to give a bunch of examples:

In general, I feel that Vim requires more mental energy to use (by forcing the user to pick the action more precisely, and by having the user plan ahead). You need to pick the specific action you wanted to perform. You need to think ahead and decide which registers to use. This also comes from Vim's modal nature, but Vim gives you more decisions and a grammar, whereas Emacs gives you a way to quickly do the common thing. I think much of this may have been forced on the design of Vim by deciding to be keystroke-based, so that the only way to make some action available in normal mode was to assign some key to it. Whereas Emacs went more in the direction of being functions-first, and once you have functions, it is natural to pass arguments to the function to modify the behavior.

Word movement: consistent vs "do the common thing"

Vim's word-based motions like w, b, and e always treat contiguous alphanumeric sequences as single words, and also treats contiguous symbols as single words. This leads to a very consistent word movement, which means you will never have to backtrack.

Emacs does the thing that most other text editors do, which is that if the cursor is before/on a symbol, then moving forward by one word will not just jump to the end of the symbols, but will jump to the end of the alphanumeric sequence after the symbols. Emacs caters to the most common thing, and sometimes you need to backtrack.

Suppose you have some text like: Hello, world. and the cursor is past the final period. You want to add the word there before the comma, to make it Hello there, world. In Vim, you press b a few times to move backwards by word, until the cursor is on the comma, at which point you can go into insert mode to type the "there". In Emacs, Alt-b will move the cursor back by word, but once the cursor is on the 'w', pressing Alt-b again will jump past the comma onto the 'H' -- in other words, it overshoots. So then you need to backtrack by pressing Alt-f to move forward by word.

Scrolling: scrolloff vs scroll-into-view

In Vim, defaults.vim sets scrolloff=5, which means that when the cursor is at the edge of the window, it will always show 5 lines of context. You can never "touch" the very edge of the screen, because the screen will scroll when you try to move to the edge. (But due to Vim's line-oriented heritage, this will scroll into view an entire logical line instead of just one visual line.)

In Emacs, the default behavior is instead to jerk the screen to the center after you step off the edge.

Search and replace

Emacs automatically does all the case variants, e.g. if you search and replace foo → bar, it also does Foo → Bar, FOO → Bar, etc. Vim doesn't do this.

Visual noise

Emacs has more visual noise, e.g. the line continuation markers, incremental search by default, highlighting of all search matches as you type, a status bar. Vim comes from an environment where terminals were very slow so it tries by default to not draw to the screen very much. This means fewer things flash on the screen as you do things -- quite monastic vibes.

Of course, by modern standards of things like VS Code, Zed, JetBrains, etc., even Emacs will feel minimal! No line numbers, sidebar with a file tree, no minimap that shows a zoomed out view of the file, no tabs shown by default, no git gutter, no git blame next to every line as the cursor moves, no popups nagging you about updates or extensions to install, no breadcrumbs (path of nested scope at the top), no hover-over documentation.

Both Vim and Emacs have prominent comment colors in their syntax highlighting by default (in Vim it's blue, in Emacs it's red), which I think says a lot. By making most things invisible but making comments stand out, it tells the user that comments are something worth paying attention to. They both come from a saner culture in which programmers were intelligent and comments meant something. Now modern editors have all this crap in your face, and not just that, they make comments grayed out so that they almost fade into the background (VS Code is the one exception, where its default colorscheme has green comments).

Prompting the user

For Vim, see [2].

Emacs often prompts the user.

Documentation: graph/linear vs tree

Vim uses a wiki-like help system, where you can click on links to read the sections. It also contains a linear book under :help user-manual. Emacs has a GNU-like hierarchical tree documentation system.

Both have a way to look things up based on keystroke or command name though. Vim has a universal :help command, while Emacs has e.g. Ctrl-h k for keystrokes or Ctrl-h f for functions.

Selection endpoint

Vim includes the selection endpoint, whereas Emacs doesn't. The need to make this decision comes from both editors originating on the terminal with block cursors, rather than the more modern I-beam cursors.

Messages: clear as late as possible/explicitly vs clear as soon as possible

Vim only clears messages when the user does ctrl-l or does something that would redraw the screen somehow. Emacs clears as soon as the cursor is moved.