Some Vim tips and tricks
This started out as an internal training at Adfinis SyGroup to show off some Vim features and how to work best with it. I’m assuming that you know the absolute basics, like Vim’s primary modes like insert, normal, ex, and what each one does.
Preparations
It’s essential that you get some text somewhere to play around. How about some Samuel L. Jackston Lorem Ipsum text? Go and grab some paragraphs of that.
Getting around
Characters, words, sentences, paragraphs. Functions, code blocks, etc. Learn
them! There’s a lot more than what I’m showing here. To see more, just type
:help motion.txt
Basic editing
Try to use Vim’s editing features and commands, instead of hanging around in insert mode and editing by backspace, delete and typing text. We’ll get into more advanced usage later, but here’s some basic commands. All of those can be used with either a visual selection, a movement or a text object:
Keys | Explanation |
---|---|
c |
Change text. Basically a “delete” followed by an “insert”, but will only be one step in undo etc. |
gU |
Make text uppercase |
gu |
Make text lowercase |
Movements
Movement | Keys | Explanation |
---|---|---|
Characters | h , j , k , l |
J goes down, K goes up. H goes left, L goes right.. Use those instead of arrow keys, it’s faster! |
fX |
Go to the next occurrence of the character X | |
tX |
Go to the left of the next occurrence of the character X | |
Fx |
Go to the previous occurrence of the character x | |
Tx |
Go to the left of the previous occurrence of the character x | |
Words | w |
Go to the beginning of next word |
b |
Go to the beginning of the previous word | |
e |
Go to the end of the next word | |
Lines | _ |
Go to the beginning of the (possibly indented) text |
$ |
Go to the end of the line | |
0 |
Go to the beginning of the line (first column) | |
gg |
Go to the first line in your file | |
G |
Go to the last line in your file | |
Text | { |
Go to the beginning of the paragraph (Separated by an empty line) |
} |
Go to the end of the paragraph | |
( |
Go to the beginning of the sentence | |
) |
Go to the end of the sentence | |
Code | % |
When on a bracket / brace etc, go to the matching bracket |
Almost any movements and other actions can be repeated. Need to move four lines up? Type “4k” (in normal mode, of course). Repetitions work in almost all situations in Vim.
Text Objects
Text objects are extremely useful in managing your … text! We’ve learned about lines, words and paragraphs already, but Vim knows a lot more shortcuts to get around text (or code, of course). Text objects are one major feature to do this.
Text objects can be used in two variants: “Inner” and “outer” mode. For example, the content of a pair of braces would be the “inner” variant, and if you want to include the braces pair, you would use the “outer” variant.
Before we get to some examples, you should note that this stuff only gets really powerful when combining directly with other editing commands. Most of this stuff works together as expected. So, when editing, try to directly use editing commands, instead of resorting to the simple basics (like deleting and then rewriting text). Here are some examples to combine the things we’ve learned above. Almost all editing commands support movements or visual selections as well. So here we go:
Keys | Explanation |
---|---|
dap |
Deletes a paragraph (In text objects, “a” is outer, “i” is inner) |
ci( |
Change contents of a braces pair |
ca[ |
Replace an array subscript with something else |
d3) |
Not a text object, but a movement: Delete three sentences |
3ds |
Delete three sentences, this time using text objects |
cit |
Assuming you’re in HTML between some tags: Change text between opening and closing tags |
There are plugins available to add even more text objects. Python developers would probably love to hear that there is a plugin that turns indentation into text objects - thus you can manage indentation blocks just as well..
Again, there’s a huge number of shortcuts managing text objects. Type :help
text-objects
to find out more.
Registers
Vim has a ton of registers that you can use. There are 26 general-purpose
registers (one for each character). You can yank text into the "a
register
by typing "ay
, for example. To paste from the "a
register again, type
"ap
.
A lot of people don’t know this, but you also have access to the registers
in the ex-mode command line. If you want to search for some text that you
currently have in the register "f
, you can type /
(to get into search
mode), followed by Ctrl+R
, followed by the character f
.
If you want to see what’s currently in your registers, use :reg
.
There are a lot of special-purpose registers as well. For example, the
register "/
contains the last thing that you searched for, and "+
represents the X11 text selection. "*
can be used to interact with the
clipboard. If you yank something into that register, you can paste it in
another application. If you you copied something in another application, you
can read it using that register.
The numerical registers contain things that you’ve yanked the last few times. So go look there if you’ve just overwritten something.
There should be a special mention for the ".
register, as well. It
contains the last thing that you’ve inserted!
Macros
Vim also provides you with a simple way to automate things between learning command patterns and writing full-blown scripts, called macros. Macros are basically a set of commands, executed after one another. If you plan ahead a bit, you can get through a lot of text with quite little effort.
You can get into macro-recording mode by typing q
, followed by a character
denoting the register into which to store the macro. I’m usually just typing
qq
, therefore putting the macro into the "q
register.
Macros work across multiple files as well, so be careful! A very common use case where I’m using macros is if I’m changing something similar in a bunch of files. Let’s make up a story here: I’m refactoring some python code, and moved a function from one module to another. On the way there, the function was also renamed. To simplify the whole affair a bit, assume that the function did indeed have a unique name.
To update all references, I need to add a new import
line, and replace all
calls to the old function to the new one. Here’s what I’d do:
- Open a new vim on the commandline, passing all python files as a
parameter:
vim $(find . -name "*.py")
- Start recording a macro by typing
qq
(as noted above, this puts the macro into the"q
register) - Find the first
import
line, and add my new import above it:/^import
<Enter>
O
import newmodule
<Esc>
- Replace all references to the old name:
:%s/oldmodule.oldname/newmodule.newname/g
<Enter>
- Open the next file from the command line:
:next
<Enter>
- End the macro recording mode by typing
q
again.
Now that I have the macro recorded, I can execute it using the @
command.
This one also uses a register name as a parameter. And we want to do it for
all python files on the command line, which I’m just assuming to be about 20
files, in total. So we repeat the command 20 times. To put it all together,
type 20@q
<Enter>
. If there’s only 19 files, no problem. Macro execution
stops on the first error (such as no more files on the list).
Using external tools
You can filter some lines or the whole file through external commands. This is extremely useful for formatting, sorting, or whatever else you want to do with your file.
Simply calling an external program will print it’s output to your screen,
and when you press any key, the output will disappear. Try :!ls
for
example.
More useful is the ability to read the output from an external program. This
can be very handy for downloading something right into your editor, for
example: :r!curl http://store.nike.com/robots.txt
You can also filter some lines or the whole file. I’m using this mostly for
code formatting and sorting. But you could also pipe out a formula to bc
for calculation, for example… Try some of those: Write 123+999
on a new
line, mark it in visual mode, then type :!bc
followed by <Enter>
. Don’t
worry about the prefix in the command line - this is vim telling itself to
work on the current visual selection.
Vim also has a very limited terminal emulator, reachable by calling :sh
.
However, this breaks for anything more complex than very simple commands.
During `:sh
execution, vim hides itself, and only comes back once you exit
the shell. If you’re using Neovim (and you should!), then you get a
full-blown terminal emulator that runs within a Vim window. It’s also way
more feature-complete, so you can even do an Xzibit and run vim in your vim,
so you can hack while you hack! Just type :terminal
in an empty window,
and enjoy :)
Plugins
These days, you should use a plugin manager to handle this - no more copying stuff all over your .vim directory! I’m using Vundle, which does a pretty decent job. Also, I suggest some minor hackery so you can autoinstall it on a new machine. I’ve written about this before: http://winged.ch/vundle_autoinstall/
Here’s a bunch of plugins that I’m currently using. I’m grouping them together by theme to make sure that I’m not installing two plugins that do essentially the same.
"""""""""""""""""""""""""""""""""""""""""""""""""""""
" Misc helpers "
"""""""""""""""""""""""""""""""""""""""""""""""""""""
Plugin 'The-NERD-tree' " File manager etc
Plugin 'ctrlp.vim' " Open files by fuzzy matching filenames
"""""""""""""""""""""""""""""""""""""""""""""""""""""
" Motion / Text objects / Formatting helpers "
"""""""""""""""""""""""""""""""""""""""""""""""""""""
Plugin 'vim-indent-object' " Indentation text objects, useful for python development
"""""""""""""""""""""""""""""""""""""""""""""""""""""
" Completion / Compilers / syntax checkers "
"""""""""""""""""""""""""""""""""""""""""""""""""""""
Plugin 'scrooloose/syntastic' " Syntax checkers for almost everything
Plugin 'Valloric/YouCompleteMe' " Code completion, supports many languages
Please note that I’m omitting a ton of plugins here, since this article would get way too long if I’d include and explain all of them.
Some of the plugins above should be looked at in more detail.
Vundle
Vundle works by introducing additional commands that can be used in ex mode,
or listed in your .vimrc
file. The Plugin
command above tells it to
use a given plugin (which it automatically installs by checking certain
github repositories). There is also a PluginSearch
and PluginInstall
command. The latter doesn’t automatically update your .vimrc, however. So
don’t forget to do that after installing a plugin, otherwise it won’t be
working anymore when you restart Vim.
CtrlP
This plugin allows to quickly open a file. Once installed, type Ctrl+P
to
open the plugin’s menu. Then just type away until the file you want is
selected. Then press <Enter>
and it will open right away. If you want to
keep the current file open, use <Ctrl+T>
instead, so the new file gets put
into a new tab.
Vim-Indent-Object
As commented, this introduces a new category of text objects, called
indents. Those behave exactly the same as the other text objects. So you can
use yii
to copy the contents of a python function, for example. of yai
to copy the function including it’s definition.
Syntastic
Syntastic introduces support for a ton of external syntax checkers, and is usually triggered just after saving a file. It will display all errors and warnings in a separate window. Please note that for this to work, the external syntax checkers must be installed, of course.
YouCompleteMe
As with Syntastic, YouCompleteMe relies on external tools, depending on the language you’re editing. Read it’s documentation to find out more.
Completion
Completion is another huge topic that could span multiple training sessions in it’s own right. So instead of explaining all of it, I’m just giving an overview here.
Vim knows a lot of different completion modes that can be triggered by Ctrl+X
followed by some more keys. For example, Ctrl+X
, Ctrl-O
will activate
Omni-Completion, which uses a vim function (usually from a plugin) for
completion. This is mostly useful when programming.
Keys | Explanation |
---|---|
Ctrl-X , Ctrl-N |
Local keyword completion |
Ctrl-X , Ctrl-O |
(Programmable) Omnicompletion |
Ctrl-X , Ctrl-F |
Filename completion |
Ctrl-X , Ctrl-S |
Spelling / dictionary completion |
Please note that plugins such as YouCompleteMe will change the behaviour of
completion. Some map completion onto Tab
for example. Please read the
documentation of your plugins!
Training yourself
There are a few things you can do to force yourself to use Vim “the right way”. For example, here’s how you can disable the arrow keys, so you must use HJKL instead (which will make you a lot faster, because you won’t need to move your hand off the home row anymore..):
inoremap <Up> <NOP>
inoremap <Down> <NOP>
inoremap <Left> <NOP>
inoremap <Right> <NOP>
noremap <Up> <NOP>
noremap <Down> <NOP>
noremap <Left> <NOP>
noremap <Right> <NOP>
There are also people who think that Caps Lock is quite useless, and Escape is far away for your left pinky. Those people sometimes have the glorious idea to map Caps Lock to Escape. Unfortunately, you’d need to do this in your operating system’s settings.
Some more not-so-well known shortcuts
Keys | Mode | Explanation |
---|---|---|
Ctrl+A |
Normal | Increment the number under the cursor (Works with hex, decimal, octal, …) |
Ctrl+X |
Normal | Decrement the number under the cursor (Works with hex, decimal, octal, …) |
Ctrl+Z |
Normal | Suspend vim, returns to your shell. Use fg to resume vim. |
Ctrl+O |
Normal | Go to previous position (for example when jumping, searching around etc) |
Ctrl+I |
Normal | Opposite direction of Ctrl+O |
g; |
Normal | Go to previous change. Can be prefixed by a number for repetition :) |
g, |
Normal | Go to next change (opposite of g; ) |
Final words
There is a lot more to Vim than what we’ve just touched here. And I mean A LOT MORE! Vim is probably one of those tools that nobody ever knows everything about. Maybe not even it’s author…
To learn more, it’s often quite useful to just browse around it’s awesome documentation a bit and try to improve your editing skills once in a while. Sometimes you will need to force yourself into a new habit, and thus slowing you down before it’s benefits will show up.
Also, there are quite a few awesome vim tutorials online. Here are some I really liked:
- Damian Conway, “More Instantly Better Vim” - OSCON 2013 (Or as he says himself - “vim in the hands of a true maniac”)
- Bram Moolenar, “7 Habits For Effective Text Editing 2.0” (Google Taslk, 2007)
:wq