22 min read

48

Vim is a terminal-based editor optimized for speed. Keys are hotkeys by default. Vim does not even use Ctrl for most of them. Maneuvering via hotkeys is so efficient mouse input is often disabled by default.

This guide focuses on the features I use most frequently. It has nothing about with native Vim windows because I use i3 or Spacemacs instead. If you feel I left out a valuable feature then please let me know about it in the comments.

Movement

The simplest way to move is via the hjkl keys.

key action
h moves the cursor one character left
j moves the cursor one line down
k moves the cursor one line up
l moves the cursor one character right

The hl keys operate within a single line. Pressing h at the start of a line does nothing. Pressing l at the end of a line does nothing. By line I mean a string of characters ending with a carriage return. The fact that a long paragraph appears to wrap around on your screen is irrelevant.

The jk keys move the cursor down and up a single line. If the cursor is in the 3rd column of the 6th line then pressing j moves the cursor to the 3th column of the 7th line.

Most commands can be prefixed with a number. 4h moves the cursor left 4 characters. 101j moves the cursor down 101 lines.

A sequence of nonempty lines is called a paragraph. The {} keys move the cursor forward and back by paragraphs.

key action
} moves the curser forward one paragraph
{ moves the curser backward one paragraph

There are two kinds of "words" in Vim. A word is a sequence of alphanumeric characters. A Word is a sequence of non-whitespace characters. The wbe keys move the cursor around words. The WBE keys move the cursor around Words.

key action
w moves the cursor forward to the next start of a word
e moves the cursor forward to the next end of a word
b moves the cursor backward to the next start of a word
W moves the cursor forward to the next start of a Word
E moves the cursor forward to the next end of a Word
B moves the cursor backward to the next start of a Word

The #* keys move the cursor forward and backward to the next "idenfitier". If the cursor hovers over the word "marmot" then pressing * will move the cursor forward to the next instance of the word "marmot" and pressing # will move the cursor backward to the previous instance of the word "marmot".

key action
# moves the cursor backward to the previous identifier
* moves the cursor forward to the previous identifier

The f key takes a character as an argument and moves the cursor forward to that character. For example, fa moves the cursor forward to the next instance of a. The f key operates within a line. It will never take the cursor to another line. The F command is like f except it searches backward. The t and T commands are like f and F exvcept they move the cursor one fewer character.

The ; command repeats the most recent fFtT command. The , command is like ; except backwards. If you use an F command followed by a , then the double-backwardsness will cancel itself out.

key action
f<char> moves forward to <char>
F<char> moves backward to <char>
t<char> moves forward to the character before <char>
T<char> moves backward to the character after <char>
; repeats the previous fFtT command
, repeats the previous fFtT command except reversed

The 0^$ keys move the cursor to the beginning and end of a line.

key action
0 moves the cursor to the beginning of the line
^ moves the cursor to the beginning of the line, excluding whitespace
+ moves the cursor to the beginning of the next line, excluding whitespace
$ moves the cursor to the end of the line

The HLM keys move the cursor around relative to the viewing window itself.

key action
H moves the cursor the the start of the first visible line
M moves the cursor the the start of the middle visible line
L moves the cursor the the start of the last visible line

You can move the viewing window itself with z and Ctrl keys.

key action
Ctrl-e moves the viewing window down one visual line
Ctrl-y moves the viewing window up one visual line
Ctrl-f moves the viewing window forward by one viewing window
Ctrl-b moves the viewing window backward by one viewing window
Ctrl-d moves the viewing window forward by half of one viewing window
Ctrl-u moves the viewing window backward by half of one viewing window
zz moves the viewing window to position the cursor in the middle
zt moves the viewing window to position the cursor at the top
zb moves the viewing window to position the cursor at the bottom

You can move the cursor itself up and down visible lines with the g prefix.

key action
gj moves the cursor down one visual line
gk moves the cursor up one visual line

The g key can also go to a particular line.

key action
gg jumps the cursor to the beginning of the buffer[1]
G jumps the cursor to the end of the buffer
<num>gg jumps the cursor to the specified line
<num>G ''

The | key is like g except for columns.

key action
<num>| moves the cursor to the <num>th column within a line

The / key performs search. You type / then the string you are searching for and then press Enter. The ?nN keys are analogous to F;n.

key action
/ initiates a search
? initiates a backwards search
n repeats the previous search
N repeats the previous search except reversed

The () characters move forward and backward one sentence.

key action
) moves forward to the next start of a sentence
( moves backward to the next start of a sentence

The [] characters move the cursor forward and backward to a variety of things. My favorite uses of [] is to go forward and backward to matching parenthesis. For example, ]) moves forward to the next unmatched closing parenthesis. It is indispensable when writing Lisp. Inner quotes and tags behave similarly to parentheticals.

key action
]) move forward to matching parenthesis
]( ''
[) move backward to matching parenthesis
[( ''
[[ jump to function start
]] jump to function end

You can (invisibly) mark places in your buffer to return to later. You can set one mark per letter. Lowercase letters a-z are buffer-specific e.g. each buffer can have its own "a" mark. Uppercase letters A-Z are global e.g. only one buffer at a time can have an "A" mark.

key action
m<a-z> create a buffer-specific mark
m<A-Z> create a global mark
'<mark> jump to the beginning of the line with mark <mark>
`<mark> jump to mark <mark>

Some marks are populated automatically. Of the automatic marks, I only use ''. You can find the others here.

mark meaning
'' jump to last jump point

Editing

Now that you know how to move, we can edit some text. Most of the time you edit text you should use the dyp keys.

  • d stands for delete, which is similar to "cut".
  • y stands for yank, which is similar to "copy".
  • p stands for put, which is similar to "paste".

The d key operates on text objects and movement commands. For example dtA deletes everything up to (but not including) the next "A" on the current line.

Every delete operation operates on characters or lines. dtA operates on characters and thus behaves similarly to other editors. A delete operation which operates on lines deletes an integer number of lines. Delete operations which operate on lines delete the current line and the destination line. Thus, dj deletes the current line and the next line.

y is identical to d except it leaves your buffer unchanged.

delete or yank key action
d<char> deletes every character from the starting character up to (and including) the destination character
d<line> deletes every line from the starting line up to (and including) the destination line
dd deletes the current line
y<char> yanks every character from the starting character up to (and including) the destination character
y<line> yanks every line from the starting line up to (and including) the destination line
yy yanks the current line

p puts the selection before the cursor. P puts the selection after the cursor. "Before" and "after" refer to characters or lines depending on whether you deleted/yanked characters or lines.

key action
p put after the cursor
P put before the cursor

By default, p and P will put the last text you deleted or yanked. You can save text into registers by prefixing "<register> before your delete or yank command. For example, "add deletes the current line and saves it into register "a".

There is one register for each letter a-z. If you use a capital letter then your delete or yank command will append to the register instead of overwriting it. You can put from a register by prefixing your p or P command with the register. For example, "ap" will put from register "a".

You can find a list of special registers here.

Text Objects

Remember how I said you could follow d and y with a movement command or a text object? Remember from earlier the concept of "words" and "paragraphs"? Here we put them together into a simple grammar.

da deletes a text object.

key action
daw delete a word
daW delete a Word
das delete a sentence
dap delete a paragraph
da( delete a parenthetical
da) ''
yaw yank a word
yaW yank a Word
yas yank a sentence
yap yank a paragraph
ya( yank a parenthetical
ya) ''

You can replace the a with an i to delete an inner word, an inner paragraph, etcetera. An inner text object is just like the regular text object except it does not include any surrounding delimiters. In the case of a parenthetical, the "inner parenthetical" does not include the outside parenthesis. For words/sentences/paragraphs, the delimiter is whitespace.

key action
diw delete inner word
diW delete inner Word
dis delete inner sentence
dip delete inner paragraph
di( delete inner parenthetical
di) ''
yiw yank inner word
yiW yank inner Word
yis yank inner sentence
yip yank inner paragraph
yi( yank inner parenthetical
yi) ''

Other text objects include '"[]{}<>. They all do what you would expect them to do. t refers to an HTML-like tag.

Insert Mode

You cannot write everything by yanking and putting pieces of existing text together. Sometimes you have to insert text into a document. Several different keys drop you into insert mode.

key action
i inserts text before the cursor
a inserts text after the cursor
I inserts text at the beginning of the line
A inserts text at the end of the line
o creates a newline below the current line and inserts text there
O creates a newline above the current line and inserts text there
s deletes the current character and inserts text
S deletes the current line and inserts text

You can exit insert mode by pressing Escape but it is faster to remap your CapsLock key to Ctrl and then exit insert mode with Ctrl-[. Some hotkeys are valid only while in insert mode.

insert mode key action
Escape exits insert mode
Ctrl-[ ''
Ctrl-F moves cursor forward one character
Ctrl-b moves cursor backward one character
Ctrl-w deletes one word backward (without saving it to a register)

The c key is like d except it drops you into insert mode afterward.

key action
c<movement> clear text
c<text_object> clear text

After you exit insert mode, the whole insertion counts as a single edit. So if you type ci( followed by an insertion then the entire replacement of text inside the parenthetical counts as a single edit. You can repeat an edit with the . operator.

key action
. repeat previous edit

The . key might be the most important key in all of Vim. Generally-speaking, the more you use the . operator the better you are at Vim.

Miscellaneous edit commands

key action
x delete the character under the cursor
X delete the character before the cursor
~ toggle capitalization and move the cursor forward one character
r<char> replace a single character

The Undo Tree

u and Ctrl-r operate like the undo and redo stack you are familiar with.

key action
u undo last edit
Ctrl-r redo next edit

If you undo a long series of edits and then mistakenly make an edit you can undo the damage with g+ and g- which traverse the nodes of the tree in chronological and reverse-chronological order.

key action
g+ traverse undo tree in chronological order
g- traverse undo tree in reverse chronological order

Macros

A macro is a series of keystrokes. Macros are good for automating repetitive tasks, especially editing structured text.

To define a macro, start by pressing the q key. Then pick a letter a-z at which to save the macro. Then execute the macro manually. When you are done typing the macro, press q again.

Once you have a macro defined, you can press @ followed by the macro's letter to execute the macro.

key action
q define a macro
@<a-z> execute a macro
@@ execute previous macro

Macros are well-behaved. If a macro modifies a line and then goes down one line and you tell Vim to execute the macro 1000 times but your buffer only has 700 lines then Vim will stop when it gets to the end of your buffer.

Visual mode

Visual modes are similar to highlighting. Visual modes have their uses, but it is usually faster to avoid them.

key action
v enter visual mode
V enter visual line mode
Ctrl-v enter visual rectangle mode

Find and Replace

You can find and replace all the instances of a string by typing :%s/ followed by the original string followed by / followed by the replacement string followed by Enter…assuming you did not type any escape sequences. Find and replace is a complex subject I will not delve into here even though I do use it.

Enter and exit

You can enter Vim by typing vim into your terminal followed by the file you would like to create or edit. You can exit vim by typing : followed by a quit command.

command action
:q exit if no changes are pending
:q! force an exit even if changes are pending
:w write to disk
:wq write to disk and then exit

Typing ZZ does the same thing as the :wq command.

Cheatsheet


  1. If you are not from a Unix back then the term "buffer" may be unfamiliar. Just translate "buffer" to "file" or "document" in your head even though, technically, a buffer is more general than a document. ↩︎

New Comment
57 comments, sorted by Click to highlight new comments since:

Why do you believe that you are actually faster with Vim? I used Vim quite a while a bit and it usually still requires thinking to use it. I haven't seen any evidence that Vim actually makes programs faster that goes beyond programmers feeling faster. Do you have evidence for that, either through measuring your own performance or through another source?

After practicing Vim for a few months, I timed myself doing the Vim tutorial (vimtutor on the command line) using both Vim with the commands recommended in the tutorial, and a click-and-type editor. The click-and-type editor was significantly faster. Nowadays I just use Vim for the macros, if I want to do a particular operation repeatedly on a file.

I think if you get in the habit of double-clicking to select words and triple-clicking to select lines (triple-click and drag to select blocks of code), click-and-type editors can be pretty fast.

This is a great experiment, I'll try it out too. I also have pretty decent habits for non-vim editing so it'll be interesting to see.

I did :Tutor on neovim and only did commands that actually involved editing text, it took 5:46.

Now trying in Sublime Text. Edit: 8:38 in Sublime, without vim mode – a big difference! It felt like it was mostly uniform, but one area where I was significantly slower was search and replace, because I couldn't figure out how to go backwards easily.

Interesting, thanks for sharing.

I couldn't figure out how to go backwards easily.

Command-shift-g right?

I ended up using cmd+shift+i which opens the find/replace panel with the default set to backwards.

So, one of the arguments you've made at several points is that we should expect Vim to be slower because it has more choices. This seems incorrect to me, even a simple editor like Sublime Text has about a thousand keyboard shortcuts, which are mostly ad-hoc and need to be memorized separately. In contrast Vim has a small, (mostly) composable language. I just counted lsusr's post, and it has fewer than 30 distinct components – most of the text is showing different ways to combine them.

The other thing to consider is that most programmers will use at least a dozen editors/IDEs in their careers. I have 5 open on my laptop right now, and it's not because I want to! Vim provides a unified set of key bindings among practically every editor, which normally have very different ways of doing things.

So that's on the order of a 10x-100x order of magnitude reduction in vocabulary size, which should at least make you consider the idea that Vim has lower latency.

The issue is not just more choices but more choices to achieve the same result. In programming languages Python achieved a large user-base through being easy to use with it's core principles like "there should be one obvious way to do things". 

I have 5 open on my laptop right now, and it's not because I want to! Vim provides a unified set of key bindings among practically every editor, which normally have very different ways of doing things.

The problem is that it's not dependable when you can use the Vim shortcuts within user editors. If I use IdeaVim in IntelliJ I can use "*y to copy a lot of things to the clipboard but not for example the text in hover popups for which I actually need Crtl+c and where I lose the ability to copy the text when I let Vim overwrite the existing shortcut. 

Let's think about an example. I want to move my cursor. 

I might be in a situation when 3W, lllllllllllllllllllllllllllllllll, / with something else $b are all valid moves to get at my target location for the cursor. 

This has probably something like 3-5 seconds latency because I not only have to think about where my cursor should go about also about the way to get there. 

On the other hand without VIM, having a proper keyboard that makes arrow keys easy to reach I might have a latency of maybe 700 milliseconds. 

VIM frequently costs mental processing capacity because I have to model my code in my head in concepts like words (for w and b) that I wouldn't otherwise. 

If you're using non-modal editing, in that example you could press Alt+rightarrow three times, use cmd+f, the end key (and back one word), or cmd+righarrow (and back one word). That's not even counting shortcuts specific to another IDE or editor. Why, in your mental model, does the non-modal version feel like fewer choices? I suspect it's just familiarity – you've settled on some options you use the most, rather than trying to calculate the optimum fewest keystrokes each time.

Have you ever seen an experienced vim user? 3-5 seconds latency is completely unrealistic. It sounds to me like you're describing the experience of being someone who's a beginner at vim and spent half their life into non-modal editing, and in that case, of course you're going to be much faster with the second. And to be fair, vim is extremely beginner-unfriendly in ways that are bad and could be fixed without harming experts – kakoune(https://kakoune.org/) is similar but vastly better designed for learning.

As a side note, this is my last post in this conversation. I feel like we have mostly been repeating the same points and going nowhere.

The choices become much more obvious with experience. Waiting 3-5 seconds is completely unrealistic once you know what you are doing. I'd fall back to using the mouse well before 3 seconds, unless I'm in a remote terminal or something that doesn't support it, in which case I'd use / / ? and n.

You could theoretically target any character in the file using only Space to advance the cursor and gg to go back to the start (well, depending on your settings). But nobody even thinks to do it this way (because it's stupid), so it doesn't seem to drain any mental resources not thinking about it.

Similarly, experienced vimmers don't use hjkl very much. lllllllllllllllllllllllllllllllll is just not something that occurs to you when you think of (and act on) better options first. If you have to use an arrow key more than a few times in a row, you're doing something wrong. (I mean, sometimes I use js to scroll down as I'm reading, but I'm not going for speed in that case.) By the time you get to about 4-5 keystrokes, you're better off searching with / / ?.

Similarly, if you have to hit w more than a few times, you're probably doing something wrong. It's usually not something that even occurs to me.

I mostly jump around within a line by using f/F and ;/,. It's faster than going by word with w or by character with h/l. One still has to pick a character or two to target, and for longer jumps, one learns to avoid common characters like vowels, and learn to prefer rarer characters like punctuation. This is just a fast heuristic, I'm not mentally counting character statistics for my current line.

Similarly, if you have to hit w more than a few times, you're probably doing something wrong. 

Do you mean that for both doing "4w" and "wwww"?

Yes? I mean, other vimmers might feel differently, but I basically don't use counts like that. Counting to move the cursor is too much effort, especially if you're counting higher than 2-3. It's not worth the time it takes.

ww is the same number of keystrokes as 2w. I might use the latter if I needed a single motion operator to repeat later with ., like c2w, but ww or even www would be easier most of the time. Past that, we're getting to the 4-5 keystrokes where / is better, and you can probably do it in two to three keystrokes with f-something (;) as easily as www.

So rather than counting how many words to get from here to there to find the right number to enter before the w, I'm just looking at the there and hit f, plus whatever character I'm looking at getting to, or a less common one adjacent to it. If the cursor doesn't quite get there, you can ; a few times. If you overshoot, use , to reverse.

I've done pair programming with devs who don't know vim, and remember on multiple occasions watching the other dev try to make an edit while thinking that I'd be done by now if I was the one typing.

Most of the time, what I do with vim is at the level of habit and "muscle memory". I don't have to think about it. If I'm programming a macro or writing a regex, sure, I have to think. But the motion commands just happen now.

For me, Vim isn't about speed, it's about staying focused. If I have to move my hand between the keyboard and the mouse every time I want to move the cursor, I lose a little bit of focus. Vim solves this issue by not having to move the placement of your hands. Of course a pointing stick also solves most of these issues.

As far as I know there's almost no measurement of productivity of developer tools. Without data, I think there are two main categories in which editor features, including keyboard shortcuts, can make you more productive:

  1. By making difficult tasks medium to easy
  2. By making ~10s tasks take ~1s

An example of the first would be automatically syncing your code to a remote development instance. An example of the first would be adding a comma to the end of several lines at once using a macro. IDEs tend to focus on 1, text editors tend to focus on 2.

In general, I think it's very likely that the first case makes you more productive. What about the second?

My recollection is that in studies of how humans respond to feedback, there are large differences between even relatively short periods of latency. Something like vim gives you hundreds of these (learning another editor's keyboard shortcuts very well probably does too.) I can point to dozens of little things that are easier with vim, conversely, nothing is harder because you can always just drop into insert mode.

I agree that this isn't nearly as convincing as actual studies would be, but constructing a reasonable study on this seems pretty difficult.

My recollection is that in studies of how humans respond to feedback, there are large differences between even relatively short periods of latency. 

I would expect using VIM to increase latency. While you are going to press fewer keys you are likely going to take slightly longer to press the keys as using any key is more complex. 

I can point to dozens of little things that are easier with vim, conversely, nothing is harder because you can always just drop into insert mode.

There's the paradox of choice and having more choices to accomplish a task costs mental resources. Vim forces me to spent cognitive resources to chose between different alternatives of how to accomplish a task. 

All the professional UX people seem to advocate making interfaces as simple as possible. 

There's the paradox of choice and having more choices to accomplish a task costs mental resources.

As your vocabulary has grown, has your speech slowed down? Is it faster to look at the keyboard and type with one finger, or touch-type with all ten? Have you ever played fighting video games? Is someone who knows more moves at a disadvantage? It might depend on how much they've practiced them!

More conscious choices slow me down, it's true, but once it's ingrained at the level of habit, you can do it almost as fast as you can think it, just like speaking or typing or playing a fighting game. Learning to do it in the first place is slower, but like learning to touch-type, try to get it right before you try to get it fast.

When I touch-type words, I don't think in terms of individual letters. I don't move that way either. There are clusters of keystrokes that happen frequently in English text. My other fingers have already started moving to the next letters before I've finished pressing the first one. Vim's motion commands end up feeling the same way. It's just like typing words.

New vimmer: I need to swap a line with the next one. I should cut it and paste it after. What was the command for that again? D? Uh. Visual mode! hhhhhhhhhhhhhhhhhv. Um. k? no. j. l. $. d. Down? j. p! What? Uh, undo! u! Up? k! p! Why isn't this working? u! $! i! Enter. Aw screw it! Backspace! Right-arrow, Enter, p! Backspace! Escape, p! Phew!

Intermediate vimmer: I could select the whole line with V and cut with d or do a cut-motion with ^D. 0D is a little easier to reach than ^D though. Or dd. The dd is easiest. Am I still in insert mode? Escape, Escape. dd! Down? Oh, already there. Paste-below with p. p! Done.

Experience vimmer: swap-linesddpdone.

I'm not even thinking in terms of select-copy-paste steps here. ddp is a muscle macro in its own right, just like a common word or a practiced fighting-game move.

Is it faster to look at the keyboard and type with one finger, or touch-type with all ten? 

Touch typing doesn't increase the amount of choices if you do it properly. If you learn touch typing properly there's a single finger that's responsible for a single key.

As your vocabulary has grown, has your speech slowed down? 

That's a bad comparison because as my vocabulary grew I also get better got speaking. 

In cross language comparisons more choices, do slow down speakers. Speakers of a language with fewer phomenes are faster at speaking a single phoneme then speakers of a language with more different phonemes. 

I would expect using VIM to increase latency. While you are going to press fewer keys you are likely going to take slightly longer to press the keys as using any key is more complex.

This really isn't my experience. Once you've practiced something enough that it becomes a habit, the latency is significantly lower. Anecdotally, I've pretty consistently seen people who're used to vim accomplish text editing tasks much faster than people who aren't, unless the latter is an expert in keyboard shortcuts of another editor such as emacs.

There's the paradox of choice and having more choices to accomplish a task costs mental resources. Vim forces me to spent cognitive resources to chose between different alternatives of how to accomplish a task.

All the professional UX people seem to advocate making interfaces as simple as possible.

You want simple interfaces for beginners. Interfaces popular among professionals tend to be pretty complex, see e.g. Bloomberg Terminal or Photoshop or even Microsoft Excel.

This really isn't my experience. Once you've practiced something enough that it becomes a habit, the latency is significantly lower. 

How much experience do you have with measuring the latency of things to know what takes 400ms and what takes 700ms?

Anecdotally, I've pretty consistently seen people who're used to vim accomplish text editing tasks much faster than people who aren't, unless the latter is an expert in keyboard shortcuts of another editor such as emacs.

Even if total time for the task is reduced the latency for starting the task might still be higher.

I think about ~1year into using vim, I thought the same thing: I’m doing the same thing, just with more quicker steps, so it feels faster. But after that I persisted and now it’s actually faster. Part of it is expanding your repertoire and memorizing it (where you don’t have to think about it at all). Also vim editor by itself I still find very clunky, but using vim shortcuts in something like PyCharm is $$$!

But after that I persisted and now it’s actually faster. 

How do you know?

For any given thing you want to do imagine what it would take to do it without Vim and it’s just more & usually more awkward key strokes.

I’d say the only place where I still use mouse is to jump to a completely random place in code.

I've found that / is still often faster for that. Not always, but often. I still use the mouse sometimes.

For any given thing you want to do imagine what it would take to do it without Vim 

This reminds me of the person with whom I was arguing about what takes how long on Anki and who was saying that his own judgement of what takes how long is superior to the Anki statistics where I know how the code works and which actually measures the time correctly. 

Human imagination is not good at estimating what tasks have how much latency.

For people who are newer to vim, I think that reviewing lists like this is useful, but the main thing to realize is that there's always a clever, easy way of doing things in vim. If you're having some text-editing problem, and having to do lots of repetitive work, there will be a way of reducing that using vim. Then, when you have a problem and you are interested in sharpening your saw for a bit and you have the necessary free time, you can look up the clever way to do things.

Looking at VimGolf (https://www.vimgolf.com/) can also help make a link in your mind between useful shortcuts (like the ones listed in this post) and problems that can be solved easily with those shortcuts. For me at least, that makes it easier to recall the shortcuts when they would be useful.

This is a superb overview! I've used Vim for about 2 years now, but I still learned a bunch of things from this post that I didn't pick up from other cheatsheets or articles. 

My 2-cents: Vim itself is powerful as an editor, but I always missed some IDE features. What I've come to realise is that the real power of Vim is not the editor, but the keybindings. I installed the Vim extension in VSCode some time ago and have loved the hybrid workflow. Since then, I've been gradually incorporating Vim keybindings into all the tools I use for text — like Overleaf for writing papers in LaTeX and Zettlr for writing notes in Markdown. I still use Vim itself for small scripts and quickly editing files. It's so powerful being able to go between applications and never have to think about what your fingers are doing to transform ideas into output. 

One thing I still haven't quite figured out is in-browser text entry. So far, I haven't liked the solutions I've found, but it's something I'm looking into for the future. Writing this comment without my usual keybindings is... slow. 

I have to agree with this. Having one set of keybindings that you can take with you to most editors is something that really adds to the value of learning vim. I learned Sublime Text's shortcuts, then IntelliJ's shortcuts, which required a separate retraining. Learning vim required retraining again, but now I can bring that effort with me to new editing environments.

In addition, some old Unix utilities like less use a subset of Vim keybindings by default.

Yes! Even many websites and web apps implement some Vim standards. Particularly \ for search. 

I'm in the same boat. I do most of my text editing in Spacemacs with Vim keybindings. Please let me know if you figure out a good in-browser text entry solution.

I have an AutoHotKey script that copies any highlighted text, pops up a gVim window with that text, and then I can save it back into the clipboard with :wq. I works on any plain text field in any app that respects the C-c copy-selection shortcut. I'm sure someone with your skills could put together something similar. I think I had a variant that would also C-a to select all and then C-v after I closed gVim.

I also have a more involved AHK script that does a subset of vim commands in any normal text field while I hold down the tab button. Getting the f command to work was a bit of a trick. I kind of stopped using it once I got a Lenovo with a TrackPoint, but if anyone is interested I could try to dig it up and put in on GitHub or something.

It's funny that this came up on LessWrong around this time, as I've just recently been thinking about how to get vim-like behavior out of arbitrary text boxes. Except I also have the additional problem that I'm somewhat unsatisfied with vim. I've been trying to put together my own editor with an "API first" mentality, so that I might be able to, I don't know, eventually produce some kind of GTK widget that acts like my editor by default. Or something. And then maybe it'll be easy to make a variant of, say, Thunderbird, in which the email-editing text box is one of those instead of a normal text box.

(If you're curious, I have two complaints about vim. (1) It's a little bloated, what with being able to open a terminal inside of the editor and using a presumably baked-in variant of sed to do find-and-replace rather than making you go through a generic "run such-and-such program on such-and-such text selection" command if you want the fancy sed stuff. And (2) its commands are slightly irregular, like how d/foo deletes everything up to what the cursor would land on if you just typed /foo but how dfi deletes everything up to and including what the cursor would land on if you just typed fi.)

Vim is far from optimal, but it's very customizable, which makes it easy to paper over the more obvious cracks.

For alternative ideas, the Canon Cat had a pretty well-designed interface for text editing, which Jef Raskin described in The Humane Interface, which has influenced my thinking about UI design. It's still not as fast as Vim, but much easier to learn. The 80% solution for the 20% effort maybe. If you want to try it out, it's old enough that you can emulate it in your browser, although I had to download MAME to get all the keybindings working.

Hey, this was a great write-up! Quite comprehensive, and definitely showcases more of the functionality than I normally use. 

Another useful trick is that you can increment and decrement numbers. In normal mode, making sure your cursor is on the same line and before or on the chosen number, press ctrl a to increase by one, or ctrl x decrease by one. You can combine this with a prefix (just like above with jumping lines), so 56 ctrl a will increase the next number on that line by 56. This is most useful with integers, not so great with decimals.

Edit: formatting.

Nice; didn't know about ;

A couple months after reading this post, I am now getting a big burst of dopamine every time I use the . key in vim.

(Even though it's just on the level of "Insert/replace the same text in multiple places")

In my opinion, the 4 killer features of vim beyond moving around and basic editing are:

  • macros
  • the s command used with regular expressions
  • the g command (see e.g. Power of g)
  • the ability to run text through any Unix utility (Vim and the shell)

If you know your Unix utilities (I often use awk inside of vim; it's also great outside of it), your regular expressions, and these features, you can sculpt any text as you wish. What I mean is that you can take the output of pretty much anything, in a messed up format, and transform it into the content and format you want. This is supposed to be inspiring but I'm not sure how good a job I'm doing.

Also, if anyone's interested, here are my current vim Anki cards. I use Anki for keyboard shortcuts which are supposed to be muscle memory, AMA

Some highlights from my .vimrc

" Prevent data loss
set undofile
" Flush to disk every character (Note: disk intensive, e.g. makes large copy-pastes slow)
set updatecount=1

" Directory browsing usability
let g:netrw_liststyle = 3 " tree list view
let g:netrw_banner = 0

" Copy for X11
vnoremap <C-c> "cy <Bar> :call system('xclip -selection clipboard', @c)<CR><CR>

Also worth checking out CoC (language server)

There is a typo: "idenfitier" instead of "identifier"

Hi, I downloaded vim for the first time, after reading your post. It is fascinating program, and learning about it is another interesting experience. Now, I have three things to ask you.

  • Why didn't you write about [ESC] and [i] keys to turn on and off the [vim mode]? I had no idea but just messing with it, before I can activate these cool shortcuts. Hahaha
  • I write stuff and save constantly. In Vim, whenever I save, it creates another file ~[filename], over and over again.  How do we organize files for vim?
  • Lastly, how do we paste outside texts to the vim? :p didn't work.

I just dumped you all these questions, sorry about that, but I appreciate your help much.

  • Escape is too far from homerow compared to Ctrl+[. It's better to use Ctrl+[. I wrote about the i key in the "Insert Mode" section.
  • I'm not sure I understand the question. I take it you mean you save various versions of the same file? For version control, I use Git.
  • If you're using Vim via the terminal, you can often paste via Ctrl+Shift+v.

O I like these keys. Thank you

I'm not sure I understand the question.

Each time I save progress, vim creates another file. At the end, I have multiple files in addition to the original one. But it seems like it is not supposed to work that way?  

It shouldn't be that way at all. The normal way to save progress while you're editing a file is to type :w followed by the Enter key. If you do this, Vim should write (or overwrite) the file on disk, resulting in a maximum of one file. (I'm ignoring the hidden temporary file.)

[-]krg10

Nice, I've only used VIM for a year so far, and now I'm stuck with it and happy.

Are these typos?

<num>gg - jumps the cursor to the beginning of the buffer

And the results for p and P being "before" and "after" are switched, at least I believe so. For me p pastes after, and P pastes before.

Fixed. Thanks.

Modal editing is a nice idea for compressing many hotkeys - it's a shame IDEs don't support defining your own modes.

You can exit insert mode by pressing Escape but it is faster to remap your CapsLock key to Ctrl and then exit insert mode with Ctrl-[.

I don't get how that's faster.

You have to reach farther for Escape than for CapsLock, which makes Escape slower.

I mapped fd to Escape, because that's what Spacemacs uses. It's also much less error-prone than jj and jk, which seem to be common choices.

Escape is farther from home row.

A question for the people who use vim keybindings in IDEs: how do you deal with keybindings for IDE tasks which are not part of vim (like using the debugger, refactoring, code completion, etc.)? The last time I tried to use vim bindings in an IDE there were quite some overlaps with these so I found myself coming up with compromise systems which didn't work that well because they weren't coherent.

At least for PyCharm, this was somewhat easier on macOS than on Windows, since you have control, option, command and shift, instead of just Ctrl, Alt, and Shift (well, and the Win key, but the OS reserves too many bindings there.) On macOS, The IDE uses command for most things, while Vim usually uses control when it needs a modifier at all. On Windows they both want to use Ctrl, so it's more difficult to configure all the bindings.

Some IDEs are just very accommodating about this, e.g. PyCharm. So that's great.

Some of them aren't, like VS Code. For those, I just manually reconfigure the clashing key bindings. It's annoying, but it only takes ~15 minutes total.

Thanks for your answer. Part of the problem might have been that I wasn't that proficient with vim. When I reconfigured the clashing key bindings of the IDE I sometimes unknowingly overwrote a vim command which turned out to be useful later on. So I had to reconfigure numerous times which annoyed me so much that I abandoned the approach at the time.

Thanks for this writeup. Could you share a bit more about how you got into using Vim and why you've found it to improve speed so much? I occasionally need to use vi when there's nothing else installed on a system, but the clunkiness and high barrier to entry has never made me tempted to use Vim as my primary editor.

Keyboard shortcuts are faster than the mouse. Keys accessible from homerow are faster than distant keys like the arrow keys. Keyboard shortcuts you can combine are more powerful than standalone keyboard shortcuts. As gianlucatruda mentioned, the important thing is Vim keybindings, not the editor itself. You can get a similar speed boost by installing Vim keybindings on your favorite editor.

I learned Vim very early in my programming career because I knew the upfront investment would pay itself over many times—and it has. Vim has paid my initial investment back many times over purely in terms of time saved. But speed does not just help me save time editing files. It also helps me think faster because my memory is volatile. For every time interval there is a chance I will forget a critical piece of information. My volatile memory puts a limit on how complex of a task I can handle. If my think-decide-act cycles iterate faster, I can complete more complicated tasks before my volatile memory expires.