Vim notes & plugins

Basic vim

All this is vim built-in and requires no plugin.

Useful commands

  • %: jump to the matching { .. } or ( .. ) etc.
  • =: indent visual selection (<: shift block to the left, >: shift block to the right)
  • ~: change case
  • ctrl-x + : vim ‘context aware’ complete mode (based on set complete list) in insert mode
    • ctrl-n/ctrl-p: next/previous word matching prefix (the difference with ctrl-p/ctrl-n is the context awareness)
    • ctrl-f: file names
    • ctrl-l: whole lines
    • ctrl-d: macro definitions (also in included files)
    • ctrl-i: current and included files
    • ctrl-k: words from a dictionary
    • ctrl-t: words from a thesaurus
    • ctrl-]: tags
    • ctrl-v: Vim command line
    • ctrl-o: language aware completion
  • :set spell [spelllang=fr_fr]/:set nospell: activate/deactivate spell checking
  • :!<command>: execute <command> in a shell without leaving vim (e.g. :!make)
  • :read !<command>: insert result of <command> on next line (e.g. read !ls .)
  • ctrl-O, ctrl-I: navigate through “jump locations” locations, both within current and other opened documents; :jumps to list all jump locations.
  • .: repeat last command

Macros

  1. q<key>: start recording
  2. (do commands)
  3. q: stop recording
  4. @<key>: replay macro

Advanced editing (command mode ex/ed)

The command mode syntax basically reads

:[[start_line],[end_line]]<verb>/<pattern>/<action>

Lines shortcuts

  • :%:1,$: all the lines
  • .: current line
  • $: last line

Verbs

  • g: match line with pattern
  • v: reverse match lines
  • s: substitute

Action

  • d: delete
  • y: yank
  • <position>j: join (-1j go up one line and join)
  • m<position>: move lines (e.g. m$ to move at the end of file)

Examples

  • :%g/foo/s/bar/zzz/g: for every line containing foo substitute all bar with zzz.
  • :%g/bar/m/baz/+1: moves next bar occurrence 1 line after next baz occurrence
  • :%g/bar(/ normal nmaf(ldi(`aPa.:
    1. g/bar(/ executes the following command on every line that contains “bar(”
    2. normal execute the following text as if it was typed in in normal mode
    3. n goes to the next match of “bar(” (since the :g command leaves the cursor position at the start of the line)
    4. ma saves the cursor position in mark a
    5. f( moves forward to the next opening bracket
    6. l moves right one character, so the cursor is now inside the brackets
    7. di( delete all the text inside the brackets
    8. `a go back to the position saved as mark a (i.e. the first character of “bar”)
    9. P paste the deleted text before the current cursor position
    10. a. go into insert mode and add a “.”
  • vim convert.csv "+:v/^\"oai:/-1j" "+wq" : concatenate lines starting by "oai: with previous line using a non-interactive script

Plugins

Vim plugins ecosystem is gigantic and it can feel overwhelming when it comes to actually choosing what plugin to use. Here are some details about my current configuration.

Plugin manager

There are lots of vim plugin managers (vundle, pathogen). All those make testing plugins straightforward and will handle the vim runtimepath and basically allow to simply clone the plugin in a folder and not moving data around. Some are obsolete, some are slow. After testing multiple choices, it feels like vim-plug is just the best alternative:

  • it’s really blazing fast (and I didn’t consider this as a big issue until I tried vim-plug)
  • it offers multiple hooks like a post-install hook to e.g. call a build script

Sublime democratized this feature. Typing full path can be a pain, especially for large projects. For this again, there are multiple alternatives like ctrlp (rather slow) or unite (very powerful but rather complicated to setup). fzf (note that this is the same author as vim-plug) is just great. Defaults are sane, it’s incredibly fast, and like unite it’s highly customizable. The only thing that I’m missing – but that may be possible – is the configuration of the root search folder.

Closing pairs

Closing quotes/brackets/parenthesis can be automated. The feature interest seems obvious but its implementation is not. There are lots of alternatives, each making some assumptions about how clever they should be (e.g. when deleting an open quote). delitMate is my current choice as even with no specific configuration it doesn’t get in my edit way when it doesn’t need to.

Commenting lines

Commenting/decommenting code is a frequent operation when updating code. Each language has its own comment syntax and having a plugin handle this transparently and easily is a must. I usually operate by visually selecting lines and need a plugin that handle this; tcomment works very nicely. The only arguable feature missing is that calling the TComment function is not a command so it prevents from using .. This is not such a big deal as using the tcomment toggle should likely be mapped to a shortcut.

Side note: vim 703+ has a nice option removing comment character when joining commented lines

if v:version > 703 || v:version == 703 && has("patch541")
  set formatoptions+=j " Delete comment character when joining commented lines
endif

References