Best of Vim Tips David Rayner ([1]zzapper) 15 Years of Vi + 7 years of Vim and still learning 28Jan10 : Last Update [2]Vim Tips Blog (NEW) [3]Vim @ Squidoo [4]ZSH [5]Cygwin [6]Blog [7]VimTools [8]Buy Vim Book Support VIM [9]Submit to Social Websites __BEGIN__ * new items marked, corrected items marked * searching .. /joe/e - cursor set to End of match .. /joe/e+1 - cursor set to End of match plus 1 .. /joe/s-2 - cursor set to Start of match minus 2 .. /joe/+3 - find joe move cursor 3 lines down .. /^joe.*fred.*bill/ - find joe AND fred AND Bill (Joe at start of line) .. /^[A-J]/ - search for lines beginning with one or more A-J .. /begin\_.*end - search over possible multiple lines .. /fred\_s*joe/ - any whitespace including newline .. /fred\|joe - Search for FRED OR JOE .. /.*fred\&.*joe - Search for FRED AND JOE in any ORDER! .. /\/ - search for fred but not alfred or frederick .. /\<\d\d\d\d\> - Search for exactly 4 digit numbers .. /\D\d\d\d\d\D - Search for exactly 4 digit numbers .. /\<\d\{4}\> - same thing .. /\([^0-9]\|^\)%.*% - Search for absence of a digit or beginning of line * finding empty lines .. /^\n\{3} - find 3 empty lines .. /^str.*\nstr - find 2 successive lines starting with str .. /\(^str.*\n\)\{2} - find 2 successive lines starting with str * using rexexp memory in a search >> /\(fred\).*\(joe\).*\2.*\1 * Repeating the Regexp (rather than what the Regexp finds) >> /^\([^,]*,\)\{8} * visual searching :vmap // y/" : search for visually highlighted text :vmap // y/=escape(@", '\\/.*$^~[]') : with spec chars * \zs and \ze regex delimiters :h /\zs /<\zs[^>]*\ze> : search for tag contents, ignoring chevrons * zero-width :h /\@= .. /<\@<=[^>]*>\@= - search for tag contents, ignoring chevrons .. /<\@<=\_[^>]*>\@= - search for tags across possible multiple lines * searching over multiple lines \_ means including newline .. / - search for multiple line comments .. /fred\_s*joe/ - any whitespace including newline .. /bugs\(\_.\)*bunny - bugs followed by bunny anywhere in file .. -h \_ : help * search for declaration of subroutine/function under cursor :nmap gx yiw/^\(sub\function\)\s\+" * multiple file search :bufdo /searchstr/ : use :rewind to recommence search * multiple file search better but cheating :bufdo %s/searchstr/&/gic : say n and then a to stop * How to search for a URL without backslashing ?http://www.vim.org/ : (first) search BACKWARDS!!! clever huh! * Specify what you are NOT searching for (vowels) /\c\v([^aeiou]&\a){4} : search for 4 consecutive consonants /\%>20l\%<30lgoat : Search for goat between lines 20 and 30 /^.\{-}home.\{-}\zshome/e : match only the 2nd occurence in a line of "home" * N* :%s/home.\{-}\zshome/alone : Substitute only the occurrence of home in any line * find str but not on lines containing tongue ^\(.*tongue.*\)\@!.*nose.*$ \v^((tongue)@!.)*nose((tongue)@!.)*$ .*nose.*\&^\%(\%(tongue\)\@!.\)*$ :v/tongue/s/nose/&/gic "---------------------------------------- *substitution .. :%s/fred/joe/igc - general substitute command .. :%s//joe/igc - Substitute what you last searched for .. :%s/~/sue/igc - Substitute your last replacement string .. :%s/\r//g - Delete DOS returns ^M * Is your Text File jumbled onto one line? use following .. :%s/\r/\r/g - Turn DOS returns ^M into real returns .. :%s= *$== - delete end of line blanks .. :%s= \+$== - Same thing .. :%s#\s*\r\?$## - Clean both trailing spaces AND DOS returns .. :%s#\s*\r*$## - same thing * deleting empty lines .. :%s/^\n\{3}// - delete blocks of 3 empty lines .. :%s/^\n\+/\r/ - compressing empty lines .. :%s#<[^>]\+>##g - delete html tags, leave text (non-greedy) .. :%s#<\_.\{-1,}>##g - delete html tags possibly multi-line (non-greedy) .. :%s#.*\(\d\+hours\).*#\1# - Delete all but memorised string (\1) * VIM Power Substitute .. :'a,'bg/fred/s/dick/joe/ -: VERY USEFUL * duplicating columns .. :%s= [^ ]\+$=&&= - duplicate end column .. :%s= \f\+$=&&= - same thing .. :%s= \S\+$=&& - usually the same * memory %s#.*\(tbl_\w\+\).*#\1# : produce a list of all strings tbl_* :s/\(.*\):\(.*\)/\2 : \1/ : reverse fields separated by : :%s/^\(.*\)\n\1$/\1/ : delete duplicate lines * non-greedy matching \{-} :%s/^.\{-}pdf/new.pdf/ : delete to 1st pdf only * use of optional atom \? :%s#\<[zy]\?tbl_[a-z_]\+\>#\L&#gc : lowercase with optional leading characters * over possibly many lines :%s/// : delete possibly multi-line comments :help /\{-} : help non-greedy * substitute using a register :s/fred/a/g : sub "fred" with contents of register "a" :s/fred/asome_texts/g :s/fred/\=@a/g : better alternative as register not displayed * multiple commands on one line :%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/ :%s/a/but/gie|:update|:next : then use @: to repeat * ORing :%s/goat\|cow/sheep/gc : ORing (must break pipe) :%s/\v(.*\n){5}/&\r : insert a blank line every 5 lines * Calling a VIM function :s/__date__/\=strftime("%c")/ : insert datestring * Working with Columns sub any str1 in col3 :%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2: * Swapping first & last column (4 columns) :%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1: * format a mysql query :%s#\\|\\|\\|\<\inner join\>#\r&#g * filter all form elements into paste register :redir @*|sil exec 'g#<\(input\|select\|textarea\|/\=form\)\>#p'|redir END :nmap ,z :redir @*sil exec 'g@<\(input\select\textarea\/\=fo rm\)\>@p'redir END * substitute string in column 30 :%s/^\(.\{30\}\)xx/\1yy/ * decrement numbers by 3 :%s/\d\+/\=(submatch(0)-3)/ * increment numbers by 6 on certain lines only :g/loc\|function/s/\d/\=submatch(0)+6/ * better :%s#txtdev\zs\d#\=submatch(0)+1#g :h /\zs * increment only numbers gg\d\d by 6 (another way) :%s/\(gg\)\@<=\d\+/\=submatch(0)+6/ :h zero-width * rename a string with an incrementing number :let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1 # convert yy to 10,11,12 etc * as above but more precise :let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1 # convert xxyy to xx11,xx12, xx13 * find replacement text, put in memory, then use \zs to simplify substitute :%s/"\([^.]\+\).*\zsxx/\1/ * Pull word under cursor into LHS of a substitute :nmap z :%s#\<=expand("")\># * Pull Visually Highlighted text into LHS of a substitute :vmap z :%s/\<*\>/ * substitute singular or plural :'a,'bs/bucket\(s\)*/bowl\1/gic * all following performing similar task, substitute within substitution * Multiple single character substitution in a portion of line only :%s,\(all/.*\)\@<=/,_,g : replace all / with _ AFTER "all/" * Same thing :s#all/\zs.*#\=substitute(submatch(0), '/', '_', 'g')# * Substitute by splitting line, then re-joining :s#all/#&^M#|s#/#_#g|-j! * Substitute inside substitute :%s/.*/\='cp '.submatch(0).' all/'.substitute(submatch(0),'/','_','g')/ == global command display .. :g/gladiolli/# - display with line numbers (YOU WANT THIS!) .. :g/fred.*joe.*dick/ - display all lines fred,joe & dick .. :g/\/ - display all lines fred but not freddy .. :g/^\s*$/d - delete all blank lines .. :g!/^dd/d - delete lines not containing string .. :v/^dd/d - delete lines not containing string .. :g/joe/,/fred/d - not line based (very powerfull) .. :g/fred/,/joe/j - Join Lines .. :g/-------/.-10,.d - Delete string & 10 previous lines .. :g/{/ ,/}/- s/\n\+/\r/g - Delete empty lines but only between {...} .. :v/\S/d - Delete empty lines (and blank lines ie whitespace) .. :v/./,/./-j - compress empty lines .. :g/^$/,/./-j - compress empty lines .. :g/> :g/^/ if line('.')%2|s/^/zz / * match all lines containing "somestr" between markers a & b * copy after line containing "otherstr" :'a,'bg/somestr/co/otherstr/ : co(py) or mo(ve) * as above but also do a substitution :'a,'bg/str1/s/str1/&&&/|mo/str2/ :%norm jdd : delete every other line * incrementing numbers (type as 5 characters) :.,$g/^\d/exe "norm! \": increment numbers :'a,'bg/\d\+/norm! ^A : increment numbers * storing glob results (note must use APPEND) you need to empty reg a first with qaq. *save results to a register/paste buffer :g/fred/y A : append all lines fred to register a :g/fred/y A | :let @*=@a : put into paste buffer :let @a=''|g/Barratt/y A |:let @*=@a * filter lines to a file (file must already exist) :'a,'bg/^Error/ . w >> errors.txt * duplicate every line in a file wrap a print '' around each duplicate :g/./yank|put|-1s/'/"/g|s/.*/Print '&'/ * replace string with contents of a file, -d deletes the "mark" :g/^MARK$/r tmp.txt | -d * display prettily :g//z#.5 : display with context :g//z#.5|echo "==========" : display beautifully * Combining g// with normal mode commands :g/|/norm 2f|r* : replace 2nd | with a star *send output of previous global command to a new window :nmap :redir @a:g//:redir END:new:put! a *---------------------------------------- * Global combined with substitute (power editing) :'a,'bg/fred/s/joe/susan/gic : can use memory to extend matching :/fred/,/joe/s/fred/joe/gic : non-line based (ultra) :/biz/,/any/g/article/s/wheel/bucket/gic: non-line based * Find fred before beginning search for joe :/fred/;/joe/-2,/sid/+3s/sally/alley/gIC *---------------------------------------- * create a new file for each line of file eg 1.txt,2.txt,3,txt etc :g/^/exe ".w ".line(".").".txt" *---------------------------------------- * chain an external command :.g/^/ exe ".!sed 's/N/X/'" | s/I/Q/ *---------------------------------------- * Operate until string found d/fred/ :delete until fred y/fred/ :yank until fred c/fred/e :change until fred end *---------------------------------------- * Summary of editing repeats . last edit (magic dot) :& last substitute :%& last substitute every line :%&gic last substitute every line confirm g% normal mode repeat last substitute g& last substitute on all lines @@ last recording @: last command-mode command :!! last :! command :~ last substitute :help repeating == Summary of repeated searches .. ; - f, t, F or T .. , - f, t, F or T in opposite direction .. n - last / or ? search .. N - last / or ? search in opposite direction .. == Absolutely essential tips .. * # g* g# - find word under cursor () (forwards/backwards) .. % - match brackets {}[]() .. . - repeat last modification .. @: - repeat last : command (then @@) .. matchit.vim - % now matches tags