Notes on Vim
(22 July 2011)

This is a list of things in Vim that I have learned but find hard to remember.


We know that w moves forward a word, but W moves forward a word without stopping at symbols and punctuation.

uu is a classic trick to move to the position of the last edit by undoing it, and the undoing the undo. This doesn's work in Vim where you have infinite undo. Use `. to jump to the mark of the last change instead.

The + (or just enter) and - characters move the cursor to the first character of the next and previous line, respectively.

0 and $ moves to the beginning and end of a line respectively. ^ moves to the first nonblank character. n| moves to column n. Useful e.g. when investigating a compiler error at a specific line and column.

Use ; to repeat previous f (find-character-in-line) command.

Marks. Use mx to set mark x. Use `x to jump to mark x. (Or 'x to first character of that line.) Vim sets lots of special marks, use :marks to show a list. I find . (last change) and ^ (end of last insert) most useful.

Edit Commands

Repeat last edit with .. I wish there was a command to "repeat the last move".

Just as move commands take numeric prefixes, so do insert commands. To append 10 xs to a line: 10Ax. The r command does this too. To replace five characters with x, do 5rx.

Registers: Last deletions are stored in registers 1 to 9. Registers a to z are available for general use. To paste from a certain register x, use "xp. To yank the current line into register x, use "xyy. The thing to remember is to prefix with "x. There are many special registers; prehaps most notably, * is the system clipboard.

Filtering text through a command is super useful. I tend to select a line range with visual mode, and then pipe through sort for example, with !sort. Useful for sorting include directives in C and C++.

Use << and >> to shift left and right by the shiftwidth amount. Always have shiftwidth set to the same value as tabstop.

Use CTRL-n for auto completion. Use CTRL-n and CTRL-p to cycle and select match.

Change case with ~. This does not make sense with Swedish keyboard layout.


Use qx to start recording a macro into register x. Stop recording by pressing q again. Use @x to replay the macro in register x. Use @@ to repeat the last macro replay.

Screen Position

I tend to remember CTRL-u (up) and CTRL-d (down) which scroll by half screens. CTRL-f (forward) and CTRL-b (backward) scroll whole screens.

scroll-cursor: z followed by return makes current line the top line, z. makes current line the center of screen, z- makes current line bottom of screen. Giving a prefix makes z use a specific line rather than the current, e.g. 42z. puts the cursor on line 42 and makes that line center of the screen.

To do the opposite of moving the screen around a certain line, we can move to a certain line on the screen: H (home) moves cursor to the first line on the screen, M (middle) moves to the middle line, and L (last) moves to the last line.


Edit a file in a new tab with :tabe. Use gt to go to the next tab, and gT to go to the previous. Use ngt to go to tab n. Use :tabl to go to the last tab.

Use vim -p file1 file2 to open files in separate tabs.


It can be very useful to set different options for different directories, for example when working on projects with different style guidelines:

autocmd BufNewFile,BufRead /path1/* set tabstop=4 shiftwidth=4
autocmd BufNewFile,BufRead /path2/* set tabstop=2 shiftwidth=2

The LLVM project has some useful suggestions for .vimrc here. This is a bit of it that I like to use:

" Highlight trailing whitespace and lines longer than 80 columns.
highlight LongLine ctermbg=DarkYellow guibg=DarkYellow
highlight WhitespaceEOL ctermbg=DarkYellow guibg=DarkYellow
if v:version >= 702
  " Lines longer than 80 columns.
  au BufWinEnter * let w:m0=matchadd('LongLine', '\%>80v.\+', -1)

  " Whitespace at the end of a line. This little dance suppresses
  " whitespace that has just been typed.
  au BufWinEnter * let w:m1=matchadd('WhitespaceEOL', '\s\+$', -1)
  au InsertEnter * call matchdelete(w:m1)
  au InsertEnter * let w:m2=matchadd('WhitespaceEOL', '\s\+\%#\@<!$', -1)
  au InsertLeave * call matchdelete(w:m2)
  au InsertLeave * let w:m1=matchadd('WhitespaceEOL', '\s\+$', -1)
  au BufRead,BufNewFile * syntax match LongLine /\%>80v.\+/
  au InsertEnter * syntax match WhitespaceEOL /\s\+\%#\@<!$/
  au InsertLeave * syntax match WhitespaceEOL /\s\+$/

Set guioptions to remove some components from the gvim GUI. Hiding the menus, buttons, etc. that you never use gives a cleaner experience. In my .vimrc, I normally do:

:set guioptions-=M   "remove menu bar
:set guioptions-=T   "remove tool bar


Ex command-lines start with a : followed by a line range. No range means current line. The range 1,3 means lines 1 to 3. $ is the last line in the file. % is equal to 1,$, that is, all lines in the file. We can also use g/pattern/ to specify all lines that contain pattern.

The line range is followed by a command. If we do not specify a command, we get the default command, p, which prints the lines. The command I use the most is s for substitution. E.g. %s/foo/bar/ substitutes foo with bar on every line. Add the g flag after the last / to allow for more than one match in each line. There is also d for delete.

Combining with the g line range thingy, we can do :g/patt/s/foo/bar/g, which will replace all occurrences of foo with bar on lines that contain patt.

The search patterns are basically ordinary regular expressions. Two very useful metacharacters are \< and \> which force the match to be at the begining or end of a word, respectively.

Other commands. :r reads a file and inserts it at the line after the cursor. :w file writes the current buffer to a file. It is also possible to do :w >>file to append to a file.

Combine r with ! to read the results of a command into the file: :r !hostname.


Use :set to show which options you have set (i.e. not showing defaults). Use :set option? to show the value of some option.

Abbreviations. Set with :ab foo bar. When you type foo, it will be expanded to bar. Remove abbreviation with :unab foo, show all abbreviations with :ab.

Control whether searches wrap or not with the wrapscan option, i.e. :set wrapscan or :set nowrapscan.

Command-line Arguments

I use vim +n filename to open a file at a specific line a lot. Ommit n to open at the last line. Use vim +/word filename to open at first search match for word. Use -R to open read-only.

Some more Vim command-line flags: -b binary edit mode, -c command execute an ex command (you can have more than one of these).


Press CTRL-v to enter blockwise visual mode. This lets you select a rectangular area, which you can then apply an edit operation to. Sometimes called column editing.

Use CTRL-g to show info about total number of lines. Use g CTRL-g to show word count, byte count, etc.