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.
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.
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
" 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) else au BufRead,BufNewFile * syntax match LongLine /\%>80v.\+/ au InsertEnter * syntax match WhitespaceEOL /\s\+\%#\@<!$/ au InsertLeave * syntax match WhitespaceEOL /\s\+$/ endif
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.
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.
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.