Best Vim Tips
From Vim Tips Wiki
Tip 305 Previous Next created 2002 · complexity intermediate · author zzapper · version 7.0
Here is a necessarily cryptic list of the Best Vim Tips. There is an updated version and a printer friendly version.
[edit] Basic use
<Esc> is the escape key vimtutor : starts vim editing a copy of a tutorial file -- very good. i : insert mode (so you can type) <Esc> : so you can navigate and edit commands (stop typing) (stop selecting) h j k l : move cursor A : append at end of line (you can't navigate past the next to last character) u : undo last command x : delete character under cursor dd : delete line (also puts it into the default register) p : paste the default register :wq : write and quit :w filename : Save a copy of the file you are editing as filename :q! : quit without saving :help : display help <Tab> : use tab completion to check what your command is
[edit] Still basic
COPY PASTE (for CUT use d as described above) v : visual mode -- use to select text with your mouse y : use to yank (copy) what was selected above <Esc> : esc gets you back to the main mode l w e $ : these are special movements, letter, word, end of word, end of line Modes: normal, insert and visual, there are others too <Esc> (C-[) 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 ce : change to end of word (a complete change command) C : change to end of line (same as c$)
[edit] Really useful
www.vim.org : Visit frequently
comp.editors : Vim dominated newsgroup
* # g* g# : find word under cursor (forwards/backwards)
% : match brackets {}[]()
matchit.vim : % now matches tags <tr><td><script> etc
<C-N> <C-P> : word completion in insert mode
<C-X><C-L> : Line complete SUPER USEFUL
/<C-R><C-W> : Pull <cword> 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<C-D> : type control-D and get a list all help topics containing slash
(plus use TAB for Help completion)
[edit] Make it easy to update/reload vimrc
:nmap <Leader>s :source $MYVIMRC
:nmap <Leader>v :e $MYVIMRC
(<Leader> is \ by default, so those commands can be invoked by doing \v and \s)
[edit] Visual Mode Mappings
:vmap sb "zdi<b><C-R>z</b><Esc> : wrap <b></b> around visually selected text :vmap st "zdi<?= <C-R>z ?><Esc> : wrap <?= ?> around visually selected text
[edit] Exploring
:Ex : file explorer note capital Ex \be : builtin buffer explorer :ls : list of buffers(eg following) :cd .. : move to parent directory
[edit] Great
guu : lowercase line gUU : uppercase line ~ : invert case (upper->lower; lower->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)
If you use Ctrl-V for paste, you will probably need to unmap CTRL-A first.
[edit] Easter Eggs
- :help 42
- :help holy-grail
- :help!
- :help map-modes (see comment below the table about :nunmap)
- :help UserGettingBored
- :Ni!
[edit] Markers and moving about
'. : jump to last modification line (SUPER)
`. : jump to exact spot in last modification line
<C-O> : retrace your movements in file (old)
<C-I> : retrace your movements in file (new)
:ju(mps) : list of your movements {{help|jump-motions}}
:history : list of all your commands
[edit] Abbreviations and maps
:map <F7> :'a,'bw file " Write the lines from mark a to mark b to 'file' :map <F8> :.w file<CR> " Write the current line to 'file' :map <F9> :r file " Read text from 'file' and insert it below the current line :map <F10> :w<CR>:!php %<CR> " Write the file and run it through php :ab php " list abbreviations beginning with php :map \ " list maps beginning with \
[edit] For use in maps
<CR> : carriage Return for maps <Esc> : Escape <Leader> : normally \ <Bar> : | pipe
[edit] List registers
:reg : display contents of all registers "1p : paste from register 1
[edit] Execute command from buffer contents
"ayy@a : execute the Vim command in the current line yy@" : same
[edit] Get output from shell commands
The following uses external programs – sort is just an example (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 : grepping in content :20,25 !rot13 : rot13 lines 20 to 25 :r!date : same thing (use date /T on Windows) " Sorting with external sort :%!sort -u : use an external program to filter content :'a,'b!sort -u : use an external program to filter content !1} sort -u : sorts paragraph (note normal mode!) :g/^$/;,/^$/-1!sort : sort each block (note the crucial ;) " Using !!command in normal mode will automatically translate to :.!command " This will send the current line to the command, and replace the current line " With command's result !!date : Replaces current line with date !!which 'command': Replace current line with the absolute path to 'command' !!tr -d abcd : Delete a,b,c,d 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. (Note " that this is equivalent to :'<,'>!command). For example, after selecting multiple lines " with visualmode: !sort : Filters the lines through the sort program !grep word : delete all lines not containing 'word'
[edit] Multiple Files Management
: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)
[edit] Recording (BEST TIP of ALL)
qq : record keystrokes to register q your commands q : quit recording @q : execute commands again @@ : repeat # editing a register/recording "qp <you can now see register contents, edit as required> "add @a :%normal @q #execute the macro recorded in register q on all lines of the current file. #or, with a visually selected set of lines: :normal @q
[edit] vimrc essentials
:set incsearch : jumps to search word as you type (annoying but excellent) :set wildignore=*.o,*.obj,*.bak,*.exe :set shiftwidth=3 :set syntax on
[edit] 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 <silent> <C-F6> :let old_reg=@"<CR>:let @"=substitute(expand("%:p"), "/", "\\", "g")<CR>:silent!!cmd /cstart <C-R><C-R>"<CR><CR>:let @"=old_reg<CR>
You can also use Windows rundll32.exe for some options:
" vmap <silent> <C-F5> :<C-U>let old_reg=@"<CR>gvy:silent!!start rundll32.exe url.dll,FileProtocolHandler <C-R><C-R>"<CR><CR>:let @"=old_reg<CR>
Or, for example, you can launch Internet Explorer directly:
:nmap <Leader>f :update<CR>:silent !start c:\progra~1\intern~1\iexplore.exe file://%:p<CR> :nmap <Leader>i :update<CR>:!start c:\progra~1\intern~1\iexplore.exe <cWORD><CR>
[edit] FTP from Vim
cmap <Leader>r :Nread ftp://209.51.134.122/public_html/index.html cmap <Leader>w :Nwrite ftp://209.51.134.122/public_html/index.html gvim ftp://209.51.134.122/public_html/index.html : For ascii file transfers add the following line to your .vimrc let g:netrw_ftpmode="ascii"
[edit] Appending to registers (use CAPITAL)
# yank 5 lines into "a" then add a further 5 "a5yy 10j "A5yy [I : show lines matching word under cursor <cword>
[edit] Conventional shifting
:'a,'b>> # visual shifting (builtin-repeat) :vnoremap < <gv :vnoremap > >gv
[edit] Searching
/^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
[edit] Substitution
:%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/<c-r>a/g : substitute "fred" with contents of register "a"
:%s/^\(.*\)\n\1/\1$/ : delete duplicate lines
:help /\{-}
# multiple commands
:%s/\f\+\.gif\>/\r&\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.
:%s/\%x01/^/g
[edit] Global command
:g/^\s*$/d : delete all blank lines :g!/^dd/d : delete lines not containing string :v/^dd/d : delete lines not containing string :g/fred/,/joe/d : not line based :v/./.,/./-1join : compress empty lines :'a,'b g/^Error/ . w >> errors.txt :g/cmap\|form/p : ORing
[edit] Paste register *
:redir @* : redirect commands to paste :redir END "*yy : yank to paste "*p : insert paste buffer
[edit] Formatting text
gq<CR> gqap (a is motion p paragraph (visual mode))
[edit] Operate command over multiple files
:argdo %s/foo/bar/ :bufdo %s/foo/bar/ :windo %s/foo/bar/ :tabdo %s/foo/bar/
[edit] 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" *) &
[edit] Preview in web browser
#add this to your .vimrc: command Preview :!firefox %<CR> #if you are using windows, you will need to adjust your PATH to include the path to your browser.
[edit] Comments
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.
[edit] 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
[edit] 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 <F11> "qyy:let @q=@q."zzz"
Options
:verbose set history : show value of history, and where set
Run file through an external program (eg php)
map <F9> :w<CR>:!php %<CR>
Inserting Carriage Returns (TODO replace with \r)
:%s/nubian/<C-V><C-M>&/g : that's what you type :%s/nubian/<C-Q><C-M>&/g : for Win32 :%s/nubian/^M&/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 & pasting into text <c-r>: Retrieving last Search Command for copy & pasting into text <c-r>/
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
<C-X><C-F> :insert name of a file in current directory
Help for help
:h visual<C-D><Tab> : obtain list of all visual help topics
: Then use tab to step through them
:h ctrl<C-D> : 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 <C-R> in insert mode
:h c_CTRL-R : help for say <C-R> in command mode
:h v_CTRL-V : visual mode
[edit] 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).
[edit] If you want to delete multiple adjacent duplicate lines
:%s/^\(.*\)\n\(\1\n\)*/\1\r/
[edit] More, unformatted tips
TODO Might delete some of these if covered in other tips.
Instead of this:
:map <F12> :set number!<CR>
try this:
map <F12> :set number!<Bar>set number?<CR>
and possibly these:
map <F11> :set hls!<Bar>set hls?<CR> map <F10> :set paste!<Bar>set paste?<CR> map <F9> :set wrap!<Bar>set wrap?<CR>
to easily change (and display) the current state.
Delete any line that contains DTE unless that line also contains STX or ETX:
:g/^/call setreg(0,getline(".")) | if (@0=~#"DTE") && !((@0=~#"STX") || (@0=~#"ETX")) | d | endif
Each line is searched for the strings DTE, STX, ETX and according to the given rule only the lines matching the specified condition are deleted. If you replace =~# with =~ then the search will be case insensitive. The vertical bar separates the commands to be entered all in one line First copying the lines in a register and then examining the register avoids calling the getline() function several times. See :help eval.
If you do not want to remove Windows key mappings, keep the line
noremap <C-kPlus> <C-A>
in your vimrc. Then you can use Ctrl-NumPad+ to increment numbers as others do with Ctrl-A.
Another very useful mapping:
noremap <C-J> gj noremap <C-K> 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 <Up> gk noremap <Down> 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
:%s/FILE/\=expand("%:t")
The mappings to wrap visual selections in text clobbers a buffer. I use:
vmap s( <Esc>`>a)<Esc>`<i(<Esc> : wrap a visual selection in ()
