Wiki: Vim
Basic Vim Commands Referenceby Oliver; 2014
Introduction

ssh
-ed into a remote server and you're trying to edit a file with one of these GUI text editors, then you have to locally mount the server to edit the file—another headache.
If these two reasons aren't compelling enough to switch to Vim, it's also a good editor in its own right.
The downside is that Vim isn't the easiest thing to learn, and it sometimes seems geared towards those with a love of the technical.
But there is an extensive user manual, a Tips Wiki, and vim.org, which admirably states:
The most useful software is sometimes rendered useless by poor or altogether missing documentation. Vim refuses to succumb to death by underdocumentation.(The manual weighs in at over 250 pages—mission accomplished!) What follows is a collection of miscellaneous Vim commands—so you know what to expect, it's more a reminder to myself than a carefully crafted article.
Vim Modes
Vim has a bunch of modes. In normal mode, you can navigate through your file and do some simple commands. If you type a colon ( : ) in normal mode, you enter command mode (technically called command-line mode, but not to be confused with the unix command line) where you can enter syntactically more complex commands at the prompt. In insert mode you can edit text and in visual mode you can highlight text. Vim visual mode has 3 sub-modes:- regular
- whole line
- block
i | enter insert mode |
I | enter insert mode at beginning of line |
a | enter insert mode one character after the cursor |
A | enter insert mode at end of line |
o | create new line (below cursor), enter insert mode at its beginning |
O | create new line (above cursor), enter insert mode at its beginning |
: | enter command mode |
v | enter visual mode |
V | enter visual line mode |
Ctrl-v | enter visual block mode |
Here's how to get back to normal mode from another mode:
Ctrl-c | normal mode |
Esc | normal mode |
Some people also map jj to Esc (you can see how to do this in the .vimrc included below).
For the remainder of this article, I'll put a colon in front of any command executable from command mode, as it would appear at your Vim prompt.
Saving and Quitting in Vim
In command mode::w | save |
:q | quit |
:wq | save and quit |
:q! | quit without saving |
Navigating Through Your File in Vim
In normal mode:gg | move to top of file |
G | move to bottom of file |
Cntrl-u | move up a chunk |
Cntrl-d | move down a chunk |
Cntrl-o | move to previous position in cursor history (including in different files in the buffer) |
Cntrl-i | move to next position in cursor history (including in different files in the buffer) |
W | jump cursor forward on whitespace |
w | jump cursor forward on special characters |
B | jump cursor backward on whitespace |
b | jump cursor backward on special characters |
e | move to end of current word |
H | move to top of page |
M | move to middle of page |
L | move to bottom of page |
zz | view current line in the middle of the screen |
zt | view current line at the top of the screen |
zb | view current line at the bottom of the screen |
27gg | move to line 27 |
In command mode:
:27 | move to line 27 |
Copying (Yanking), Pasting, Cutting, and Deleting
In normal mode:x | delete character under cursor (and store in default register) |
rx | replace character under cursor with x |
dd | delete line (and store in default register) |
yy | copy or yank line (into default register) |
d | delete (and store in default register) |
y | yank (into default register) |
p | paste (from default register) after cursor |
P | paste (from default register) before cursor |
ddp | swap the order of two rows |
d0 | delete everything from cursor to beginning of line |
d$ | delete everything from cursor to end of line |
dW | delete one word forward |
dB | delete one word back |
yyp | duplicate line |
Many of these are useful in visual mode, too. If you're pasting text into your Vim editor from the outside world, it's sometimes necessary to use the special paste mode:
:set pasteIf you don't set this, Vim can trip up on special characters or mess up your indentation. To turn it off:
:set nopasteSuppose you yank a word (yiw) and then delete a line (dd). Now you can't paste the word you yanked because, to use a Mac analogy, the line has superceded the word in your clipboard: if you you paste (p), you get the line. How do we get around this? Vim is not limited to merely copying one thing but, instead, has multiple registers in which to store information. You can see their contents:
:regIf your last command was delete or yank, whatever you operated on goes into the default register. However, you can always access the other registers by name. For example, yank puts its contents into both the default register and the 0 register. Hence you can always paste what you last yanked with "0p even if, say, you've deleted stuff since then.
Paste the entirety of another file, myfile.txt, into your current document:
:r myfile.txtWrite the output of a system command (e.g., pwd) into your current document:
:r !pwd
Undo and Redo
Undoing, redoing, and repeating the previous command (in normal mode):u | undo |
Cntrl-r | redo |
. | repeat previous command |
Editing Multiple Files in Vim
In Vim you can work on multiple files at once, which means you can copy and paste things from one file to another without ever quitting the editor. In command mode::e /my/file | open up /my/file (in buffer) |
:bp | Jump to next file in buffer |
:bn | Jump to previous file in buffer |
:b1 | go to first file in buffer |
:bd | destroy file in buffer |
:ls | list files in the buffer |
As we noted above, Cntrl-o and Cntrl-i will jump to cursor positions across files. One more interesting command, in normal mode:
gf | Go to file underneath cursor |
Jumping Back to the Command Line Without Quitting Vim
Happily, we can jump back to the command line without quitting Vim (in normal mode):Cntrl-z | pause VIM and return to command line |
To resume Vim:
$ fg
System Commands in Vim
A powerful feature in Vim is the ability to use unix utilities without leaving the editor. System commands are prefixed by the ! symbol. Try typing this into your Vim editor:asdf dasdf asdf asdf fasdf asdf dGo into Visual Block mode and select them. Let's try using unix cut:
:'<,'>!cut -f1 -d" "Just as if we were cutting a file on the command line, we get:
asdf asdf asdfAnother example:
:'<,'>!sort -k5,5This would sort on the 5th column of the selected rows.
One of the coolest system commands to use in vim is grep, which filters lines:
:'<,'>!grep applewould delete all selected lines that don't contain apple. To do the reverse and delete any lines that contain apple:
:'<,'>!grep -v apple
Switching Lowercase Text to Uppercase (and Vice Versa)
To change the case of your text characters, select those characters in visual mode and use:U | convert to all uppercase |
u | convert to all lowercase |
~ | toggle case (uppers to lowers and lowers to uppers) |
Read more.
Finding and Replacing Text in Vim
To find text in Vim, type a slash ( / ) in normal mode. To find findthistext, for example:
/findthistext
To step through each instance, it's:
n | find next instance |
N | find prev instance |
in normal mode. Happily, unix less also shares this syntax for find. In Vim, we can also find characters on a single line:
fx | go to next occurrence of x |
Fx | go to prev occurrence of x |
; | repeat |
In command mode, we can do a global substitution of findtext with replacetext:
:%s/findtext/replacetext/gOnce Vim has found text, it will highlight it. To turn off highlighting:
:nohA familiar task when writing HTML is replacing the reserved character > with its code >. We can do this easily is Vim:
:%s/\>/>/gYet this would replace all such > characters in our file. Since this would mess up our HTML tags, it's more likely we want to do this in a local region, say lines 10 to 20:
:10,20 s/\>/>/gAnother way to do this is by calling a system command like sed:
:'<,'>!sed s'/>/\>\;/g'
Example: Using Awk Inside Vim to Create HTML List Tags
As we've seen, we can use system tools within Vim and this includes awk. Let's say we have the following list to which we want to add HTML list tags, <li> </li>:tiny small large hugeGo into Visual Block mode and select these words. Now try:
:'<,'>!awk '{print "<li>"$0"</li>"}'This produces:
<li>tiny</li> <li>small</li> <li>large</li> <li>huge</li>
Manipulating Text
Sometimes you want to add or remove tabs from the beginning of a bunch of rows. This works in normal mode and especially well in visual mode:shift > | insert tab |
shift < | remove tab |
Another nice ability is putting two rows on the same line:
J | join next line onto current line |
Verb Preposition Object in Vim
The Verb Preposition Object paradigm is one of the most powerful Vim features. The basic idea is that in normal mode you enter three letters, which represent an action, the scope of that action, and the object which that action acts upon. It's best illustrated by example:Action | Preposition | Object | Explanation |
d | i | w | delete (in) word |
c | i | w | cut word |
y | i | w | yank word |
d | i | { | delete everything in { } |
d | i | t | delete everything in an HTML tag |
d | a | [ | delete everything in and including [ ] |
d | t | " | delete everything to next occurrence of " |
y | T | ( | yank everything to prev occurrence of ( |
You can mix and match these as you like. For example, if we had:
help="Print line number at the beginning of each line [default]"Then entering di" anywhere inside the quotation marks produces:
help=""
Writing to Multiple Lines Simultaneously
In Vim you can add characters to multiple lines simultaneously. This is useful if, say, you want to comment out multiple lines. To use this feature, first enter visual block mode and select the lines you want to edit. For example, here I'm selecting lines 2 through 4:
Now press I to enter text in front of the cursor or A to enter text after the cursor. Here, I'll use I to enter a pound sign and a space in the front:

To apply this to all lines, hit Esc Esc:

And we're done! Note if you wanted to write something at the end of every line, the recipe would be: enter visual block mode; scroll up or down to select the lines you want; type $; type A; enter your text; type Esc Esc.
Hat tip: Albert
Making Vim Macros
If we have to repeat the same sequence of commands frequently, it gets tiresome. You can automate this in your current Vim session using a macro. To use a macro, type q followed by any character in normal mode. Then write your commands. When you're finished, return to normal mode and press q again. To elicit your macro, type @ followed by the character you choose.Let's see an example. Since I'm writing HTML code, a recurring task is putting things in <i> tags to make them italic. This is a pain to do by hand, so let's automate it in a macro I'll call @i. Here's the Vim, step by step:
editor command explanation someword qi start recording macro in @i someword b jump to start of word someword i change to insert mode <i>someword <i> enter text in insert mode <i>someword Esc return to normal mode <i>someword e go to end of word <i>someword a enter insert mode <i>someword</i> </i> enter text in insert mode <i>someword</i> Esc return to normal mode <i>someword</i> q stop recording macro
Now anytime our cursor is in the middle of a word, we need only press @i in normal mode and italic tags will appear around it. Cool, eh? However, this is only for the here and now. What if we want to make sure this macro is saved for all time or use it on other computers? If that's the case, we can put it in our .vimrc (which we'll discuss below):
let @i='bi<i>^[ea</i>^['How do we get this without retyping everything already stored in our macro? We can see our macros by entering:
:regNote: you need to be extra careful copying from this list—say with ⌘c on Macintosh—because of how the escape character is represented. To write the escape character, we have to use Control-v Esc. This produces ^[ which is NOT THE SAME as simply typing a ^ character followed by a [ character! The ^[ here is one character, not two, and Vim will color it to remind you of this fact. However, if you just copy it, you'll end up with the two characters, which is not the escape character.
pathogen.vim
pathogen.vim makes it easy to install Vim plugins. For details, go here: As described in the link, download it like this:$ mkdir -p ~/.vim/autoload ~/.vim/bundle $ curl -Sso ~/.vim/autoload/pathogen.vim \ https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim
Useful Vim Plugins
With pathogen installed, we can install some useful Vim plugins. tcomment allows one to comment out multiple lines at once:$ cd ~/.vim/bundle/ $ git clone https://github.com/tomtom/tcomment_vim.gitnerdtree pops up a directory menu on your left sidebar:
$ cd ~/.vim/bundle $ git clone https://github.com/scrooloose/nerdtree.git
Accessing a Website's HTML source code with Vim
A neat Vim trick is the ability to access the HTML source code of a website from the terminal:$ vim https://en.wikipedia.org/wiki/Main_PageHat tip: Albert
Use Vim on the Web in Chrome with Wasavi
Wasavi is a "vi editor for any web page" plugin for the Chrome browser, which allows you to do stuff like use Vim inside Gmail.Hat tip: Albert
Sample .vimrc
Here's a sample .vimrc configuration file. If you put this in your home directory, Vim will add its rules:" use plugins, such as tComment " execute pathogen#infect() syntax on filetype plugin indent on " set nerd tree key bindings nmap \e :NERDTreeToggle<CR> "Split navigation nmap gh <C-w>h nmap gj <C-w>j nmap gk <C-w>k nmap gl <C-w>l " number lines set nu " allow color highlighting syntax enable " good color scheme for white background colorscheme delek " colorscheme slate " make sure arrow keys work on mac " (http://vim.wikia.com/wiki/Fix_arrow_keys_that_display_A_B_C_D_on_remote_shell) " this was messing things up so comment out " set term=cons25 " use this instead: " (http://vim.wikia.com/wiki/Fix_broken_arrow_key_navigation_in_insert_mode) set term=builtin_ansi "reselect after indenting vnoremap < <gv vnoremap > >gv "Paste Toggle " i.e., switch between paste-insert mode and ordinary insert-mode using \1 set pastetoggle=<Leader>1 " map jj to escape key inoremap jj <esc> " set macro @s to add HTML tags around a word let @a='bi<a href="">^[ea</a>^[' let @b='bi<b>^[ea</b>^[' let @c='bi<code>^[ea</code>^[' let @i='bi<i>^[ea</i>^[' let @s='bi<samp>^[ea</samp>^[' let @u='bi<u>^[ea</u>^['Note: comments are prefixed with a quotation mark ( " ).