Best Vim Tips Best Vim Tips

Basic use

<Esc> is the escape key or use <ctrl>[  sometimes written as  <C-[>

vimtutor    : starts vim editing a copy of a tutorial file -- very good.
i           : insert mode. Next keys typed are inserted into the file.
<Esc>       : Escape from insert mode so you can navigate and use edit commands (stop selecting)
h j k l     : move cursor ( h: ←  j: ↓  k: ↑  l: → )
A           : Append at end of line
o           : Insert at new line below
u           : undo last command, again and again
x           : delete character under cursor
dw          : delete everything right from the cursor to the start of next word (and put it into the default register)
dd          : delete line (and put it into the default register)
p           : paste the default register

/myname     : search forward for myname

:wq         : write and quit
😡          : write and quit
:w filename : write a copy of the file you are editing as filename
:q!         : quit without saving even if changes were made!
:help       : display help
<Tab>       : use tab completion to scroll through commands that start with what you typed

Still basic

COPY PASTE  (for CUTting lines use dd as described above)
v           : visual mode -- use to select text with cursor movement or mouse
y           : use to yank (copy) what was selected
       : esc gets you back to the main mode

^ w e $     : bigger movements: beginning of line, word, end of word, end of line

 normal, insert and visual, there are others too
     takes you back to normal

Enter a number before a command to repeat it, examples:
   10w      : skip forward 10 words
   10dd     : delete 10 lines

Commands are case sensitive:
   c        : starts a change command
   C        : change to end of line (same as c$)
   ce       : change to end of word (a complete change command)

Really useful   : Visit frequently
comp.editors  : Vim dominated newsgroup
* # g* g#     : find word under cursor (forwards/backwards)
%             : match brackets {}[]()
matchit.vim   : % now matches tags <tr><td> etc
    : word completion in insert mode
    : Line complete SUPER USEFUL
/   : Pull  onto search/command line
:set ignorecase : you nearly always want this
:set smartcase  : case-sensitive if search contains an uppercase character
:syntax on    : colour syntax in Perl,HTML,PHP etc
:h slash : type control-D and get a list all help topics containing slash
    (plus use TAB for Help completion)

Make it easy to update/reload vimrc

" source $MYVIMRC reloads the saved $MYVIMRC
:nmap s :source $MYVIMRC

" opens $MYVIMRC for editing, or use :tabedit $MYVIMRC
:nmap v :e $MYVIMRC

"  is \ by default, so those commands can be invoked by doing \v and \s

Visual mode mappings

:vmap sb "zdi<b>z</b> : wrap <b></b> around visually selected text
:vmap st "zdi&lt;?= z ?&gt; : wrap  around visually selected text


:Ex     : file explorer note capital Ex
\be     : show buffer explorer (requires plugin)
:ls     : list of buffers(eg following)
:cd ..  : move to parent directory


guu     : lowercase line
gUU     : uppercase line
~       : invert case (upper-&gt;lower; lower-&gt;upper) of current character
gf      : open file name under cursor (SUPER)
ga      : display hex, ascii value of character under cursor
g8      : display hex value of utf-8 character under cursor
ggg?G   : rot13 whole file
xp      : swap next two characters around
CTRL-A,CTRL-X : increment, decrement next number on same line as the cursor
CTRL-R=5*5    : insert 25 into text
=             : (re)indent the text on the current line or on the area selected (SUPER)
=%            : (re)indent the current braces { ... }
G=gg          : auto (re)indent entire document

If you use Ctrl-V for paste, you will probably need to unmap CTRL-A first.

Easter eggs

:help 42
:help holy-grail
:help map-modes (see comment below the table about :nunmap)
:help UserGettingBored
:help spoon
:help showmatch (read the note)
:help bar

Markers and moving about

'.       : jump to last modification line (SUPER)
`.       : jump to exact spot in last modification line
    : retrace your movements in file (backward)
    : retrace your movements in file (forward)
:ju(mps) : list of your movements {{help|jump-motions}}
:history : list of all your commands

Abbreviations and maps

:map   :'a,'bw file            " Write the lines from mark a to mark b to 'file'
:map   :.w file            " Write the current line to 'file'
:map   :r file                 " Read text from 'file' and insert it below the current line
:map  :w:!php %       " Write the file and run it through php
:ab php                            " list abbreviations beginning with php
:map \                             " list maps beginning with \

For use in maps

     : carriage Return for maps
    : Escape
 : normally \  change with :let mapleader = ","
    : | pipe

List registers

:reg     : display contents of all registers
"1p      : paste from register 1
Execute command from buffer contents
"ayy@a   : execute the Vim command in the current line
yy@"     : same

Get output from shell commands
These use external programs – ls, grep, date, sort, … (see :help :sort to learn how to use Vim's built-in sort).

:r!ls                 : reads in output of ls (use dir on Windows)
:r !grep "^ebay" file.txt  : read output of grep
:20,25 !rot13        : rot13 lines 20 to 25
:r!date              : insert date (use  date /T on Windows)
:.!sh                : execute contents of current line in buffer and capture the output

 Sorting with external sort
:%!sort -u           : contents of the current file is sorted and only unique lines are kept
:'v,'w!sort          : sort from line marked v thru lines marked w
:g/^$/;,/^$/-1!sort  : sort each block (note the crucial 😉

!1} sort             : sorts paragraph; this is issued from normal mode!)

 Entering !! in normal mode is translated to  :.!
 Appending a command sends the current line to the command replacing it with command's result
!!date              : Replace current line with date
!!which command     : Replace current line with the absolute path to command
!!tr -d AEIO        : translate current line deleting As, Es, Is, and Os from the current line

 You can also use ! on a visual selection. Select an area with one of the visualmode
 commands, and then type !command to pipe the whole selection through command.

This is equivalent to :'!command.
For example, after selecting multiple lines with visualmode:

!sort              : sort selected lines
!grep word         : keep only lines containing 'word' in the selected range.

Multiple files

:wn           : write file and move to next (SUPER)
:bd           : remove file from buffer list (SUPER)
:sav php.html : Save current file as php.html and "move" to php.html
:sp fred.txt  : open fred.txt into a split
:e!           : return to unmodified file
:w /some/path/%:r   : save file in another directory, but with the same name
:e #          : edit alternative file
:args         : display argument list
:n            : next file in argument list
:prev         : previous file in argument list
:rew          : rewind to first file in argument list
:ls           : display buffer list
:bn           : next buffer
:bp           : previous buffer
:brew         : rewind to first buffer in buffer list
:tabe         : open new tab page (Ctrl-PgUp, Ctrl-PgDown for next/previous tab)
:tabm n       : move tab to position n (0=leftmost position)


qa            : record keystrokes to register a
your commands
q             : quit recording
@a            : execute commands again
@@            : repeat
# editing a register/recording

:%normal @a #execute the macro recorded in register a on all lines of the current file.
#or, with a visually selected set of lines:
:normal @a

vimrc essentials

:set incsearch : jumps to search word as you type (annoying but excellent)
:set wildignore=*.o,*.obj,*.bak,*.exe
:syntax on : display syntactical elements by color based on filetype ( extension )

Launching programs under Windows
There are a number of options to run applications on the Windows platform.

This causes Windows to launch the program associated with the file extension. It also restores the paste buffer to its original value:

" This command will execute the file, for example, if this is an
" HTML file, it will run:
"     start c:\absolute\filename.html
nnoremap   :let old_reg=@":let @"=substitute(expand("%:p"), "/", "\\", "g"):silent!!cmd /cstart ":let @"=old_reg
You can also use Windows rundll32.exe for some options:

" vmap   :let old_reg=@"gvy:silent!!start rundll32.exe url.dll,FileProtocolHandler ":let @"=old_reg

Or, for example, you can launch Internet Explorer directly:

:nmap f :update:silent !start c:\progra~1\intern~1\iexplore.exe file://%:p
:nmap i :update:!start c:\progra~1\intern~1\iexplore.exe 
FTP from Vim
cmap r :Nread
cmap w :Nwrite
: For ascii file transfers add the following line to your .vimrc
let g:netrw_ftpmode="ascii"
Appending to registers
# yank 5 lines into "a" then add a further 5
[I : show lines matching word under cursor 
Conventional shifting
# visual shifting (builtin-repeat)
:vnoremap &lt;  &gt;gv
/^fred.*joe.*bill  : line beginning with fred, followed by joe then bill
/^[A-J]            : line beginning A-J
/^[A-J][a-z]\+\s   : line beginning A-J then one or more lowercase characters then space or tab
/fred\_.\{-}joe    : fred then anything then joe (over multiple lines)
/fred\_s\{-}joe    : fred then any whitespace (including newlines) then joe
/fred\|joe         : fred OR joe
:%s/fred/joe/igc           : general substitute command
:%s/\r//g                  : delete DOS Carriage Returns (^M)
:'a,'bg/fred/s/dick/joe/gc : VERY USEFUL
:s/\(.*\):\(.*\)/\2 : \1/  : reverse fields separated by :
# non-greedy matching \{-}
:%s/^.\{-}pdf/new.pdf/     : to first pdf)
:s/fred/a/g           : substitute "fred" with contents of register "a"
:%s/^\(.*\)\n\1/\1$/       : delete duplicate lines
:help /\{-}
# multiple commands
:%s/\f\+\.gif\&gt;/\r&amp;\r/g | v/\.gif$/d | %s/gif/jpg/
:%s/suck\|buck/loopy/gc       : ORing
:s/__date__/\=strftime("%c")/ : insert datestring

Replace FIX delimiter for a 'caret':
'01' is the hex for the FIX protocol delimiter. You can move your cursor over a character and press 'ga' to see a character's hex value.

Global command
:g/one\|two/     : list lines containing "one" or "two"
:g/^\s*$/d       : delete all blank lines
:g/green/d       : delete all lines containing "green"
:v/green/d       : delete all lines not containing "green"
:g/one/,/two/d   : not line based
:v/./.,/./-1join : compress empty lines
Between lines with marks a and b (inclusive), append each line starting with "Error" to a file:

:'a,'b g/^Error/ .w &gt;&gt; errors.txt

Delete all lines containing "green" but not "red" or "pink". Command :g/^/ matches every line; the current line is copied into variable x; if any part of x matches (case sensitive) "green" and not "red" and not "pink", the line is deleted. Replace # with ? for case insensitive.

:g/^/let x=getline('.') | if x=~#'green' &amp;&amp; x!~#'red' &amp;&amp; x!~#'pink' | d | endif
Paste register *
:redir @* : redirect commands to paste
:redir END
"*yy      : yank to paste
"*p       : insert paste buffer
Formatting text
gqap (a is motion p paragraph (visual mode))
Operate command over multiple files
:argdo %s/foo/bar/
:bufdo %s/foo/bar/
:windo %s/foo/bar/
:tabdo %s/foo/bar/

Command line tricks

gvim -h
ls | gvim -   : edit a PIPE!
# vg.ksh (shell script)
# vi all files in directory containing keyword $1 and jump to $1
gvim.exe -c "/$1" $(grep -isl "$1" *) &amp;

Preview in web browser

#add this to your .vimrc:
command Preview :!firefox %
#if you are using windows, you will need to adjust your PATH to include the path to your browser.

The Buffer Explorer scripts mentioned above (\be \bs) rely on the popular script bufexplorer.vim.

Have recently started to appreciate taglist.vim (the most popular Vim script) it really comes into it's own with very long programs containting lots of subroutines/functions as it shows which function/sub you're in etc script#273.

Vim traps
In regular expressions you must backslash + (match 1 or more).

/fred\+/ : matches fred/freddy but not free
\v (very magic) reduces backslashing

/codes\(\n\|\s\)*where : normal regexp
/\vcodes(\n|\s)*where  : very magic

More tips
Pulling objects onto command/search line (SUPER)

CTRL-R CTRL-W   : pull word under the cursor into a command line or search
CTRL-R CTRL-A   : pull whole word including punctuation
CTRL-R -        : pull small register
CTRL-R [0-9a-z] : pull named registers
CTRL-R %        : pull file name (also #)
Manipulating registers

map  "qyy:let @q=@q."zzz"

:verbose set history : show value of history, and where set
Run file through an external program (eg php)

map  :w:!php %
Inserting Carriage Returns (TODO replace with \r)

:%s/nubian/&amp;/g : that's what you type
:%s/nubian/&amp;/g : for Win32
:%s/nubian/^M&amp;/g         : what you'll see where ^M is ONE character
TODO move following to other CTRL-R tips

Retrieving last command line command for copy &amp; pasting into text
Retrieving last Search Command for copy &amp; pasting into text
Searching over multiple lines: \_ includes newline

/<!--\_p\{-}-->    : search for multiple line comments
/fred\_s*joe/i     : any whitespace including newline
/bugs\_.*bunny : bugs followed by bunny anywhere in file
:h \_              : help

More completions

 :insert name of a file in current directory
Help for help

:h visual : obtain list of all visual help topics
                    : Then use tab to step through them
:h ctrl : list help of all control keys
:h :r        : help for :ex command
:h CTRL-R    : normal mode
:h \r        : what's \r in a regexp
:h i_CTRL-R  : help for say  in insert mode
:h c_CTRL-R  : help for say  in command mode
:h v_CTRL-V  : visual mode
:h 'ai       : help on setting option 'autoindent'
To number the lines in the file
Try one of these

:%! nl -ba
:%!cat -n

To simply display how many lines are in the current buffer, type Ctrl-g (or g then Ctrl-g for more information).

If you want to delete multiple adjacent duplicate lines


More, unformatted tips
TODO Might delete some of these if covered in other tips.

Instead of this:

:map  :set number!

try this:

map  :set number!set number?

and possibly these:

map  :set hls!set hls?
map  :set paste!set paste?
map   :set wrap!set wrap?

to easily change (and display) the current state.

If you do not want to remove Windows key mappings, keep the line

in your vimrc. Then you can use Ctrl-NumPad+ to increment numbers as others do with Ctrl-A.

Another very useful mapping:

noremap  gj
noremap  gk

That's really useful when dealing with long lines. It lets you use Control-J and Control-K to move up and down screen lines instead of buffer lines with j and k. Control-J isn't really mapped to anything by default, it's like hitting enter, but Control-K is something to do with digraphs. However, noremap won't remove this ability in insert mode.

Alternatively, you could use:

noremap  gk
noremap  gj

which would map the arrow keys to screen line movement instead of buffer line movement.

To substitute any word (say FILE) by actual filename you can use


The mappings to wrap visual selections in text clobbers a buffer. I use:

vmap s( `&gt;a)`&lt;i( : wrap a visual selection in ()

What was the point of changing into and into ? The capitalized form is what's used in Vim's help, and it's what should be used here. (Spiiph 03:34, December 6, 2009 (UTC))

unfixed it. sorry. (perhaps this would have been better been placed in the discussion
Thanks for working on the tip. I might join in later. We put comments in plain view in the "Comments" section (so I removed the html comment) and we avoid the talk page (see the discussion guidelines for a little more). In due course we will delete these temporary comments, and what is on the talk page.
It's hard to know what to do with this tip. I think it should pretty well all be kept, but we should resist the temptation to expand it much (some better explanations are good). I'll think about how we might provide links to tips that expand some points, for example Tutorial. JohnBeckett 04:25, December 6, 2009 (UTC)
Commands are case sensitive:

  c        : starts a change command
  C        : change to end of line (same as c$)
  ce       : change to end of word (a complete change command)

Does ce belong as an example of case sensitive command? Would better additional entry be

  a        : append after cursor
  A        : Append at end of line

DG12 13:48, December 6, 2009 (UTC)

Help for help

Is it me or does this section have a mix of syntax for control characters? DG12 13:51, December 6, 2009 (UTC)

My thoughts on comments by DG12 above and on my talk:

By "all be kept" above, I mean that the content is probably all good and should not be removed (although there's a lot of it, and when I take some time to look through it again I might change my mind).
Re the format of the tip: The current plain text with just a ':' separating command and text is a bit confusing in places, but the simplicity rather suits Vim. I have used cleartable in a couple of tips, and I might try it here. See VimTip605 for an example. Wikitable is also available, but it's rather overwhelming; see VimTip1611 for an example.
Re the style of the tip: The quirky comments are often not directly helpful but they worked well for me when I first read this tip (at several years ago. For example ":set ignorecase : you nearly always want this" alerts readers that they should find out what the command means and consider using it. If every point were clarified, the tip would be far too long and hard to read. Currently the tip is useful because it provides a subjective overview of what people should look for in Vim.
Re the case sensitive point above: While a/A is a good example, it's not needed as an additional example. I think the ce is to show a complete change command. It might be a good idea to replace the c/C/ce with a/A which makes the point. Actually, even better might be j/J because the two actions are totally different.
The "Help for help" section is perhaps confusing, but it is exactly correct because it shows what a person should type. Like many of the items, it could be improved while resisting the tempation to add too many words.
Finally thanks for drawing attention to this page because the tip does need cleaning, and discussion and work will help. JohnBeckett 01:03, December 7, 2009 (UTC)

re Help for help: I was refering to:
:h ctrl : list help of all control keys
:h CTRL-R    : normal mode

or maybe I am confused? (Be nice!)

I also think some people know the info so well what is unclear to someone reading the tip may not seem awkward at all.

re case sensitive example: I choose a/A because many (well some) of the uppercase form of the command are like BIG versions of the lowercase version w/W b/B h/H i/I ...
re "quirky" comments: may mean something to look into but without a link its not much help.
Then there is the length of this document which makes scrolling difficult!
DG12 01:58, December 7, 2009 (UTC)

It is impossible to learn everything about Vim in a short period. This tip is definitely quirky and subjective, however, many people (long before this wiki was created) have found the tip to be very helpful as a source of ideas rather than as a detailed manual. Perhaps the lead should make that clear, although it will be clear after reading for a minute or two. Yes, we should add links. The "help for help" should link to VimTip882 although that tip needs to be fixed! When I first read this page, I did not understand it either, but I referred to it many times while learning Vim.
The "help for help" stuff is correct, although unclear. The ":h ctrl" item is saying to type :h ctrl then press Ctrl-D. The ":h CTRL-R" item is saying that the page of help will show you what Ctrl-R does in normal mode, whereas ":h i_CTRL-R" shows what Ctrl-R does in insert mode, etc. That should be explained at 882. JohnBeckett 04:18, December 7, 2009 (UTC)


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s