Some Vim protips

Utilities

7 minutes

Vim is a great editor and vimtutor is a great way to begin learning how to use it. Occasionally, however, you’ll find needing much more specific tools that are not often contained in an introductory manual, here are some of my favorite less known uses of Vim.

Motions

Maybe you know you can move up/down a paragraph with {/}, but did you know you can also move up/down a sentence with (/)? Also you can go to the first line on the screen with H (for high), to the last line with L (for low) and to the middle with M.

While not technically motions, scrolling can be useful as well: you can put your current line at the center with zz and put it at the top/bottom of your screen with zt/zb.

Changes

A truly wonderful feature of Vim is the hability of organizing the latest unsaved changes for files with :changes, which should display a list like the following

change line  col text
    2    85    0 ---> The cow jumped over the moon.
    1   109   45 ---> There is some text missing from this line.
>
You can jump to the Nth previous change with Ng; and to the Nth following change with Ng, (in this example, 2g; goes to “The cow…”).

Marks

Just like buffers and macros, associated to every lowercase character c you can put a mark with mc and then open it with '{mark}. Marks even work through multiple files, to do so you must make them uppercase or numeric and open them with '{Mark} as well.

By default, Vim creates automatically certain marks such as '^ for the last position where text was inserted, '. for the last change made, '[/'] for the first/last character of the last changed or yanked text and '</'> for the first/last character of the last visual selection.

This allows the user to jump back and forth inside a file, though it can be slightly misleading since marks are invisible; however, you may take a look at your marks with :marks. You can also delete marks with :delm[ark] {list} (for example, :delm ab1 d-f deletes all marks a, b, 1, d, e and f).

Wrapping lines

If you have long lines in Vim you can cut them with the operator gq to get them into the 80-character limit (or gw to not move the cursor position). You can join multiple lines instead with the operator J.

Long lines will wrap by default, in order to move down/up through wrapped lines you should use gj/gk. Moreover, you can go to the beginning/end of a wrap with g0/g$. You can also go the N percent of a wrap (from left to right) with NgM (for example, 50gM moves to the approximate half of the line, while 90gM is near the end).

(Un)folding lines

Very recently I discovered the wonderfull world of folding in Vim. You can select some not-so-important lines with V and now fold them with zf (this is actually an operator and, as such, you can do things like zfip to fold the entire paragraph). This temporarily hides them, but you can always unfold them (or open them) with zo and close them again with zc, you can toggle this with za. You can fold lines recursively (i.e., making folds inside of folds) and open/close them recursively with zO/zC. You can delete a fold under the cursor with zd (or zD for recursiveness), and undo a fold with zx.

Since folding can made recursive, each fold has a level (or should it be a depth?). You can increase the level globally with zm (to fold more) and decrease it with zr (to reduce foldings). You can close/open all folds with zM/zR.

After making all the necessary folds, you may save them with :mkvie[w] and reload them with :lo[adview]. If you don’t want to do this every time you close and open a file, you can turn it automatic with the following code on your .vimrc:

autocmd BufWinLeave *.* mkview
autocmd BufWinEnter *.* silent loadview 
Foldings are also quite useful movement-wise. You can move up/down to the next fold with zk/zj. You can also move inside to the beginning/end of a fold with [z/]z.

Finally, and this is quite the cherry on top, you can automatize foldings. By default Vim uses the foldmethod=manual, but if you write Python files it might be better to use :set fdm=indent or if you write C files it might be better to use :set fdm=syntax.

Natively, Vim doesn’t include too many smart options for folding LaTeX files, but the plugin vimtex certainly does. For instance, to automatically fold both the preface and long multi-line comments you may add the following to your .vimrc:

let g:vimtex_fold_types = {
   \ 'preamble' : {'enabled' : 1},
   \ 'comments' : {'enabled' : 1}
   \}
You can learn more about folding with :help usr_28.

Multiple files at once

Most people either use a tiling window manager or a terminal tabbing system, but Vim offers one by default (and I do believe it’s better!). You know you can open horizontal splits by :split <file> and vertical ones with :vsplit <file>, but Vim also allows for tabs with :tabnew <file>; personally I prefer tabs unless I am editing documents back-to-back. You can also open up multiple files with vim from your terminal by running:

vim -[oOp] <file1> <file2> <...>
where the -o/-O/-p flag tells it to open up in splits/vertical splits/tabs.

You can move between splits with <Ctrl-w>[hjkl], you can make two splits (either horizontal or vertical ones) the same size with <C-w>=, and also change increase the size of the splits with:

  • <C-w>+/<C-w>- for horizontal ones (you can use :<NUM>winc [+-] in the command line).
  • <C-w>>/<C-w>< for vertical ones (you can use :<NUM>winc [><] in the command line). You can also manually set your vsplit to have N lines with zN<Enter>.

You can navigate one tab up/down with gt/gT, you can move your current tab one space before or after with :+tabm/:-tabm, and also put your current tab in the n-th position with :<n>tabm and finally you can save your current session with :mks <session>.vim. You may then re-enter your session with vim -S <session>.vim and then save the current changes with :mks! <session>.vim; I use the following on my ~/.vimrc to update sessions automatically with ZS:

fu SessionSave()
	if exists("v:this_session") == 1 && "v:this_session" != ""
		exe "mks!" . v:this_session
	endif
endf
nnoremap ZS :call SessionSave()<CR>
Also, I believe Vim’s syntax for comparing files is absolutely astonishing. Instead of the usual diff <a> <b> you can use vim -d <a> <b> and navigate through both files, you can skip onto the next/previous change with ]c/[c.

Misc

If there is an integer number under the cursor (including sign), you can increase/decrease the number with <C-a>/<C-x>. Just very recently I found that you can create smart lists with Vim by block-selecting (i.e., with <C-v>) a block of same numbers and gradually increase/decrease them with g<C-a>/g<C-x>. For instance, the list:

1
2
3
4
1.
1.
1.
1.
May become the following (after 2G<C-v>jjg<C-a>):
1
2
3
4
1.
2.
3.
4.

Some further configurations at vimrc

You may know this already, but Vim does allow for configurations specific towards certain filetypes.
For instance, the following line sets automatic folding for Python only:

autocmd FileType python set fdm=indent
autocmd FileType c      set fdm=syntax
Another reason might be that certain color palettes work better in filetypes than others, or that it can be helpful for creating file-specific methods of “compilation”. The following might be an example:
autocmd FileType tex    nmap ZR :silent!<space>latexmk<space>-pdf<space>"%"<cr>
autocmd FileType python nmap ZR :!<space>python<space>"%"<cr>
You can check the filetype of a certain file in Vim with :set ft?.