&& The 'Vi Improved' Text Editor --------------------------------: Quote: "annoying but excellent" (David Rayner) INTRODUCTION Vim is a free, open-source text editor which is available for Unix-type operating systems and Microsoft Windows. Vim is an editor which may prove frustrating to use at first (and later....) but which is capable of editing text rapidly with very few keystrokes. For example typing 'dapGp' deletes the current paragraph (where the cursor is) and copies it to at the end of the document. Vim is especially designed for people who can, or would like to type without looking at the keyboard. Vim may be regarded as a sharp tool which is capable of carrying out work rapidly but also capable of causing confusion and frustration to its user. Vim is most suited to those people whose work involves significant amounts of writing or dealing with textual information. It is also likely to be most appreciated by those people who are able to 'touch-type'. Vim (or vi) is installed by default on many Unix systems, including Apple OSX and Linux. The current document is orientated towards using vim on a Unix-style operating system such as Apple OSX or Linux. WEB RESOURCES @@ www.vim.org the official site @@ http://en.wikibooks.org/wiki/Learning_the_vi_editor/ another book CHEAT SHEETS .... @@ http://www.eec.com/business/vi.html THE CRASH COURSE The thing was most confuses the new user of the Vim text editor is that when you first start the editor, you are unable to type anything! (at least, until you hit the letter 'i'). The most important thing to know about vim, is that it has 2 (main) modes: 'Normal' mode and 'Insert' mode. In normal mode you can't type anything! Thereby leading the novice to a great deal of confusion, perplexity and desperation. In order to start entering text in the editor, you have to type 'i', (which puts the editor in Insert Mode). Hitting the [esc] key, goes back to Normal Mode (in which you can enter commands). If you can overcome this initial hurdle in using Vim, you may (one day) appreciate its qualities. One important hint: If vim seems to have gone completely mad... check that the caps lock key is not on! * get me the hell out of here!!, (save and exit) >> [esc] ZZ >> [esc] :wq! [enter] ##(if the previous didn't work!) * put the Vim editor into 'insert' mode so you can enter some text >> i * undo the change which you just made (your gonna need this!). >> [esc] u >> :u ##(the same) Any command beginning with ':' must be terminated by pressing the [enter] key. * repeat the thing you just did >> . * redo the change which you just undid >> [esc] :red [enter] * stop inserting text >> [esc] * find the word 'big' in the file >> [esc] /big * view the helpful user guides to vim. These are more understandable * than the reference manuals >> :help user * view the help for the command ':w' (the save file command) >> :help :w * getting help for the Vim editor >> :help >> :help GETTING HELP Vim contains an extremely comprehensive set of help files but unfortunately to the uninitiated this help system can be as impenetrable as the vim editor itself. One reason is that the vim help system uses its own form of 'hypertext', that is, the help files contain links such as |uganda| between bar characters. To navigate to that link you need to press ] (the control key followed by the ']' character). Who would guessed that? To navigate back to the previous link, you need to press The help obtained through typing ':help topic' can be very cryptic for the same reason that unix man pages and javadoc files are cryptic ... there are virtually no example commands. This cryptic-ness seems to form part of a venerable but annoying unix tradition. Luckily with the advent of the web you can find countless good tutorials and examples with Google. @@ http://vim.runpaint.org/toc/ good advanced tips, with explanations @@ www.vim.org/tips/index.php lots of tips @@ http://vim.wikia.com/wiki/Main_Page more tips @@ http://rayninfo.co.uk/vimtips.html probably the best set of tips on the web. * display the help for the 'y' (yank) command >> :help y * display the help for the ':set' command >> :h :set >> :help :set ##(the same) * display some help for vim from the command line >> vim -h ##(this help is mainly about options, not how to use) >> gvim -h ##(the same if you using gvim) * display help for the key combination (from 'normal' mode) >> :h ctrl-r * press tab after a partial help term to cycle through the choices >> :h qui ##(this means, type ':h qui' and then press [tab]) * press after a partial help term to list all the choices >> :h qui ##(type ':h qui' and then press ) Press to choose one from the list. * display the tips from the help file >> :h tips * start the vim tutorial >> :h tutor == help for help (USE TAB) .. :h quickref - VIM Quick Reference Sheet .. :h ctrl - list help of all control keys .. :h \\zs - double up backslash to find \zs in help ??? .. :cabbrev h tab h - open help in a tab .. * see a vim tutorial from the command line (shell) >> vimtutor * what's \r in a regexp (matches a ) >> :h /\r - * get help for the '\@=' pattern in searches or jumps >> :h /\@= * view help for using '[control] r' when in insert mode >> :h i_CTRL-R >> :h c_CTRL-R - ##(the same for 'command' mode) >> :h v_CTRL-V - ##(the same for 'visual' mode) * view the help for customizing the vim help files >> :help add-local-help * rebuild all *.txt help files in /doc >> :helptags /vim/vim64/doc SEARCHING THE VIM HELP FILES .... * search the vim help files for the text 'utf8' >> helpg utf8 >> helpgrep utf8 ##(the same) When the above search is executed the first help file containing the text 'utf8' will be opened at the appropriate spot in a new vim window. * jump to the next file found by 'helpgrep' >> :cn * jump to the previous file found by 'helpgrep' >> :cp * search the vim help files using a pattern (regular expression) >> :helpgrep edit.*dir ##(will find 'edit' followed by 'dir' ) THE VIM HELP SYSTEM .... The vim help system uses its own type of 'hyper-text' with links embedded in the text. * within the vim help system, to navigate to a 'link' press >> * within the vim help system, to navigate to the previous page >> THE VIM ANNOYANCES In order to go into 'normal' mode (where you can enter commands such as 'D' delete the rest of the line) you have to press the [escape] key which is quite difficult to find without looking at the keyboard. But there are several solutions to this, probably the best is to map 'fj' or 'jj' to * map the key combo 'fj' in insert mode to the '' key >> :imap fj >> :inoremap fj ##(the same, but subtly different) The mapping should use a key combination which is not likely to occur often in your language or documents. In English this would be, for example 'fj'. In order to insert 'fj' in the document you just need to type the fj slowly. 'normal' mode does not seem very normal, and seems a confusing name for that mode. * map [shift] [space] to go to 'normal' mode, but doesn't work for me >> :imap == alternatives to the escape key .. [control] [ .. [control] c .. :imap jj .. :imap ;; I find 'K' annoying. It looks up help under the cursor. But this is never what I want, since I always hit it by mistake for 'k' * remap K to be more innocuous (goes down 30 lines) >> :map K 30+ TRAPS .... == Vim traps .. In regular expressions you must backslash + (match 1 or more) .. In regular expressions you must backslash | (or) .. In regular expressions you must backslash ( (group) .. In regular expressions you must backslash { (count) .. /fred\+/ matches fred/freddy but not free .. /\(fred\)\{2,3}/ note what you have to break .. STARTING VIM * open the file 'list.txt' with the cursor on line 24 >> vim +24 list.txt * open the file 'test.txt' at the 1st line which contains 'hello' >> vim +/hello test.txt * prevent modifications to a file >> :set noma * start vim in insert mode >> vim -c start * from bash, delete those pesky swap files >> find /home/ -iname '*.swp' -delete * a bash function to delete vim swap files >> delswap () { find /home/ -iname '*.swp' -delete ; } Swap files for vim (.swp) contain a file which was being edited but not saved. Only delete them if you are sure. OPENING FILES TO EDIT ------------------------------------------------------- * edit the text file 'poem.txt' in the current folder >> vim poem.txt * edit all files found having a specific string found by grep >> grep -Hrli 'foo' * | xargs vim * edit the file which was just mentioned on the command line >> less ~/docs/poem.txt >> vim !$ ##(this opens the file '~/docs/poem.txt' for editing) * choose a file from the current directory to edit >> :e . ##(the dot IS necessary) * choose a file to edit >> :E ##(no dot is necessary) * edit the file most recently edited in the current session >> :e # * reload the current file which has been modified in another editor >> :e! * search for the location of the file name (or similar) under the cursor >> :!locate "" | less * edit a compressed file (.Z, .gz .bz2) >> vim file ##(same as editing a normal file, thanks to the 'gzip' plug-in) * Edit a script that's somewhere in your path. >> vim `which ` >> vim $(which ) ##(the same) Its possible to edit the standard input stream (usually called 'stdin') This might also be useful for searching multiple files. * edit (a new file) containing lines which contain 'tree' from 'doc.txt' >> grep tree doc.txt | vim - ##(I'm not sure why you would want to do this) == exploring files to edit .. :e . - file explorer .. :Exp(lore) - file explorer note capital Ex .. :Sex(plore) - file explorer in split window .. :browse e - windows style browser .. :cd .. - move to the parent directory .. :args - list files currently open for editing .. :args *.php - open all 'php' files in this folder .. :lcd %:p:h - change to directory of current file .. * change to the folder of the current document automatically >> :autocmd BufEnter * lcd %:p:h * edit the file which was most recently changed >> vim $(ls -t | head -n1) * open for editing the file whose name is under the cursor >> gf * use tab-completion to open 'long-name.extension' for editing >> :e long * use file-name completion to insert 'long.name.ext' file in the text >> long. [control] x [control] f The recipe above means: type 'long.' then press the [control] key, then 'x' then the [control] key again and then 'f' THE EDIT WINDOW * VIM: when Ctrl-D and Ctrl-U only scroll one line, reset to default >> :set scroll=0 * make the current line the center line of the window >> zz EDITING MULTIPLE FILES ------------------------------------------------------- In vim we open a file as a 'buffer'. As we edit that buffer, no changes are made to the file until we write that buffer to the file (save it) with the ':w' command. The distinction between a buffer and a file is important. * edit all filenames ending with '.txt' in the current folder >> vim *.txt * edit all files on the computer ending with 'tree' in the filename >> vim $(find / -name "*tree") ##('find' may take a while to finish) >> vim `find / -name "*tree"` ##(the same) * see all the files currently being edited >> :args * open a new file and edit it >> :arge file * close a file or a buffer, but the file still appears with :args >> :bd * close file number 1 (as shown with the ':ls' command) >> :bd 1 * edit lots of files which contain the word 'tree' (including sub-folders) >> vim $(grep -ril tree *) It would probably be faster to use a find/xargs and grep * substitute yes with no, in all the files, confirming each substitution >> :argdo %s/yes/no/gc | w ##(the 'w' saves each file) * write all files in the argument list (all files being edited) >> :wa * jump to the file (or url) under the cursor >> gf * open a new file (without closing the last) and edit it >> arge * toggle between 2 buffers (files) which are open in vim >> [control] ^ This switches back and forth between the 2 files, but it doesnt work when vim is in insert mode (when you are entering text into the document) or command mode (when you are typing commands at the bottom of the screen after a ':' character) * Sessions (Open a set of files) >> gvim file1.c file2.c lib/lib.h lib/lib2.h : load files for "session" >> :mksession ##( Make a Session file (default Session.vim)) * execute multiple commands on a group of files >> vim -c "argdo %s/ABC/DEF/ge | update" *.c * remove blocks of text from a series of files >> vim -c "argdo /begin/+1,/end/-1g/^/d | update" *.c * %s across multiple files with Vim >> :set nomore :argdo %s/foo/bar/g | update == Operate a command over multiple files .. :argdo %s/foo/bar/e - operate on all files in :args .. :bufdo %s/foo/bar/e .. :windo %s/foo/bar/e .. :argdo exe '%!sort'|w! - include an external command .. :bufdo exe "normal @q" | w - perform a recording on open files .. == commands for multiple files management .. :bn - goto next buffer, the cycles around (unlike ':n') .. :bp - goto previous buffer .. :wn - save file and move to next .. :wp - save file and move to previous .. :bd - remove file from buffer list .. :bun - Buffer unload (remove window but not from list) .. :badd file.c - file from buffer list .. :!mv % %:r.bak - rename current file (DOS use Rename or DEL) .. :help filename-modifiers - get help .. :e! - return to unmodified file .. :w c:/aaa/% - save file elsewhere .. :sp fred.txt - open fred.txt into a split .. :sball,:sb - Split all buffers .. :scrollbind - in each split window .. :set hidden - Allows to change buffer w/o saving current buffer .. SWITCHING BETWEEN OPEN FILES .... * make pressing 'T' cycle through (switch between) the open files >> :map T :bn * a mapping to make key list all buffers, then type a number to jump >> :map :ls:e # * edit the alternative file == commands to switch between open files .. :ls - list all open buffers .. :e # .. :e #3 - edit the 3rd file .. :rew - return to beginning of edited files list (:args) .. :brew - buffer rewind .. - switch the alternate open file .. :b3 - go to buffer number 3 .. :b main - go to buffer with 'main' in name eg "main.c" .. :bd1 - delete the 1st file from the buffer list .. EDITING IN MULTIPLE WINDOWS .... Vim windows are not like 'desktop' windows; they are panes into which the text editing area is split. * open the file in a split window above the current file >> :sp file ##(the original file remains open) >> :split file ##(the same) * close the current window >> :q * jump from one window to another >> [control]+w [control]+w * capturing output of current script in a separate buffer >> :new | r!perl # ##( opens new buffer,read other buffer) >> :new! x.out | r!perl # ##( same with named file) >> :new+read!ls * vertically split current file with other.php >> :vsplit other.php * a map to jump quicly between splits >> map j_ >> map k_ TRANSFERING TEXT FROM ONE FILE TO ANOTHER .... * open 2 files ('fa' and 'fb') in vim >> vim fa fb * use '[control] ^' to switch between the 2 files * delete a paragraph in one file and paste it in the second >> dap (press [control] ^) p * copy a paragraph to the clipboard and paste it into the second >> yap (press [control] ^) p * a command 'Wr' to (over-)write a paragraph from this file to 'i.txt' >> :com! Wr ?^ *$?+1,/^ *$/-1w ~/i.txt * a command to append a paragraph from this file to another file >> :com! -nargs=1 Send ?^ *$?+1,/^ *$/-1w !cat - >> ~/.txt The above command can be run with ':Send filename' which appends the current paragraph (wherever the cursor happens to be positioned) to the end of the file 'filename'. COMPARING FILES .... * compare a remote file with a local file >> vimdiff scp://[@]/ * complex comparison of parts of a file with itself >> :1,2yank a | 7,8yank b >> :tabedit | put a | vnew | put b >> :windo diffthis TABS Recent versions of vim can use tabs to edit multiple files. I had no idea about this. Tabs are similar to the tabs used in modern web browsers, allowing you to have more that one file open and easily switch between the open files. Tabs are possible more useful than split windows because you do not have to share the 'screen space' between the two files. == a tab cheat sheet .. :tabe fred.php - open the document 'fred.php' in a new tab .. :tabn - switch to the next (or first) tab .. :tabc - close the current tab .. :tabc - close all tabs except the current tab .. GETTING HELP FOR TABS .... * view help for using tabs >> help :tab >> help tabpage ##(better help) * show all open tab files >> :tabs OPENING FILES IN TABS .... * open 2 files in vim using tabs >> vim -p fred.php joe.php * open fred.php in a new tab >> :tabe fred.php * reopen files in new tabs >> :tab ball * read the 'vimtips' site from the web into a new tab >> :tabe | :r ! lynx -dump http://zzapper.co.uk/vimtips.html This is an old link CLOSING TABS .... * close the current tab >> :tabc >> :tabclose ##(the same) * close all tabs except the current one >> :tabo * exit all tabs and vim in one go >> :qa SWITCHING TABS .... * switch to the next tab. Goes back to the first if on the last tab >> :tabn >> :tabnext ##(the same) >> [control] [pagedown] ##(the same again) * switch to the previous tab >> :tabp >> :tabN ##(the same) * go to the last tab page >> :tabl * go to the first tab page >> :tabr >> :tabfir * use with vim 7 to force the use of tabs from .vimrc >> :nnoremap gf gf >> :cab e tabe >> :tab sball ##(retab all files in the buffer) EDITING REMOTE FILES Use the 'netrw' plug-in, but the version which comes with vim 7.0 for windows does not work well. * edit a file on a sourceforge site with vim >> :e scp://user,project@web.sourceforge.net/htdocs/file.txt * edit the text file 'index.txt' from a webserver >> :r http://nowhere.org/index.txt The changes made to the file 'index.txt' are only saved locally * create maps to edit files via ftp (using the 'netrw' plugin) >> cmap ,r :Nread ftp://209.51.134.122/public_html/index.html >> cmap ,w :Nwrite ftp://209.51.134.122/public_html/index.html >> gvim ftp://www.somedomain.com/index.html EDITING A WIKI WITH LYNX AND VIM .... @@ http://c2.com/cgi/wiki?UsingWikiWithLynx instructions on how to use vim and lynx to edit a wiki. Start lynx; press "o"; in the "Editor" field write "usr/bin/vim" or the path to the "vim" executable (if you dont know this, type "which vim" on the command line). At the bottom of the page activate the "accept changes" link. Go to a wiki-page in lynx and "click" on "edit". Go to the edit field and type "control X v" or "control V v". After editing type ":wq" and then click on the save link ENCRYPTION AND VIM The Vim encryption algorithm is stated to be weak. But it may keep the honest people out. * start editing 'file.txt' using encryption >> vim -x file.txt ##(a password prompt will appear) * remove the password for a file (and file encryption) >> set key= * change or add a password for a file >> :X ##(an 'enter password' prompt will appear) Rot13 encryption is an extremely weak type of encryption and is better described as 'obfuscation' == ways to use 'rot13' encryption .. ggg?G - encode in 'rot13' whole file (quicker for large file) .. :8 | normal VGg? - rot13 from line 8 .. :normal 10GVGg? - rot13 from line 8 .. :20,25 !rot13 - encrypt with rot13 lines 20 to 25 SAVING FILES ----------------------------------------------------------- * set vim to automatically save files on exit or when switching buffers >> :set autowriteall * save a copy of the current file named 'copy.txt' >> :w copy.txt ##(continue to edit the original file) * save a file with a new name ("save as") and edit the new file >> :sav copy.txt * save the current file with a new name by substitution >> :sav %:s/report/list/ * save the current file changing the extension to bak >> :w %:r.bak * Save a file you edited in vim without the needed permissions >> :w !sudo tee % ##(the file must be reloaded) >> :w !pfexec tee % ##(another way, but requires 'pfexec' to be installed) == other save commands .. :sav! %<.bak - Save Current file to alternative extension (old way) .. :sav! %:r.cfm - Save Current file to alternative extension .. :sav %:s/fred/joe/:r.bak2 - do a substitute on file name & ext. .. SAVING CHUNKS OF FILES .... * save highlighted text to a new file >> [shift]+v , highlight text with j or k, then >> :w newfile * save the text between bookmarks 'a' and 'b' to newfile >> 'a,'b w newfile * save the lines 200-300 to the end of 'textfile' (append the text) >> :200,300w >> textfile * save the current paragraph to the end of 'textfile' >> !apw >> textfile ##( means press that key) * write everything from the current line to the bookmark 'x' to 'file.txt' >> !'xw file.txt ##(the file is created) >> !'xw! file.txt ##(if the file exists, it is overwritten) BACKING UP FILES * load the swap backup of a file into vim >> :recover COMPRESSED FILES * do 'zip' compression on all the currently open text files >> :silent bufdo !zip proj.zip %:p FILENAME MODIFIERS * get help for filename modifiers (for saving files with new names) >> :help filename-modifiers == manipulating file names .. :h filename-modifiers - help .. :w % - write to current file name .. :w %:r.cfm - change file extention to .cfm .. :!echo %:p - full path & file name .. :!echo %:p:h - full path only .. :!echo %:t - filename only .. :reg % - display filename .. % - insert filename (insert mode) .. "%p - insert filename (normal mode) .. /% - Search for file name in text .. :!echo %:gs/A/a/ - show current filename with all 'A' as 'a' .. :!echo %:s/A/a/ - only substitute the 1st occurance .. :lcd %:p:h - change to directory of current file .. * display the full path and filename without the filename extension >> :!echo %:r TIPS == miscellaneous useful tips .. % - jump to the matching brackets '{}[]()' .. . - repeat last modification .. @: - repeat last : command (then @@) .. matchit.vim - % now matches tags