Difference between revisions of "Design philosophies of Vim vs Emacs"
(→Modal vs chording) |
|||
| (36 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
==Modal vs chording== | ==Modal vs chording== | ||
| + | |||
| + | * Atomic edits and the dot command in Vim: When you use Vim, you naturally start to think in terms of repeatable edits that you can then use the <code>.</code> command to repeat. But this has a side-effect in that Vim requires you to manually chunk your undo history. Emacs instead automatically chunks undos. | ||
| + | * One consequence of the modal editing is that I think Vim degrades gracefully to having worse keyboards/a less ergonomic setup in general ([https://youtu.be/SY8L-cj4x6k?t=3594 or big hands]). For example, I bought a fairly crappy external USB keyboard for $25 where if I don't press the Ctrl key very firmly, sometimes it will not register. This hasn't been a problem in most software, but ''has'' become a problem when I use Emacs because I need to hold down the Ctrl key a lot for navigating with Ctrl+p and Ctrl+n. In Vim, I don't have this problem at all because Ctrl just isn't a key I need to hold down for long periods; it's something I momentarily hold down, just long enough to press another key. So I have never run into this problem when using Vim (or even Firefox or other software). Emacs is the editor, and really only software, that in some sense ''requires'' me to have a nice keyboard. | ||
==Unix as IDE vs Emacs as OS== | ==Unix as IDE vs Emacs as OS== | ||
| Line 6: | Line 9: | ||
Vim tries to just be a text editor, and tries to play nice with the other tools on your computer, using commands like <code>:!command</code> (runs external command) or <code>:w !command</code> (pipes text to external command via stdin) or <code>:r !command</code> (reads from external command via stdout). | Vim tries to just be a text editor, and tries to play nice with the other tools on your computer, using commands like <code>:!command</code> (runs external command) or <code>:w !command</code> (pipes text to external command via stdin) or <code>:r !command</code> (reads from external command via stdout). | ||
| − | ==...with some exceptions== | + | ===...with some exceptions=== |
| − | Vim has a built-in spellchecker, whereas Emacs doesn't. (Emacs comes with tetris, an RPN calculator, an email client, etc., but not a spell-checker!) | + | 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== | ==Session management: per project vs single instance== | ||
| Line 14: | Line 17: | ||
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. | 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, Emacs itself doesn't maintain its current directory, and instead all file-open actions are relative to the buffer's 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. | Vim can do the Emacs thing with :set autochdir, but this is disabled by default. | ||
| + | |||
| + | See [https://nullprogram.com/blog/2017/08/22/ 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 [https://www.reddit.com/r/vim/comments/267vrv/i_am_tim_pope_crafter_of_plugins_ama/chojzsb/]. 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 <code>gf</code>, <code>gF</code>, Ctrl-w f, etc., but Emacs only has M-x ffap. | ||
| + | |||
| + | ==Tree-based undo vs stack-based undo== | ||
==Multiple similar commands vs single repeated command== | ==Multiple similar commands vs single repeated command== | ||
| Line 24: | Line 51: | ||
* Changing the screen view relative to cursor: Vim gives you zz to scroll so as to leave the cursor at the center of the screen, zt to scroll and put the cursor at the top, and zb to scroll and put the cursor at the bottom. Emacs just gives you a single command, Ctrl-l, which when repeatedly pressed, will cycle between all three views. | * Changing the screen view relative to cursor: Vim gives you zz to scroll so as to leave the cursor at the center of the screen, zt to scroll and put the cursor at the top, and zb to scroll and put the cursor at the bottom. Emacs just gives you a single command, Ctrl-l, which when repeatedly pressed, will cycle between all three views. | ||
* Moving cursor to top, middle, bottom: Vim gives you H to move cursor to the top of the screen, M to move to middle, and L to move to bottom. Emacs just gives you Alt-r, which will cycle between the three configurations. | * Moving cursor to top, middle, bottom: Vim gives you H to move cursor to the top of the screen, M to move to middle, and L to move to bottom. Emacs just gives you Alt-r, which will cycle between the three configurations. | ||
| + | * Indenting: The way TAB indenting works in Emacs is very distinctive. You press TAB and Emacs just indents the line to whatever it thinks is the right level. Vim's TAB in insert mode just inserts a literal tab or spaces depending on the 'expandtab' option. But Vim also gives you, in insert mode, Ctrl-f to do the Emacs-like thing, Ctrl-t to indent the current line, Ctrl-d to decrease the indent of the current line. And many more commands in normal mode. | ||
* Folding: Vim gives you fine-grained commands like zo to open a fold, zc to close a fold, zR to globally reduce the fold level in the file, etc. Emacs as far as I know doesn't have folding by default, but certain major modes like org-mode and markdown-mode do have folding, and in these, you simply press TAB to cycle the different folding levels, or Shift-TAB to do the cycling globally across the entire file. | * Folding: Vim gives you fine-grained commands like zo to open a fold, zc to close a fold, zR to globally reduce the fold level in the file, etc. Emacs as far as I know doesn't have folding by default, but certain major modes like org-mode and markdown-mode do have folding, and in these, you simply press TAB to cycle the different folding levels, or Shift-TAB to do the cycling globally across the entire file. | ||
* Vim gives you Y, D, C, to copy, delete, and change (respectively) until the end of the line. Emacs just gives you Ctrl-k, which it then expects you to creatively make use of (e.g. if you want to copy until the end of the line, you do Ctrl-k to delete until the end of the line, then Ctrl-/ to undo). | * Vim gives you Y, D, C, to copy, delete, and change (respectively) until the end of the line. Emacs just gives you Ctrl-k, which it then expects you to creatively make use of (e.g. if you want to copy until the end of the line, you do Ctrl-k to delete until the end of the line, then Ctrl-/ to undo). | ||
| Line 29: | Line 57: | ||
* When you have multiple split windows, Vim has Ctrl-w followed by h, j, k, or l to move to that window. It also has Ctrl-w followed by w to keep cycling between the splits. It also has Ctrl-w followed by p to toggle between the two most recent splits. There are just a lot of fine-grained choices you can make. Emacs just gives you Ctrl-x o which cycles. | * When you have multiple split windows, Vim has Ctrl-w followed by h, j, k, or l to move to that window. It also has Ctrl-w followed by w to keep cycling between the splits. It also has Ctrl-w followed by p to toggle between the two most recent splits. There are just a lot of fine-grained choices you can make. Emacs just gives you Ctrl-x o which cycles. | ||
* Text formatting: Vim gives you two operators, gq and gw, which format text; gq moves the cursor to the end of the formatted text, while gw tries to keep the cursor where it was before the formatting. You can then combine these operators with any motion, e.g. gwip to format the current paragraph, gww to format the current line, gwib to format inside parentheses. Emacs just gives you Alt-q to format the paragraph. It is then up to you to creatively combine that with text selection; you can select some text and then do Alt-q to format just the text that is selected. | * Text formatting: Vim gives you two operators, gq and gw, which format text; gq moves the cursor to the end of the formatted text, while gw tries to keep the cursor where it was before the formatting. You can then combine these operators with any motion, e.g. gwip to format the current paragraph, gww to format the current line, gwib to format inside parentheses. Emacs just gives you Alt-q to format the paragraph. It is then up to you to creatively combine that with text selection; you can select some text and then do Alt-q to format just the text that is selected. | ||
| + | * Copy-pasting: Vim gives you named registers, so if you want to copy two different lines and remember both, you do something like <code>"ayy</code> and <code>"byy</code>; then you can paste them with <code>"ap</code> and <code>"bp</code>. In Emacs, you instead kill both lines, and then when you go to paste them, you first Ctrl-y to paste the most recent, and then you do Alt-y to cycle between the most recently killed text. | ||
| + | * Vim has j and k to move down and up by logical lines, and also has gj and gk to move down and up by screen-lines. Emacs only has Ctrl-n and Ctrl-p to move down and up by screen-lines. To move by logical lines, you need to do something creative like Ctrl-e Ctrl-f or Ctrl-a Ctrl-b, or just repeatedly press Ctrl-n or Ctrl-p. | ||
| + | |||
| + | 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: <code>Hello, world.</code> and the cursor is past the final period. You want to add the word <code>there</code> before the comma, to make it <code>Hello there, world.</code> 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 [https://www.reddit.com/r/vim/comments/267vrv/i_am_tim_pope_crafter_of_plugins_ama/chojzsb/]. | ||
| + | |||
| + | Emacs often prompts the user. | ||
==Documentation: graph/linear vs tree== | ==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. | 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. | ||
Latest revision as of 21:29, 4 December 2025
Contents
- 1 Modal vs chording
- 2 Unix as IDE vs Emacs as OS
- 3 Session management: per project vs single instance
- 4 Line-based vs character-based
- 5 Mappings: keystroke based vs function-based
- 6 Actions: commands vs keybindings
- 7 Tree-based undo vs stack-based undo
- 8 Multiple similar commands vs single repeated command
- 9 Word movement: consistent vs "do the common thing"
- 10 Scrolling: scrolloff vs scroll-into-view
- 11 Search and replace
- 12 Visual noise
- 13 Prompting the user
- 14 Documentation: graph/linear vs tree
- 15 Selection endpoint
Modal vs chording
- Atomic edits and the dot command in Vim: When you use Vim, you naturally start to think in terms of repeatable edits that you can then use the
.command to repeat. But this has a side-effect in that Vim requires you to manually chunk your undo history. Emacs instead automatically chunks undos. - One consequence of the modal editing is that I think Vim degrades gracefully to having worse keyboards/a less ergonomic setup in general (or big hands). For example, I bought a fairly crappy external USB keyboard for $25 where if I don't press the Ctrl key very firmly, sometimes it will not register. This hasn't been a problem in most software, but has become a problem when I use Emacs because I need to hold down the Ctrl key a lot for navigating with Ctrl+p and Ctrl+n. In Vim, I don't have this problem at all because Ctrl just isn't a key I need to hold down for long periods; it's something I momentarily hold down, just long enough to press another key. So I have never run into this problem when using Vim (or even Firefox or other software). Emacs is the editor, and really only software, that in some sense requires me to have a nice keyboard.
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
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:
- Changing the screen view relative to cursor: Vim gives you zz to scroll so as to leave the cursor at the center of the screen, zt to scroll and put the cursor at the top, and zb to scroll and put the cursor at the bottom. Emacs just gives you a single command, Ctrl-l, which when repeatedly pressed, will cycle between all three views.
- Moving cursor to top, middle, bottom: Vim gives you H to move cursor to the top of the screen, M to move to middle, and L to move to bottom. Emacs just gives you Alt-r, which will cycle between the three configurations.
- Indenting: The way TAB indenting works in Emacs is very distinctive. You press TAB and Emacs just indents the line to whatever it thinks is the right level. Vim's TAB in insert mode just inserts a literal tab or spaces depending on the 'expandtab' option. But Vim also gives you, in insert mode, Ctrl-f to do the Emacs-like thing, Ctrl-t to indent the current line, Ctrl-d to decrease the indent of the current line. And many more commands in normal mode.
- Folding: Vim gives you fine-grained commands like zo to open a fold, zc to close a fold, zR to globally reduce the fold level in the file, etc. Emacs as far as I know doesn't have folding by default, but certain major modes like org-mode and markdown-mode do have folding, and in these, you simply press TAB to cycle the different folding levels, or Shift-TAB to do the cycling globally across the entire file.
- Vim gives you Y, D, C, to copy, delete, and change (respectively) until the end of the line. Emacs just gives you Ctrl-k, which it then expects you to creatively make use of (e.g. if you want to copy until the end of the line, you do Ctrl-k to delete until the end of the line, then Ctrl-/ to undo).
- Vim has / to search forward, ? to search backward, then n or N to repeat that search in the same direction or opposite direction. Emacs just has Ctrl-s and Ctrl-r to do the search forward or backward. If you want to repeat the search, you just keep pressing Ctrl-s.
- When you have multiple split windows, Vim has Ctrl-w followed by h, j, k, or l to move to that window. It also has Ctrl-w followed by w to keep cycling between the splits. It also has Ctrl-w followed by p to toggle between the two most recent splits. There are just a lot of fine-grained choices you can make. Emacs just gives you Ctrl-x o which cycles.
- Text formatting: Vim gives you two operators, gq and gw, which format text; gq moves the cursor to the end of the formatted text, while gw tries to keep the cursor where it was before the formatting. You can then combine these operators with any motion, e.g. gwip to format the current paragraph, gww to format the current line, gwib to format inside parentheses. Emacs just gives you Alt-q to format the paragraph. It is then up to you to creatively combine that with text selection; you can select some text and then do Alt-q to format just the text that is selected.
- Copy-pasting: Vim gives you named registers, so if you want to copy two different lines and remember both, you do something like
"ayyand"byy; then you can paste them with"apand"bp. In Emacs, you instead kill both lines, and then when you go to paste them, you first Ctrl-y to paste the most recent, and then you do Alt-y to cycle between the most recently killed text. - Vim has j and k to move down and up by logical lines, and also has gj and gk to move down and up by screen-lines. Emacs only has Ctrl-n and Ctrl-p to move down and up by screen-lines. To move by logical lines, you need to do something creative like Ctrl-e Ctrl-f or Ctrl-a Ctrl-b, or just repeatedly press Ctrl-n or Ctrl-p.
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.