% ------------------------------------------- % latex generated by: booktolatex.cgi % from source file : ../htdocs/books/vim/vim-book.txt % on: 19 April 2024, 10:22pm % querystring: books/vim/vim-book.txt % document-root: /var/www/html % script-name: /cgi-bin/booktolatex.cgi % Server-name: bumble.sourceforge.net % Sed-script: booktolatex.sed % ------------------------------------------- \documentclass[a4paper,12pt]{article} \usepackage[margin=0.4cm,noheadfoot]{geometry} \usepackage{color} %% to use colours, use "xcolor" for more \usepackage{multicol} %% for multiple columns \usepackage{keystroke} %% for keyboard key images \usepackage[toc]{multitoc} %% for multi column table of contents \usepackage{tocloft} %% to customize the table of contents \setcounter{tocdepth}{2} %% only display 2 levels in the contents \setlength{\cftbeforesecskip}{0cm} %% make the toc more compact \usepackage{listings} %% for nice code listings %\lstset{language={}, \lstset{language=, %% define special comment delimiters '##(' and ')' moredelim=[s][\color{grey}\itshape\footnotesize\ttfamily]{~(}{)}, basicstyle=\ttfamily, %% fixed pitch font xleftmargin=1cm, %% margin on the left outside the frames breaklines=true, %% break long code lines breakatwhitespace=false, %% break long code lines anywhere breakindent=10pt, %% reduce the indent from 20pt to 10 postbreak=\mbox{{\color{blue}\small$\Rightarrow$\space}}, %% mark with arrow showstringspaces=false, %% dont show spaces within strings framerule=5pt, %% thickness of the frames rulecolor=\color{lightgrey}, frame=l} %% source code settings \usepackage{graphicx} %% to include images \usepackage{fancybox} %% boxes with rounded corners \usepackage{wrapfig} %% flow text around tables, images \usepackage{tabularx} %% change width of tables \usepackage[table]{xcolor} %% alternate row colour tables \usepackage{booktabs} %% for heavier rules in tables \usepackage[small,compact]{titlesec} %% sections more compact, less space \usepackage{enumitem} %% more compact and better lists \setlist{noitemsep} %% reduce list item spacing \usepackage{hyperref} %% make urls into hyperlinks \hypersetup{ %% add "pdftex," if only pdf output is required colorlinks=true, %% set up the colours for the hyperlinks linkcolor=black, %% internal document links black urlcolor=black, %% url links black filecolor=red, citecolor=red, bookmarks=true, pdfpagemode=UseOutlines} % define some colours to use \definecolor{lightgrey}{gray}{0.70} \definecolor{grey}{gray}{0.30} \titleformat{\section}[frame] %% titlesec: create framed section headings {\normalfont} {\filleft \footnotesize \enspace Section \thesection\enspace\enspace} {3pt} {\bfseries\itshape\filright} \title{The 'Vi Improved' Text Editor} \author{} \date{25 July 2018, 11:47am} \setlength{\parindent}{0pt} % \setlength{\parskip}{1ex} % label lists with stars \renewcommand{\labelitemi}{$\star$} \begin{document} \centerline{\Large \bf The 'Vi Improved' Text Editor} \medskip \begin{center} {\huge ``}\textit{}{\huge ''} \textsc{} \end{center} % ----------------------------------- % the toc should be 2 columns because of the \multitoc package \tableofcontents Quote: ``annoying but excellent'' (David Rayner) \section{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. \section{Web Resources} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{www.vim.org}] the official site \item[\url{http://en.wikibooks.org/wiki/Learning_the_vi_editor/}] another book \end{description} \subsection{Cheat Sheets} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://www.eec.com/business/vi.html}] \end{description} \section{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! \emph{ Get me the hell out of here!!, (save and exit) } \begin{lstlisting} [esc] ZZ \end{lstlisting} \begin{lstlisting} [esc] :wq! [enter] ~(if the previous didn't work!) \end{lstlisting} \emph{ Put the Vim editor into 'insert' mode so you can enter some text } \begin{lstlisting} i \end{lstlisting} \emph{ Undo the change which you just made (your gonna need this!). } \begin{lstlisting} [esc] u \end{lstlisting} \begin{lstlisting} :u ~(the same) \end{lstlisting} Any command beginning with ':' must be terminated by pressing the \Enter key. \emph{ Repeat the thing you just did } \begin{lstlisting} . \end{lstlisting} \emph{ Redo the change which you just undid } \begin{lstlisting} [esc] :red [enter] \end{lstlisting} \emph{ Stop inserting text } \begin{lstlisting} [esc] \end{lstlisting} \emph{ Find the word 'big' in the file } \begin{lstlisting} [esc] /big \end{lstlisting} \emph{ View the helpful user guides to vim. These are more understandable } \emph{ Than the reference manuals } \begin{lstlisting} :help user \end{lstlisting} \emph{ View the help for the command ':w' (the save file command) } \begin{lstlisting} :help :w \end{lstlisting} \emph{ Getting help for the Vim editor } \begin{lstlisting} :help \end{lstlisting} \begin{lstlisting} :help \end{lstlisting} \section{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 $<$control$>$ ] (the control key followed by the ']' character). Who would guessed that? To navigate back to the previous link, you need to press $<$control-t$>$ 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. \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://vim.runpaint.org/toc/}] good advanced tips, with explanations \item[\url{www.vim.org/tips/index.php}] lots of tips \item[\url{http://vim.wikia.com/wiki/Main_Page}] more tips \item[\url{http://rayninfo.co.uk/vimtips.html}] probably the best set of tips on the web. \end{description} \emph{ Display the help for the 'y' (yank) command } \begin{lstlisting} :help y \end{lstlisting} \emph{ Display the help for the ':set' command } \begin{lstlisting} :h :set \end{lstlisting} \begin{lstlisting} :help :set ~(the same) \end{lstlisting} \emph{ Display some help for vim from the command line } \begin{lstlisting} vim -h ~(this help is mainly about options, not how to use) \end{lstlisting} \begin{lstlisting} gvim -h ~(the same if you using gvim) \end{lstlisting} \emph{ Display help for the $<$control-r$>$ key combination (from 'normal' mode) } \begin{lstlisting} :h ctrl-r \end{lstlisting} \emph{ Press tab after a partial help term to cycle through the choices } \begin{lstlisting} :h qui ~(this means, type ':h qui' and then press [tab]) \end{lstlisting} \emph{ Press $<$control-d$>$ after a partial help term to list all the choices } \begin{lstlisting} :h qui ~(type ':h qui' and then press ) \end{lstlisting} Press $<$tab$>$ to choose one from the list. \emph{ Display the tips from the help file } \begin{lstlisting} :h tips \end{lstlisting} \emph{ Start the vim tutorial } \begin{lstlisting} :h tutor \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ help for help (USE TAB) }} \\ \hline \texttt{ :h quickref } & VIM Quick Reference Sheet \\ \texttt{ :h ctrl$<$C-D$>$ } & List help of all control keys \\ \texttt{ :h \\textbackslash zs } & Double up backslash to find \textbackslash zs in help ??? \\ \texttt{ :cabbrev h tab h } & Open help in a tab \\ \hline \end{tabular} \end{center} \emph{ See a vim tutorial from the command line (shell) } \begin{lstlisting} vimtutor \end{lstlisting} \emph{ What's \textbackslash r in a regexp (matches a $<$CR$>$) } \begin{lstlisting} :h /\r - \end{lstlisting} \emph{ Get help for the '\textbackslash @=' pattern in searches or jumps } \begin{lstlisting} :h /\@= \end{lstlisting} \emph{ View help for using '[control] r' when in insert mode } \begin{lstlisting} :h i_CTRL-R \end{lstlisting} \begin{lstlisting} :h c_CTRL-R - ~(the same for 'command' mode) \end{lstlisting} \begin{lstlisting} :h v_CTRL-V - ~(the same for 'visual' mode) \end{lstlisting} \emph{ View the help for customizing the vim help files } \begin{lstlisting} :help add-local-help \end{lstlisting} \emph{ Rebuild all *.txt help files in /doc } \begin{lstlisting} :helptags /vim/vim64/doc \end{lstlisting} \subsection{Searching The Vim Help Files} \emph{ Search the vim help files for the text 'utf8' } \begin{lstlisting} helpg utf8 \end{lstlisting} \begin{lstlisting} helpgrep utf8 ~(the same) \end{lstlisting} 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. \emph{ Jump to the next file found by 'helpgrep' } \begin{lstlisting} :cn \end{lstlisting} \emph{ Jump to the previous file found by 'helpgrep' } \begin{lstlisting} :cp \end{lstlisting} \emph{ Search the vim help files using a pattern (regular expression) } \begin{lstlisting} :helpgrep edit.*dir ~(will find 'edit' followed by 'dir' ) \end{lstlisting} \subsection{The Vim Help System} The vim help system uses its own type of 'hyper-text' with links embedded in the text. \emph{ Within the vim help system, to navigate to a 'link' press $<$control ]$>$ } \begin{lstlisting} \end{lstlisting} \emph{ Within the vim help system, to navigate to the previous page } \begin{lstlisting} \end{lstlisting} \section{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 $<$esc$>$ \emph{ Map the key combo 'fj' in insert mode to the '$<$escape$>$' key } \begin{lstlisting} :imap fj \end{lstlisting} \begin{lstlisting} :inoremap fj ~(the same, but subtly different) \end{lstlisting} 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. \emph{ Map [shift] [space] to go to 'normal' mode, but doesn't work for me } \begin{lstlisting} :imap \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ alternatives to the escape key }} \\ \hline \texttt{ [control] [ } \\ \texttt{ [control] c } \\ \texttt{ :imap jj $<$esc$>$ } \\ \texttt{ :imap ;; $<$esc$>$ } \\ 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' \emph{ Remap K to be more innocuous (goes down 30 lines) } \begin{lstlisting} :map K 30+ \end{lstlisting} \subsection{Traps} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Vim traps }} \\ \hline \texttt{ In regular expressions you must backslash + (match 1 or more) } \\ \texttt{ In regular expressions you must backslash | (or) } \\ \texttt{ In regular expressions you must backslash ( (group) } \\ \texttt{ In regular expressions you must backslash $\{$ (count) } \\ \texttt{ /fred\textbackslash +/ matches fred/freddy but not free } \\ \texttt{ /\textbackslash (fred\textbackslash )\textbackslash $\{$2,3$\}$/ note what you have to break } \\ \hline \end{tabular} \end{center} \section{Starting Vim} \emph{ Open the file 'list.txt' with the cursor on line 24 } \begin{lstlisting} vim +24 list.txt \end{lstlisting} \emph{ Open the file 'test.txt' at the 1st line which contains 'hello' } \begin{lstlisting} vim +/hello test.txt \end{lstlisting} \emph{ Prevent modifications to a file } \begin{lstlisting} :set noma \end{lstlisting} \emph{ Start vim in insert mode } \begin{lstlisting} vim -c start \end{lstlisting} \emph{ From bash, delete those pesky swap files } \begin{lstlisting} find /home/ -iname '*.swp' -delete \end{lstlisting} \emph{ A bash function to delete vim swap files } \begin{lstlisting} delswap () { find /home/ -iname '*.swp' -delete ; } \end{lstlisting} Swap files for vim (.swp) contain a file which was being edited but not saved. Only delete them if you are sure. \section{Opening Files To Edit} \emph{ Edit the text file 'poem.txt' in the current folder } \begin{lstlisting} vim poem.txt \end{lstlisting} \emph{ Edit all files found having a specific string found by grep } \begin{lstlisting} grep -Hrli 'foo' * | xargs vim \end{lstlisting} \emph{ Edit the file which was just mentioned on the command line } \begin{lstlisting} less ~/docs/poem.txt \end{lstlisting} \begin{lstlisting} vim !$ ~(this opens the file '~/docs/poem.txt' for editing) \end{lstlisting} \emph{ Choose a file from the current directory to edit } \begin{lstlisting} :e . ~(the dot IS necessary) \end{lstlisting} \emph{ Choose a file to edit } \begin{lstlisting} :E ~(no dot is necessary) \end{lstlisting} \emph{ Edit the file most recently edited in the current session } \begin{lstlisting} :e # \end{lstlisting} \emph{ Reload the current file which has been modified in another editor } \begin{lstlisting} :e! \end{lstlisting} \emph{ Search for the location of the file name (or similar) under the cursor } \begin{lstlisting} :!locate "" | less \end{lstlisting} \emph{ Edit a compressed file (.Z, .gz .bz2) } \begin{lstlisting} vim file ~(same as editing a normal file, thanks to the 'gzip' plug-in) \end{lstlisting} \emph{ Edit a script that's somewhere in your path. } \begin{lstlisting} vim `which ` \end{lstlisting} \begin{lstlisting} vim $(which ) ~(the same) \end{lstlisting} Its possible to edit the standard input stream (usually called 'stdin') This might also be useful for searching multiple files. \emph{ Edit (a new file) containing lines which contain 'tree' from 'doc.txt' } \begin{lstlisting} grep tree doc.txt | vim - ~(I'm not sure why you would want to do this) \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ exploring files to edit }} \\ \hline \texttt{ :e . } & File explorer \\ \texttt{ :Exp(lore) } & File explorer note capital Ex \\ \texttt{ :Sex(plore) } & File explorer in split window \\ \texttt{ :browse e } & Windows style browser \\ \texttt{ :cd .. } & Move to the parent directory \\ \texttt{ :args } & List files currently open for editing \\ \texttt{ :args *.php } & Open all 'php' files in this folder \\ \texttt{ :lcd \%:p:h } & Change to directory of current file \\ \hline \end{tabular} \end{center} \emph{ Change to the folder of the current document automatically } \begin{lstlisting} :autocmd BufEnter * lcd %:p:h \end{lstlisting} \emph{ Edit the file which was most recently changed } \begin{lstlisting} vim $(ls -t | head -n1) \end{lstlisting} \emph{ Open for editing the file whose name is under the cursor } \begin{lstlisting} gf \end{lstlisting} \emph{ Use tab-completion to open 'long-name.extension' for editing } \begin{lstlisting} :e long \end{lstlisting} \emph{ Use file-name completion to insert 'long.name.ext' file in the text } \begin{lstlisting} long. [control] x [control] f \end{lstlisting} The recipe above means: type 'long.' then press the [control] key, then 'x' then the [control] key again and then 'f' \section{The Edit Window} \emph{ VIM: when Ctrl-D and Ctrl-U only scroll one line, reset to default } \begin{lstlisting} :set scroll=0 \end{lstlisting} \emph{ Make the current line the center line of the window } \begin{lstlisting} zz \end{lstlisting} \section{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. \emph{ Edit all filenames ending with '.txt' in the current folder } \begin{lstlisting} vim *.txt \end{lstlisting} \emph{ Edit all files on the computer ending with 'tree' in the filename } \begin{lstlisting} vim $(find / -name "*tree") ~('find' may take a while to finish) \end{lstlisting} \begin{lstlisting} vim `find / -name "*tree"` ~(the same) \end{lstlisting} \emph{ See all the files currently being edited } \begin{lstlisting} :args \end{lstlisting} \emph{ Open a new file and edit it } \begin{lstlisting} :arge file \end{lstlisting} \emph{ Close a file or a buffer, but the file still appears with :args } \begin{lstlisting} :bd \end{lstlisting} \emph{ Close file number 1 (as shown with the ':ls' command) } \begin{lstlisting} :bd 1 \end{lstlisting} \emph{ Edit lots of files which contain the word 'tree' (including sub-folders) } \begin{lstlisting} vim $(grep -ril tree *) \end{lstlisting} It would probably be faster to use a find/xargs and grep \emph{ Substitute yes with no, in all the files, confirming each substitution } \begin{lstlisting} :argdo %s/yes/no/gc | w ~(the 'w' saves each file) \end{lstlisting} \emph{ Write all files in the argument list (all files being edited) } \begin{lstlisting} :wa \end{lstlisting} \emph{ Jump to the file (or url) under the cursor } \begin{lstlisting} gf \end{lstlisting} \emph{ Open a new file (without closing the last) and edit it } \begin{lstlisting} arge \end{lstlisting} \emph{ Toggle between 2 buffers (files) which are open in vim } \begin{lstlisting} [control] ^ \end{lstlisting} 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) \emph{ Sessions (Open a set of files) } \begin{lstlisting} gvim file1.c file2.c lib/lib.h lib/lib2.h : load files for "session" \end{lstlisting} \begin{lstlisting} :mksession ~( Make a Session file (default Session.vim)) \end{lstlisting} \emph{ Execute multiple commands on a group of files } \begin{lstlisting} vim -c "argdo %s/ABC/DEF/ge | update" *.c \end{lstlisting} \emph{ Remove blocks of text from a series of files } \begin{lstlisting} vim -c "argdo /begin/+1,/end/-1g/^/d | update" *.c \end{lstlisting} \emph{ \%s across multiple files with Vim } \begin{lstlisting} :set nomore :argdo %s/foo/bar/g | update \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Operate a command over multiple files }} \\ \hline \texttt{ :argdo \%s/foo/bar/e } & Operate on all files in :args \\ \texttt{ :bufdo \%s/foo/bar/e } \\ \texttt{ :windo \%s/foo/bar/e } \\ \texttt{ :argdo exe '\%!sort'|w! } & Include an external command \\ \texttt{ :bufdo exe ``normal @q'' | w } & Perform a recording on open files \\ \hline \end{tabular} \end{center} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ commands for multiple files management }} \\ \hline \texttt{ :bn } & Goto next buffer, the cycles around (unlike ':n') \\ \texttt{ :bp } & Goto previous buffer \\ \texttt{ :wn } & Save file and move to next \\ \texttt{ :wp } & Save file and move to previous \\ \texttt{ :bd } & Remove file from buffer list \\ \texttt{ :bun } & Buffer unload (remove window but not from list) \\ \texttt{ :badd file.c } & File from buffer list \\ \texttt{ :!mv \% \%:r.bak } & Rename current file (DOS use Rename or DEL) \\ \texttt{ :help filename-modifiers } & Get help \\ \texttt{ :e! } & Return to unmodified file \\ \texttt{ :w c:/aaa/\% } & Save file elsewhere \\ \texttt{ :sp fred.txt } & Open fred.txt into a split \\ \texttt{ :sball,:sb } & Split all buffers \\ \texttt{ :scrollbind } & In each split window \\ \texttt{ :set hidden } & Allows to change buffer w/o saving current buffer \\ \hline \end{tabular} \end{center} \subsection{Switching Between Open Files} \emph{ Make pressing 'T' cycle through (switch between) the open files } \begin{lstlisting} :map T :bn \end{lstlisting} \emph{ A mapping to make key $<$F5$>$ list all buffers, then type a number to jump } \begin{lstlisting} :map :ls:e # \end{lstlisting} \emph{ Edit the alternative file } \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ commands to switch between open files }} \\ \hline \texttt{ :ls } & List all open buffers \\ \texttt{ :e \# } \\ \texttt{ :e \#3 } & Edit the 3rd file \\ \texttt{ :rew } & Return to beginning of edited files list (:args) \\ \texttt{ :brew } & Buffer rewind \\ \texttt{ $<$control-\^{}$>$ } & Switch the alternate open file \\ \texttt{ :b3 } & Go to buffer number 3 \\ \texttt{ :b main } & Go to buffer with 'main' in name eg ``main.c'' \\ \texttt{ :bd1 } & Delete the 1st file from the buffer list \\ \hline \end{tabular} \end{center} \subsection{Editing In Multiple Windows} Vim windows are not like 'desktop' windows; they are panes into which the text editing area is split. \emph{ Open the file in a split window above the current file } \begin{lstlisting} :sp file ~(the original file remains open) \end{lstlisting} \begin{lstlisting} :split file ~(the same) \end{lstlisting} \emph{ Close the current window } \begin{lstlisting} :q \end{lstlisting} \emph{ Jump from one window to another } \begin{lstlisting} [control]+w [control]+w \end{lstlisting} \emph{ Capturing output of current script in a separate buffer } \begin{lstlisting} :new | r!perl # ~( opens new buffer,read other buffer) \end{lstlisting} \begin{lstlisting} :new! x.out | r!perl # ~( same with named file) \end{lstlisting} \begin{lstlisting} :new+read!ls \end{lstlisting} \emph{ Vertically split current file with other.php } \begin{lstlisting} :vsplit other.php \end{lstlisting} \emph{ A map to jump quicly between splits } \begin{lstlisting} map j_ \end{lstlisting} \begin{lstlisting} map k_ \end{lstlisting} \subsection{Transfering Text From One File To Another} \emph{ Open 2 files ('fa' and 'fb') in vim } \begin{lstlisting} vim fa fb \end{lstlisting} \emph{ Use '[control] \^{}' to switch between the 2 files } \emph{ Delete a paragraph in one file and paste it in the second } \begin{lstlisting} dap (press [control] ^) p \end{lstlisting} \emph{ Copy a paragraph to the clipboard and paste it into the second } \begin{lstlisting} yap (press [control] ^) p \end{lstlisting} \emph{ A command 'Wr' to (over-)write a paragraph from this file to 'i.txt' } \begin{lstlisting} :com! Wr ?^ *$?+1,/^ *$/-1w ~/i.txt \end{lstlisting} \emph{ A command to append a paragraph from this file to another file } \begin{lstlisting} :com! -nargs=1 Send ?^ *$?+1,/^ *$/-1w !cat - >> ~/.txt \end{lstlisting} 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'. \subsection{Comparing Files} \emph{ Compare a remote file with a local file } \begin{lstlisting} vimdiff scp://[@]/ \end{lstlisting} \emph{ Complex comparison of parts of a file with itself } \begin{lstlisting} :1,2yank a | 7,8yank b \end{lstlisting} \begin{lstlisting} :tabedit | put a | vnew | put b \end{lstlisting} \begin{lstlisting} :windo diffthis \end{lstlisting} \section{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. \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ a tab cheat sheet }} \\ \hline \texttt{ :tabe fred.php } & Open the document 'fred.php' in a new tab \\ \texttt{ :tabn } & Switch to the next (or first) tab \\ \texttt{ :tabc } & Close the current tab \\ \texttt{ :tabc } & Close all tabs except the current tab \\ \hline \end{tabular} \end{center} \subsection{Getting Help For Tabs} \emph{ View help for using tabs } \begin{lstlisting} help :tab \end{lstlisting} \begin{lstlisting} help tabpage ~(better help) \end{lstlisting} \emph{ Show all open tab files } \begin{lstlisting} :tabs \end{lstlisting} \subsection{Opening Files In Tabs} \emph{ Open 2 files in vim using tabs } \begin{lstlisting} vim -p fred.php joe.php \end{lstlisting} \emph{ Open fred.php in a new tab } \begin{lstlisting} :tabe fred.php \end{lstlisting} \emph{ Reopen files in new tabs } \begin{lstlisting} :tab ball \end{lstlisting} \emph{ Read the 'vimtips' site from the web into a new tab } \begin{lstlisting} :tabe | :r ! lynx -dump http://zzapper.co.uk/vimtips.html \end{lstlisting} This is an old link \subsection{Closing Tabs} \emph{ Close the current tab } \begin{lstlisting} :tabc \end{lstlisting} \begin{lstlisting} :tabclose ~(the same) \end{lstlisting} \emph{ Close all tabs except the current one } \begin{lstlisting} :tabo \end{lstlisting} \emph{ Exit all tabs and vim in one go } \begin{lstlisting} :qa \end{lstlisting} \subsection{Switching Tabs} \emph{ Switch to the next tab. Goes back to the first if on the last tab } \begin{lstlisting} :tabn \end{lstlisting} \begin{lstlisting} :tabnext ~(the same) \end{lstlisting} \begin{lstlisting} [control] [pagedown] ~(the same again) \end{lstlisting} \emph{ Switch to the previous tab } \begin{lstlisting} :tabp \end{lstlisting} \begin{lstlisting} :tabN ~(the same) \end{lstlisting} \emph{ Go to the last tab page } \begin{lstlisting} :tabl \end{lstlisting} \emph{ Go to the first tab page } \begin{lstlisting} :tabr \end{lstlisting} \begin{lstlisting} :tabfir \end{lstlisting} \emph{ Use with vim 7 to force the use of tabs from .vimrc } \begin{lstlisting} :nnoremap gf gf \end{lstlisting} \begin{lstlisting} :cab e tabe \end{lstlisting} \begin{lstlisting} :tab sball ~(retab all files in the buffer) \end{lstlisting} \section{Editing Remote Files} Use the 'netrw' plug-in, but the version which comes with vim 7.0 for windows does not work well. \emph{ Edit a file on a sourceforge site with vim } \begin{lstlisting} :e scp://user,project@web.sourceforge.net/htdocs/file.txt \end{lstlisting} \emph{ Edit the text file 'index.txt' from a webserver } \begin{lstlisting} :r http://nowhere.org/index.txt \end{lstlisting} The changes made to the file 'index.txt' are only saved locally \emph{ Create maps to edit files via ftp (using the 'netrw' plugin) } \begin{lstlisting} cmap ,r :Nread ftp://209.51.134.122/public_html/index.html \end{lstlisting} \begin{lstlisting} cmap ,w :Nwrite ftp://209.51.134.122/public_html/index.html \end{lstlisting} \begin{lstlisting} gvim ftp://www.somedomain.com/index.html \end{lstlisting} \subsection{Editing A Wiki With Lynx And Vim} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://c2.com/cgi/wiki?UsingWikiWithLynx}] instructions on how to use vim and lynx to edit a wiki. \end{description} 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 \section{Encryption And Vim} The Vim encryption algorithm is stated to be weak. But it may keep the honest people out. \emph{ Start editing 'file.txt' using encryption } \begin{lstlisting} vim -x file.txt ~(a password prompt will appear) \end{lstlisting} \emph{ Remove the password for a file (and file encryption) } \begin{lstlisting} set key= \end{lstlisting} \emph{ Change or add a password for a file } \begin{lstlisting} :X ~(an 'enter password' prompt will appear) \end{lstlisting} Rot13 encryption is an extremely weak type of encryption and is better described as 'obfuscation' \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ ways to use 'rot13' encryption }} \\ \hline \texttt{ ggg?G } & Encode in 'rot13' whole file (quicker for large file) \\ \texttt{ :8 | normal VGg? } & Rot13 from line 8 \\ \texttt{ :normal 10GVGg? } & Rot13 from line 8 \\ \texttt{ :20,25 !rot13 } & Encrypt with rot13 lines 20 to 25 \\ \section{Saving Files} \emph{ Set vim to automatically save files on exit or when switching buffers } \begin{lstlisting} :set autowriteall \end{lstlisting} \emph{ Save a copy of the current file named 'copy.txt' } \begin{lstlisting} :w copy.txt ~(continue to edit the original file) \end{lstlisting} \emph{ Save a file with a new name (``save as'') and edit the new file } \begin{lstlisting} :sav copy.txt \end{lstlisting} \emph{ Save the current file with a new name by substitution } \begin{lstlisting} :sav %:s/report/list/ \end{lstlisting} \emph{ Save the current file changing the extension to bak } \begin{lstlisting} :w %:r.bak \end{lstlisting} \emph{ Save a file you edited in vim without the needed permissions } \begin{lstlisting} :w !sudo tee % ~(the file must be reloaded) \end{lstlisting} \begin{lstlisting} :w !pfexec tee % ~(another way, but requires 'pfexec' to be installed) \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ other save commands }} \\ \hline \texttt{ :sav! \%$<$.bak } & Save Current file to alternative extension (old way) \\ \texttt{ :sav! \%:r.cfm } & Save Current file to alternative extension \\ \texttt{ :sav \%:s/fred/joe/:r.bak2 } & Do a substitute on file name \& ext. \\ \hline \end{tabular} \end{center} \subsection{Saving Chunks Of Files} \emph{ Save highlighted text to a new file } \begin{lstlisting} [shift]+v , highlight text with j or k, then \end{lstlisting} \begin{lstlisting} :w newfile \end{lstlisting} \emph{ Save the text between bookmarks 'a' and 'b' to newfile } \begin{lstlisting} 'a,'b w newfile \end{lstlisting} \emph{ Save the lines 200-300 to the end of 'textfile' (append the text) } \begin{lstlisting} :200,300w >> textfile \end{lstlisting} \emph{ Save the current paragraph to the end of 'textfile' } \begin{lstlisting} !apw >> textfile ~( means press that key) \end{lstlisting} \emph{ Write everything from the current line to the bookmark 'x' to 'file.txt' } \begin{lstlisting} !'xw file.txt ~(the file is created) \end{lstlisting} \begin{lstlisting} !'xw! file.txt ~(if the file exists, it is overwritten) \end{lstlisting} \section{Backing Up Files} \emph{ Load the swap backup of a file into vim } \begin{lstlisting} :recover \end{lstlisting} \section{Compressed Files} \emph{ Do 'zip' compression on all the currently open text files } \begin{lstlisting} :silent bufdo !zip proj.zip %:p \end{lstlisting} \section{Filename Modifiers} \emph{ Get help for filename modifiers (for saving files with new names) } \begin{lstlisting} :help filename-modifiers \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ manipulating file names }} \\ \hline \texttt{ :h filename-modifiers } & Help \\ \texttt{ :w \% } & Write to current file name \\ \texttt{ :w \%:r.cfm } & Change file extention to .cfm \\ \texttt{ :!echo \%:p } & Full path \& file name \\ \texttt{ :!echo \%:p:h } & Full path only \\ \texttt{ :!echo \%:t } & Filename only \\ \texttt{ :reg \% } & Display filename \\ \texttt{ $<$control-R$>$\% } & Insert filename (insert mode) \\ \texttt{ "\%p } & Insert filename (normal mode) \\ \texttt{ /$<$control-R$>$\% } & Search for file name in text \\ \texttt{ :!echo \%:gs/A/a/ } & Show current filename with all 'A' as 'a' \\ \texttt{ :!echo \%:s/A/a/ } & Only substitute the 1st occurance \\ \texttt{ :lcd \%:p:h } & Change to directory of current file \\ \hline \end{tabular} \end{center} \emph{ Display the full path and filename without the filename extension } \begin{lstlisting} :!echo %:r \end{lstlisting} \section{Tips} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ miscellaneous useful tips }} \\ \hline \texttt{ \% } & Jump to the matching brackets '$\{$$\}$[]()' \\ \texttt{ . } & Repeat last modification \\ \texttt{ @: } & Repeat last : command (then @@) \\ \texttt{ matchit.vim } & \% now matches tags $<$tr$>$$<$td$>$$<$script$>$ $<$?php etc \\ \hline \end{tabular} \end{center} .. :syntax on - colour syntax in Perl,HTML,PHP etc .. :set syntax=perl - force syntax (usually taken from file extension) .. :h regexp$<$C-D$>$ - type control-D and get a list all help topics containing \section{Patterns Or Regular Expressions} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ pattern jargon }} \\ \hline \hline \end{tabular} \end{center} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{greedy}] This means whether the pattern will try to match the biggest possible chunk of text, or the smallest (non-greedy) \item[\url{back-reference}] a reference to a bit of text which was matched by a pattern eg: /\textbackslash (.\textbackslash )/\textbackslash 1/ A back reference requires a 'grouping' to work \item[\url{regular}] expression A pattern which can be used to match some chunk of text. \end{description} \emph{ See a long description of patterns usable in vim } \begin{lstlisting} :help pattern \end{lstlisting} \emph{ Find '+3354.43' and replace at the end of a line } \begin{lstlisting} :%s/+\(\d\|\.\)*$//gc ~(looks for a '+' followed by digits or a '.') \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ special character classes for vim patterns }} \\ \hline \texttt{ \textbackslash s } & Whitespace character: $<$Space$>$ and $<$Tab$>$ \\ \texttt{ \textbackslash S } & Non-whitespace character; opposite of \textbackslash s \\ \texttt{ \textbackslash d } & Digit: eg [0-9] \\ \texttt{ \textbackslash D } & Non-digit: eg [\^{}0-9] \\ \texttt{ \textbackslash x } & Hex digit: eg [0-9A-Fa-f] \\ \texttt{ \textbackslash X } & Non-hex digit: eg [\^{}0-9A-Fa-f] \\ \texttt{ \textbackslash o } & Octal digit: eg \\ \texttt{ \textbackslash O } & Non-octal digit: eg [\^{}0-7] \\ \texttt{ \textbackslash w } & Word character: eg [0-9A-Za-z\_] \\ \texttt{ \textbackslash W } & Non-word character: eg [\^{}0-9A-Za-z\_] \\ \texttt{ \textbackslash h } & Head of word character: eg [A-Za-z\_] \\ \texttt{ \textbackslash H } & Non-head of word character: eg [\^{}A-Za-z\_] \\ \texttt{ \textbackslash a } & Alphabetic character: eg [A-Za-z] \\ \texttt{ \textbackslash A } & Non-alphabetic character: eg [\^{}A-Za-z] \\ \texttt{ \textbackslash l } & Lowercase character: eg [a-z] \\ \texttt{ \textbackslash L } & Non-lowercase character: eg [\^{}a-z] \\ \texttt{ \textbackslash u } & Uppercase character: eg [A-Z] \\ \texttt{ \textbackslash U } & Non-uppercase character: eg [\^{}A-Z] \\ \texttt{ \textbackslash i } & Identifier character (see 'isident' option) \\ \texttt{ \textbackslash I } & Like ``\textbackslash i'', but excluding digits \\ \texttt{ \textbackslash k } & Keyword character (see 'iskeyword' option) \\ \texttt{ \textbackslash K } & Like ``\textbackslash k'', but excluding digits \\ \texttt{ \textbackslash f } & File name character (see 'isfname' option) \\ \texttt{ \textbackslash F } & Like ``\textbackslash f'', but excluding digits \\ \texttt{ \textbackslash p } & Printable character (see 'isprint' option) \\ \texttt{ \textbackslash P } & Like ``\textbackslash p'', but excluding digits \\ \texttt{ \textbackslash \_x } & Where x is any of the above character classes with end-of-line included \\ \hline \end{tabular} \end{center} These character classes above dont work within [...] character classes. For example the search '/[ab\textbackslash s]/' will not work as you might hope. Using a character class such as '\textbackslash a' for an alphabetc character may be better than using the character class '[A-Za-z] because the \textbackslash w class may also handle international word characters, such as n tilde (the spanish enye) for example. \emph{ Using '\textbackslash v' (meaning 'very magic') usually reduces backslashing } \begin{lstlisting} /codes\(\n\|\s\)*where ~(without the '\v' flag) \end{lstlisting} \begin{lstlisting} /\vcodes(\n|\s)*where ~(with the 'very magic' \v flag) \end{lstlisting} \section{Ex Commands} Ex commands are derived from an ancient text editor known as 'ed' or 'ex'. These commands are usually written after a ':' colon. These commands are often overlooked when using 'vim' but in some circumstances have a zen-like power to achieve low-keystroke edits. These ex and ed commands are well explained in the classic unix treatise 'The Unix Programming Environment' by Kernighan et al. \emph{ Show a help listing of all vim ex commands } \begin{lstlisting} help holy-grail \end{lstlisting} \begin{lstlisting} help ex-cmd-index \end{lstlisting} \emph{ Show help about the ex 'p' (print) command } \begin{lstlisting} :help :p \end{lstlisting} \emph{ Show every line in the file which begins with a hash '\#' } \begin{lstlisting} :g/^\s*#/p ~(the lines are displayed one screen at a time) \end{lstlisting} \emph{ View the whole file with unprintable characters made visible } \begin{lstlisting} :%l ~(good for seeing pesky tab characters) \end{lstlisting} \emph{ View all blank lines with the invisible characters visible } \begin{lstlisting} :g/^\s*$/l \end{lstlisting} \emph{ Compress consecutive blank lines } \begin{lstlisting} :g/^\s*$/,/\S/-j|s/.*// \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ simple ex commands }} \\ \hline \texttt{ m } & Move text \\ \texttt{ d } & Delete text \\ \texttt{ $>$ } & Shift one shiftwidth to the right \\ \texttt{ $<$ } & Shift text one shift-width to the left \\ \texttt{ co } & Copy text \\ \texttt{ p } & Print (the file is unchanged) \\ \texttt{ l } & Print text with invisible characters made visible \\ \texttt{ a } & Append text \\ \texttt{ i } & Insert text \\ \hline \end{tabular} \end{center} \subsection{Inserting Text With Ex} \emph{ Insert the word 'tree' after the next line starting with a '\#' } \begin{lstlisting} :/^ *#/atree. ~(but doesnt work as a command) \end{lstlisting} \subsection{Moving Text With Ex} \emph{ Move the current line to line 100 (inserting not overwriting) } \begin{lstlisting} :m100 \end{lstlisting} \emph{ Move the current line to the bottom of the file } \begin{lstlisting} :m$ \end{lstlisting} \begin{lstlisting} :.m$ ~(the same) \end{lstlisting} \emph{ Move the line number 315 to the top of the file } \begin{lstlisting} :315m0 \end{lstlisting} \emph{ Move lines 316 to 330 inclusive to line 10 } \begin{lstlisting} :316,330m10 ~(this inserts the lines at line 10, not overwrites) \end{lstlisting} \emph{ Move all lines which begin with 'doc' to the bottom of the file } \begin{lstlisting} :g/^\s*doc/m$ \end{lstlisting} \emph{ Move the next line which starts with a '\#' to the end of the file } \begin{lstlisting} :/^\s*#/m$ \end{lstlisting} \subsection{Deleting With Ex} \emph{ Delete all lines which start with '\#' (which are script comments) } \begin{lstlisting} :g/^\s*#/d \end{lstlisting} \emph{ Delete all empty lines from a file with vim } \begin{lstlisting} :g!/\S/d \end{lstlisting} \emph{ Delete all lines from the current line to the end of the file } \begin{lstlisting} :.,$d \end{lstlisting} \emph{ Delete the next 10 lines after the current line } \begin{lstlisting} :.,+10d \end{lstlisting} \emph{ Delete lines not containing 'blue' } \begin{lstlisting} :g!/blue/d \end{lstlisting} \begin{lstlisting} :v/blue/d ~(the same) \end{lstlisting} \emph{ Delete between lines with 'joe' and 'fred' } \begin{lstlisting} :g/joe/,/fred/d \end{lstlisting} \subsection{Copying With Ex} \emph{ Copy and insert the current line 4 lines below the current line } \begin{lstlisting} :co+3 \end{lstlisting} \begin{lstlisting} :.co+3 ~(the same) \end{lstlisting} \emph{ Copy all lines from the current to the next blank line to line 10 } \begin{lstlisting} :.,/^\s*$/co10 ~(the copied lines are inserted, not overwritten) \end{lstlisting} \emph{ Copy all lines from the current to the end of the file into the clipboard } \begin{lstlisting} :,$y \end{lstlisting} \begin{lstlisting} :.,$y ~(the same) \end{lstlisting} \begin{lstlisting} :.,$ya ~(the same) \end{lstlisting} \begin{lstlisting} :.,$yank ~(the same again) \end{lstlisting} \emph{ Paste the contents of the clipboard after line 100 } \begin{lstlisting} :100pu \end{lstlisting} \emph{ Insert the contents of the clipboard after every line starting with * } \begin{lstlisting} :g/^\s*\*/pu \end{lstlisting} \subsection{Reformatting Lines With Ex} \emph{ On all lines beginning with '$>$$>$' join the next line to it } \begin{lstlisting} :g/^\s*>>/j \end{lstlisting} \emph{ Shift one 'shiftwidth' to the right all lines not starting with a '\#' } \begin{lstlisting} :g!/^\s*#/> \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ examples of ex line addresses and ranges }} \\ \hline \texttt{ 123 } & Line number 123 \\ \texttt{ /doc } & The next line containing the pattern 'doc' \\ \texttt{ . } & The current line \\ \texttt{ ?pat } & Previous with pat \\ \texttt{ \$ } & The last line of the file \\ \texttt{ .-10 } & Ten lines before the current line \\ \texttt{ + } & The line after the current line \\ \texttt{ 123,234 } & From line 123 to line 234 \\ \texttt{ } & , the line before the current line \\ \texttt{ 'x } & Marked with x \\ \texttt{ +n } & N forward \\ \texttt{ '' } & Previous context \\ \texttt{ \% } & All lines in the file \\ \hline \end{tabular} \end{center} \emph{ Move all comments the top of the file in vim } \begin{lstlisting} :g:^\s*#.*:m0 \end{lstlisting} \begin{lstlisting} :g/^\s*#.*/m0 ~(the same) \end{lstlisting} \begin{lstlisting} :g/^[:space:]*#.*/m0 ~(also the same) \end{lstlisting} \subsection{The Ex Global Command} The ex global 'g' command is very powerful, but the syntax may be a little tricky to master \emph{ Move all lines starting with a 't' to the end of the file } \begin{lstlisting} :g/^\s*t.*/m$ \end{lstlisting} \emph{ Replace 't' with 'T' and 'i' with 'I' on lines containing '$<$this$>$' } \begin{lstlisting} :g//s/t/T/g | s/i/I/g \end{lstlisting} \emph{ On lines containing 'ball' sub 'ball' with 'tall' confirming each change } \begin{lstlisting} :g/ball/s//tall/gic \end{lstlisting} The only problem with this technique above is that it is difficult to quit from the process, since the 'g' command acts like a loop. For making changes with confirmation, it is better to use a simple ':s/a/A/gic' command, which allows the user to terminate the replacement process without completing it. \emph{ Between bookmarks 'a' and 'b' sub 'eg' with 'ex' on lines with 'tree' } \begin{lstlisting} :'a,'bg/tree/s/eg/ex/gic \end{lstlisting} \emph{ Global combined with substitute (power editing) } \begin{lstlisting} :/fred/,/joe/s/fred/joe/gic : non-line based (ultra) \end{lstlisting} \begin{lstlisting} :/biz/,/any/g/article/s/wheel/bucket/gic: non-line based \end{lstlisting} \emph{ Find fred before beginning search for joe } \begin{lstlisting} :/fred/;/joe/-2,/sid/+3s/sally/alley/gIC \end{lstlisting} \emph{ Create a new file for each line of file eg 1.txt,2.txt,3,txt etc } \begin{lstlisting} :g/^/exe ".w ".line(".").".txt" \end{lstlisting} \emph{ Append all lines containing 'tree' to register a } \begin{lstlisting} :g/tree/y A \end{lstlisting} \begin{lstlisting} :g/tree/y A | :let @*=@a ~(put into paste buffer) \end{lstlisting} \emph{ Save results to a register/paste buffer } \begin{lstlisting} :let @a=''|g/Barratt/y A |:let @*=@a \end{lstlisting} \emph{ Filter lines between bookmarks to a file (file must already exist) } \begin{lstlisting} :'a,'bg/^Error/ . w >> errors.txt \end{lstlisting} \emph{ Duplicate every line in a file. wrap a print '' around each duplicate } \begin{lstlisting} :g/./yank|put|-1s/'/"/g|s/.*/Print '&'/ \end{lstlisting} \emph{ Replace the text '$<$x$>$' with contents of a file, -d deletes the ``mark'' } \begin{lstlisting} :g/^$/r tmp.txt | -d \end{lstlisting} \emph{ Display something prettily {\footnotesize ?? } } \begin{lstlisting} :g//z#.5 : display with context \end{lstlisting} \begin{lstlisting} :g//z#.5|echo "==========" : display beautifully \end{lstlisting} \emph{ Perform a substitute on every second line } \begin{lstlisting} :g/^/ if line('.')%2|s/^/zz / \end{lstlisting} \emph{ Send output of previous global command to a new window } \begin{lstlisting} :nmap :redir @a:g//:redir END:new:put! a \end{lstlisting} \emph{ Match all lines containing ``somestr'' between markers a \& b } \emph{ Copy after line containing ``otherstr'' } \begin{lstlisting} :'a,'bg/somestr/co/otherstr/ ~(co[py] or mo[ve]) \end{lstlisting} \emph{ Match lines as above but also do a substitution } \begin{lstlisting} :'a,'bg/str1/s/str1/&&&/|mo/str2/ \end{lstlisting} \begin{lstlisting} :%norm jdd ~(delete every other line) \end{lstlisting} \emph{ Call a user defined fuction 'Del' for every line of the document } \begin{lstlisting} :g/^/ call Del() \end{lstlisting} \emph{ Use a bash command as part of vim command chain } \begin{lstlisting} :.g/^/ exe ".!sed 's/N/X/'" | s/I/Q/ \end{lstlisting} \emph{ Replace 2nd '|' bar character with a star } \begin{lstlisting} :g/|/norm 2f|r* \end{lstlisting} The command above combines a 'g' global command with the normal mode command '2f|r*' which search forward for the 2nd occurance of the '|' character and replaces it with a '*' asterisc. The 'norm' or 'normal' command is useful for changing from 'command mode' to 'normal mode' \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ more g (global) commands }} \\ \hline \texttt{ :g/gladiolli/\# } & Display matching lines with line numbers \\ \texttt{ :g/fred.*joe.*bob/ } & Display all lines with fred, joe \& bob \\ \texttt{ :g/\$<$fred\$>$/ } & Display all lines with fred but not freddy \\ \texttt{ :g/\^{}\textbackslash s*\$/d } & Delete all empty (blank) lines \\ \texttt{ :g/fred/,/joe/j } & Join Lines between 'fred' and 'joe' \\ \texttt{ :g/-------/.-10,.d } & Delete string \& 10 previous lines \\ \texttt{ :g/$\{$/ ,/$\}$/- s/\textbackslash n\textbackslash +/\textbackslash r/g } & Delete empty lines but only between $\{$...$\}$ \\ \texttt{ :v/\textbackslash S/d } & Delete empty lines (and blank lines having only whitespace) \\ \texttt{ :v/./,/./-j } & Compress empty lines \\ \texttt{ :g/\^{}\$/,/./-j } & Compress empty lines \\ \texttt{ :g/$<$input\textbackslash |$<$form/p } & Print line having either '$<$input' or '$<$form' \\ \texttt{ :g/\^{}/put\_ } & Double space file (pu = put) \\ \texttt{ :g/\^{}/m0 } & Reverse the lines of a file \\ \texttt{ :g/\^{}/m\$ } & The command has no effect! \\ \texttt{ :'a,'bg/\^{}/m'b } & Reverse the lines between bookmarks 'a' and 'b' \\ \texttt{ :g/\^{}/t. } & Duplicate every line \\ \texttt{ :g/fred/t\$ } & Copy (transfer) lines matching fred to the end of the file \\ \texttt{ :g/stage/t'a } & Copy lines matching stage to marker 'a' (cannot use .) \\ \texttt{ :g/\^{}Chapter/t.|s/./-/g } & Automatically underline selecting headings \\ \texttt{ :g/\textbackslash (\^{}I[\^{}\^{}I]*\textbackslash )\textbackslash $\{$80$\}$/d } & Delete all lines containing at least 80 tabs \\ \hline \end{tabular} \end{center} \emph{ A command to open the file under the cursor, creating it if necessary } \begin{lstlisting} :nnoremap gF :view \end{lstlisting} \emph{ 'rot13' encrypt the entire document (this toggles) } \begin{lstlisting} ggVGg? \end{lstlisting} \emph{ Reverse the order of all the lines in the document (toggles) } \begin{lstlisting} :g/^/m0 \end{lstlisting} \subsection{The Ex Command History} When you type a ':' character in 'normal' mode you enter 'command' or 'ex' mode. This is where you type commands after the colon at the bottom of the document window. It is possible to use vim itself to edit these commands \emph{ Get help for editing command lines with vim } \begin{lstlisting} help q: \end{lstlisting} \emph{ Choose a command line to edit and execute with vim } \begin{lstlisting} q: ~(press enter to execute the edited command, or ':q' to exit) \end{lstlisting} \emph{ Write all the commands in the history to file } \begin{lstlisting} ?? how \end{lstlisting} \emph{ Edit the current or a previous command using vim in another window } \begin{lstlisting} :blah [control] f \end{lstlisting} \emph{ Paste the default buffer into the command line (in command mode) } \begin{lstlisting} :[control] r " \end{lstlisting} \emph{ Retrieve the last command line command for copy \& pasting into text } \begin{lstlisting} i [control] r: \end{lstlisting} \emph{ Retrieve the last search command for copy \& pasting into text } \begin{lstlisting} i [control] r/ \end{lstlisting} \emph{ Choose a previous search to edit and/or execute } \begin{lstlisting} q/ \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ some ex command history commands }} \\ \hline \texttt{ :ju(mps) } & List of your movements \\ \texttt{ :help jump-motions } \\ \texttt{ :history } & List of all your commands \\ \texttt{ :his c } & Commandline history \\ \texttt{ :his s } & Search history \\ \texttt{ q/ } & Search history Window (puts you in full edit mode) (exit CTRL-C) \\ \texttt{ q: } & Commandline history Window (to full edit mode) (exit CTRL-C) \\ \texttt{ :$<$C-F$>$ } & History Window (exit CTRL-C) \\ \hline \end{tabular} \end{center} \subsection{Pasting From The Document To The Ex Line} \emph{ Map ',c' to paste the current document line into the command line } \begin{lstlisting} :nmap ,c yy:" \end{lstlisting} \begin{lstlisting} :nmap ,c "byy:b ~(the same, but a bit better) \end{lstlisting} \emph{ Paste an altered version of the current line to the vim command line } \begin{lstlisting} :nmap ,d :s/^ *>> *//"ayyu:a \end{lstlisting} In the example above, if the current line (the line where the cursor is) was ``$>$$>$ ls'', then the command ',d' would paste the text 'ls' into the vim command line, so at the bottom of the vim screen would appear ':ls' which could then be executed by hitting the \Enter key. \emph{ Remove leading spaces and '$>$$>$' characters from beginning of default reg } \begin{lstlisting} :let @" = substitute(@",'^[ ]*>>','','') \end{lstlisting} \emph{ Strip '\#' from the front of the current line and put in the 'a' reg } \begin{lstlisting} :let @a = substitute(getline("."),'^[ ]*#','','') \end{lstlisting} \emph{ Paste the word under the cursor into the ':ex' line (command line) } \begin{lstlisting} : \end{lstlisting} \section{Searching For Text} \emph{ Search for the word 'big' (and move the cursor there) } \begin{lstlisting} /big \end{lstlisting} \begin{lstlisting} /big/ ~(the same, it seems) \end{lstlisting} \emph{ Delete all text until the next occurrence of the text 'big' } \begin{lstlisting} d/big \end{lstlisting} \emph{ Repeat the last search } \begin{lstlisting} n \end{lstlisting} \emph{ Repeat the last search in the opposite direction } \begin{lstlisting} N \end{lstlisting} \emph{ Find joe followed by fred followed by bill } \begin{lstlisting} /joe.*fred.*bill/ \end{lstlisting} \emph{ Find 'begin' followd by 'end' possibly over multiple lines } \begin{lstlisting} /begin\_.*end \end{lstlisting} \emph{ Search for 'start' followed by 'end' separated by spaces or lines } \begin{lstlisting} /fred\_s*joe/ \end{lstlisting} \emph{ Search for either of the words 'blue' or 'green' and move the cursor } \begin{lstlisting} /blue\|green \end{lstlisting} \emph{ Search for 'fred' but not 'alfred' or 'frederick' } \begin{lstlisting} /\/ \end{lstlisting} \emph{ Search numbers having only 4 digits } \begin{lstlisting} /\<\d\d\d\d\> \end{lstlisting} \begin{lstlisting} /\<\d\{4}\> ~(this is the same) \end{lstlisting} \begin{lstlisting} /\D\d\d\d\d\D ~(the same again) \end{lstlisting} \emph{ Search for 'fred' and 'joe' in any order } \begin{lstlisting} /.*fred\&.*joe \end{lstlisting} \emph{ Search for lines beginning with the capital letters 'A' to 'J' } \begin{lstlisting} /^[A-J]/ \end{lstlisting} \emph{ Search for absence of a digit or beginning of line ?? } \begin{lstlisting} /\([^0-9]\|^\)%.*% \end{lstlisting} \emph{ Show lines matching word under cursor } \begin{lstlisting} [I \end{lstlisting} \emph{ Search for contents of tags, ignoring ``chevrons'' } \begin{lstlisting} /<\zs[^>]*\ze> \end{lstlisting} \emph{ Get help for the '\textbackslash zs' and '\textbackslash ze' regular expression pattern } \begin{lstlisting} :h /\zs \end{lstlisting} \begin{lstlisting} :h /\ze \end{lstlisting} \subsection{Search Completion} \emph{ Pull current word onto search/command line } \begin{lstlisting} / \end{lstlisting} In this context a 'word' means letters surrounded by spaces or by punctuation. For example if the cursor is over the text '.config a' the keystrokes above will pull the word 'config' into the search bar. \emph{ Pull current text chunk (word) onto search/command line } \begin{lstlisting} / \end{lstlisting} A text chunk is any piece of text surrounded by spaces, the same as $<$cWORD$>$ \subsection{Configuring Searches} \emph{ Ignore the 'cases' of letters in searches } \begin{lstlisting} :set ignorecase \end{lstlisting} \emph{ Jump to the searched-for-word as you type (annoying but excellent) } \begin{lstlisting} :set incsearch \end{lstlisting} \emph{ Overrides 'ignorecase' if uppercase used in search string } \begin{lstlisting} :set smartcase \end{lstlisting} \subsection{Multiline Searches} At times it is necessary to search for text which spans a number of lines in the document. The following commands show ways to do this. \emph{ Search for 'sea' followed by 'salt' over multiple lines } \begin{lstlisting} /see\_s*salt/ \end{lstlisting} \emph{ View help for muli-line search patterns } \begin{lstlisting} :h \_ \end{lstlisting} \emph{ 'bugs' followed by 'bunny' anywhere in file } \begin{lstlisting} /bugs\(\_.\)*bunny \end{lstlisting} \emph{ Search for multiple-line html comments } \begin{lstlisting} / \end{lstlisting} \subsection{Repeating Searches} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Summary of repeated searches }} \\ \hline \texttt{ ; } & F, t, F or T \\ \texttt{ , } & F, t, F or T in opposite direction \\ \texttt{ n } & Last / or ? search \\ \texttt{ N } & Last / or ? search in opposite direction \\ \hline \end{tabular} \end{center} \emph{ Match word boundaries } \begin{lstlisting} /\/ ~(matches 'all' but not 'balls') \end{lstlisting} \emph{ Find the next, previous word under the cursor } \emph{ Find the next word under the cursor } \begin{lstlisting} * g* \end{lstlisting} \emph{ Find the previous word under the cursor } \begin{lstlisting} # g# \end{lstlisting} \emph{ Find word under cursor ($<$cword$>$) (forwards/backwards) } \begin{lstlisting} * # g* g# - \end{lstlisting} \emph{ Make all searches case insensitive } \begin{lstlisting} :set ignorecase \end{lstlisting} \begin{lstlisting} :set ic ~(the same) \end{lstlisting} (this affects substitutions with s/// as well as searches) \emph{ Make all searches case sensitive (the default) } \begin{lstlisting} :set noignorecase \end{lstlisting} \emph{ VIM has an its own 'grep' command (different from the bash one) } \begin{lstlisting} :grep some_keyword *.c ~(get list of all c-files containing keyword) \end{lstlisting} \begin{lstlisting} :cn ~(go to next occurrence) \end{lstlisting} \emph{ Search through multiple files } \begin{lstlisting} :bufdo /searchstr/ ~( use :rewind to recommence search ) \end{lstlisting} \emph{ Multiple file search better but cheating } \begin{lstlisting} :bufdo %s/searchstr/&/gic ~( say n and then a to stop) \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ finding empty lines }} \\ \hline \texttt{ /\^{}\textbackslash n\textbackslash $\{$3$\}$ } & Find 3 empty lines \\ \texttt{ /\^{}str.*\textbackslash nstr } & Find 2 successive lines starting with str \\ \texttt{ /\textbackslash (\^{}str.*\textbackslash n\textbackslash )\textbackslash $\{$2$\}$ } & Find 2 successive lines starting with str \\ \hline \end{tabular} \end{center} \emph{ Using regular expression back references in a search } \begin{lstlisting} /\(fred\).*\(joe\).*\2.*\1 \end{lstlisting} The above will find 'fred and joe. fred \& joe' for example \emph{ Repeating the Regexp (rather than what the Regexp finds) } \begin{lstlisting} /^\([^,]*,\)\{8} \end{lstlisting} \emph{ How to search for a URL without backslashing } \begin{lstlisting} ?http://www.vim.org/ ~( (first) search BACKWARDS \end{lstlisting} \emph{ Specify what you are NOT searching for (vowels) } \begin{lstlisting} /\c\v([^aeiou]&\a){4} ~( search for 4 consecutive consonants) \end{lstlisting} \begin{lstlisting} /\%>20l\%<30lgoat ~( Search for goat between lines 20 and 30) \end{lstlisting} \begin{lstlisting} /^.\{-}home.\{-}\zshome/e ~( match only the 2nd occurence in a line of "home" *) \end{lstlisting} \begin{lstlisting} :%s/home.\{-}\zshome/alone ~( Substitute only the occurrence of home in any line) \end{lstlisting} \emph{ Find str but not on lines containing tree } \begin{lstlisting} ^\(.*tree.*\)\@!.*nose.*$ \end{lstlisting} \begin{lstlisting} \v^((tree)@!.)*nose((tongue)@!.)*$ \end{lstlisting} \begin{lstlisting} .*nose.*\&^\%(\%(tree\)\@!.\)*$ \end{lstlisting} \begin{lstlisting} :v/tongue/s/nose/&/gic \end{lstlisting} \subsection{Searching Multiple Files} Vim includes its own 'grep' (search) command, which may be of particular use on Microsoft windows were there is no built in grep command \emph{ Using vimgrep with copen } \begin{lstlisting} :vimgrep /keywords/ *.php \end{lstlisting} \begin{lstlisting} :copen \end{lstlisting} \emph{ Use argdo to search multiple files } \begin{lstlisting} :argdo /hello/ ~(?? unchecked) \end{lstlisting} \emph{ View what program will be used to execute a 'grep' search on this compu. } \begin{lstlisting} :set grepprg \end{lstlisting} \emph{ Gvim's use of external grep (win32 or *nix) } : creates a list of all matching files \emph{ Display a list of all '.php' files which contain the text 'ocean' } \begin{lstlisting} :grep ocean *.php \end{lstlisting} \emph{ Use :cn(ext) :cp(rev) to navigate list } \begin{lstlisting} :h grep \end{lstlisting} \subsection{Advanced Searches} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ zero-width searches }} \\ \hline \texttt{ :h /\textbackslash @= } & Get help \\ \texttt{ /$<$\textbackslash @$<$=[\^{}$>$]*$>$\textbackslash @= } & Search for tag contents, ignoring chevrons \\ \texttt{ /$<$\textbackslash @$<$=\textbackslash \_[\^{}$>$]*$>$\textbackslash @= } & Search for tags across possible multiple lines \\ \hline \end{tabular} \end{center} \subsection{Search Commands} \emph{ A command to display lines containing some text in a new window } \begin{lstlisting} com! -nargs=1 Show !sed -rn '//p' % | zenity --list --column= \end{lstlisting} \emph{ Display matching lines in a new window, with case-insensitive search } \begin{lstlisting} com! -nargs=1 Show !grep -i '' % | zenity --width=600 --height=600 --list --column= \end{lstlisting} \emph{ Display lines having 'tree' in a window, with case-insensitive search } \begin{lstlisting} :!grep -i 'tree' % | zenity --width=600 --height=600 --list --column= \end{lstlisting} \emph{ Display lines having 'tree', insert the selected line in the document } \begin{lstlisting} :r !grep -i 'tree' % | zenity --width=600 --height=600 --list --column= \end{lstlisting} \emph{ Display all uppercase lines and insert the selected line } \begin{lstlisting} :r !grep '^ *[A-Z][A-Z][^a-z]*$' % | zenity --width=600 --height=600 --list --column= \end{lstlisting} \section{Search And Replace} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ substitution }} \\ \hline \texttt{ :\%s/fred/joe/igc } & General substitute command with confirmation \\ \texttt{ :\%s//joe/igc } & Substitute what you last searched for \\ \texttt{ :\%s/$\sim$/sue/igc } & Substitute your last replacement string \\ \hline \end{tabular} \end{center} \emph{ See a long description of patterns usable with s/// } \begin{lstlisting} :help pattern \end{lstlisting} Before doing a search and replace on an important file it is a good idea to use the 'c' modifier to the 's' command, to check what changes will be made \begin{lstlisting} :%s/\s\+$//gc ~(remove trailing spaces, with confirmation each time) \end{lstlisting} \begin{lstlisting} :%s/\s\+$//g ~(remove trailing whitespace, no confirmation) \end{lstlisting} \emph{ Replace the word tall with small in the file, asking for confirmation } \begin{lstlisting} :%s/\/small/gc ~(this will replace 'tall' but not 'stall' etc) \end{lstlisting} \begin{lstlisting} :%s/\/small/g ~(the same but with no confirmation prompt) \end{lstlisting} \emph{ Multiple commands on one line } \begin{lstlisting} :%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/ \end{lstlisting} \begin{lstlisting} :%s/a/but/gie|:update|:next ~(then use @: to repeat) \end{lstlisting} \emph{ Remove trailing whitespace on every line } \begin{lstlisting} :%s/\s\+*$//g \end{lstlisting} \begin{lstlisting} :1,$s/\s\+*$//g ~(the same) \end{lstlisting} \begin{lstlisting} :1,$s/[[:space:]]\+*$//g ~(the same again) \end{lstlisting} \begin{lstlisting} :1,$s/[[:blank:]]\+*$//g ~(almost the same again) \end{lstlisting} \emph{ Turn DOS \^{}M line breaks into real line breaks } \begin{lstlisting} :%s/\r/\r/g \end{lstlisting} \begin{lstlisting} :%s/\r//g ~( Delete MS DOS line ending (^M)) \end{lstlisting} \emph{ Replace all colon ':' characters with semicolons ';' } \begin{lstlisting} :%s,:,;,g ~(this shows that any char can be used as the delimiter) \end{lstlisting} \begin{lstlisting} :%s/:/;/g ~(the same) \end{lstlisting} \emph{ Delete all empty lines from a file with vim } \begin{lstlisting} :g!/\S/d \end{lstlisting} \emph{ Make multiple consecutive blank lines into only one } \begin{lstlisting} :g/^\s*$/,/\S/-j|s/.*// \end{lstlisting} \emph{ Insert the line number at the beginning of each line } \begin{lstlisting} :%s/^/\=line('.').' ' \end{lstlisting} \emph{ Move all comments the top of the file in vim } \begin{lstlisting} :g:^\s*#.*:m0 \end{lstlisting} \begin{lstlisting} :g/^\s*#.*/m0 ~(the same) \end{lstlisting} \emph{ Get rid of tab characters in the whole file } \begin{lstlisting} :%! expand \end{lstlisting} \emph{ Replace all slash '/' characters with bar '|' characters } \begin{lstlisting} :%s@/@|@g \end{lstlisting} \emph{ Memory } \begin{lstlisting} :%s#.*\(tbl_\w\+\).*#\1# ~( produce a list of all strings tbl_*) \end{lstlisting} \begin{lstlisting} :s/\(.*\):\(.*\)/\2 : \1/ ~( reverse fields separated by :) \end{lstlisting} \begin{lstlisting} :%s/^\(.*\)\n\1$/\1/ ~( delete duplicate lines) \end{lstlisting} \emph{ Non-greedy matching \textbackslash $\{$-$\}$ } \begin{lstlisting} :%s/^.\{-}pdf/new.pdf/ ~( delete to 1st pdf only) \end{lstlisting} \emph{ Use of optional atom \textbackslash ? } \begin{lstlisting} :%s#\<[zy]\?tbl_[a-z_]\+\>#\L&#gc ~( lowercase with optional leading characters) \end{lstlisting} \emph{ Search for alternate patterns 'goat' or 'cow' and replace with 'sheep' } \begin{lstlisting} :%s/goat\|cow/sheep/gc \end{lstlisting} \emph{ Insert a blank line every 5 lines } \begin{lstlisting} :%s/\v(.*\n){5}/&\r/ ~(???) \end{lstlisting} \subsection{Search And Delete} \emph{ Delete all lines which contain the text 'big' } \begin{lstlisting} :g/big/d \end{lstlisting} \begin{lstlisting} :g/RE/cmd ~(the general form of the command) \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ deleting empty lines }} \\ \hline \texttt{ :\%s/\^{}\textbackslash n\textbackslash $\{$3$\}$// } & Delete blocks of 3 empty lines \\ \texttt{ :\%s/\^{}\textbackslash n\textbackslash +/\textbackslash r/ } & Compressing empty lines \\ \texttt{ :\%s\#.*\textbackslash (\textbackslash d\textbackslash +hours\textbackslash ).*\#\textbackslash 1\# } & Delete all but memorised string (\textbackslash 1) \\ \hline \end{tabular} \end{center} \subsection{Advanced Search And Replace} \emph{ Using a vim function within a substitution } \begin{lstlisting} :s//\=strftime("%c")/ ~(insert a date instead of ) \end{lstlisting} \emph{ Substitute between 2 bookmarks only on lines with 'fred' in them } \begin{lstlisting} :'a,'bg/fred/s/dick/joe/ \end{lstlisting} \emph{ Get help for the 'non-greedy' operator for patterns } \begin{lstlisting} :help /\{-} \end{lstlisting} \emph{ Substitute using a register } \begin{lstlisting} :s/fred/asome_texts/g \end{lstlisting} \begin{lstlisting} :s/fred/\=@a/g ~( better alternative as register not displayed) \end{lstlisting} \emph{ Substitute ``fred'' with contents of register "a" } \begin{lstlisting} :s/fred/a/g \end{lstlisting} \emph{ Substitute singular or plural between 2 bookmarks } \begin{lstlisting} :'a,'bs/bucket\(s\)*/bowl\1/gic \end{lstlisting} \emph{ Swap 'off' for 'on' and vice-versa } \begin{lstlisting} :%s/\<\(on\|off\)\>/\=strpart("offon", 3 * ("off"==submatch(0)), 3)/g \end{lstlisting} \emph{ Swap two words } \begin{lstlisting} :vnoremap `.``gvP``P \end{lstlisting} \emph{ Swap word with next word } \begin{lstlisting} nmap gw "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/ \end{lstlisting} \emph{ Break lines at 70 chars, if possible after a ; } \begin{lstlisting} :s/.\{,69\};\s*\|.\{,69\}\s\+/&\r/g \end{lstlisting} \emph{ Find replacement text, put in memory, use '\textbackslash zs' to simplify substitute } \begin{lstlisting} :%s/"\([^.]\+\).*\zsxx/\1/ \end{lstlisting} \emph{ All following performing similar task, substitute within substitution } \emph{ Multiple single character substitution in a portion of line only } \begin{lstlisting} :%s,\(all/.*\)\@<=/,_,g ~( replace all / with _ AFTER "all/") \end{lstlisting} \emph{ Same thing } \begin{lstlisting} :s#all/\zs.*#\=substitute(submatch(0), '/', '_', 'g')# \end{lstlisting} \emph{ Substitute by splitting line, then re-joining } \begin{lstlisting} :s#all/#&^M#|s#/#_#g|-j! \end{lstlisting} \emph{ Substitute inside another substitute } \begin{lstlisting} :%s/.*/\='cp '.submatch(0).' all/'.substitute(submatch(0),'/','_','g')/ \end{lstlisting} \subsection{Commands To Search And Replace} \emph{ A simple search and replace command with confirmation } \begin{lstlisting} :command! -nargs=1 Rp :% s//gc \end{lstlisting} \begin{lstlisting} :Rp this/that ~(this invokes the command) \end{lstlisting} \emph{ Pull word under cursor into LHS of a substitute } \begin{lstlisting} :nmap z :%s#\<=expand("")\># \end{lstlisting} \section{Using Cword And Cfile} \emph{ Map H to look up the word under the cursor with 'man' (like K used to) } \begin{lstlisting} nmap H :!man \end{lstlisting} \emph{ Display the filename which is under the cursor } \begin{lstlisting} :echo expand("") \end{lstlisting} If the cursor is currently over a piece of text which contains '[a:image/file.png]' then this will display 'image/file.png' \emph{ Display the space delimited 'word' (text chunk) under the cursor } \begin{lstlisting} :echo expand("") \end{lstlisting} It the cursor is over the word 'function' in some text such as 'the function(a,b) is' then the command above will display 'function(a,b)' \includegraphics[width=0.5\textwidth]{/usr/share/httpd/icons/bomb.png} \emph{ Open the filename under the cursor with the right program } \begin{lstlisting} :!xdg-open \end{lstlisting} \emph{ Open the filename under the cursor with the right program on OSX } \begin{lstlisting} :!open \end{lstlisting} \emph{ A mapping ',o' to open a file with the right program } \begin{lstlisting} :nmap ,o :!xdg-open \end{lstlisting} \emph{ Map ',o' to play an mp3 file under the cursor } \begin{lstlisting} :nmap ,o :!mpg321 \end{lstlisting} If this command above is to be put in the 'vimrc' file then it should not have the first colon ':'. This is different from the 'gf' built-in vim command, because 'gf' opens the file under the cursor for editing, but the above mapping will open the file with what ever program is appropriate for the file-type (so an image file will be opened with an image viewing program, etc) \emph{ A mapping that displays what word will looked up with 'man' } \begin{lstlisting} nmap H :!man =expand("") \end{lstlisting} \emph{ Make a mapping ',ee' to execute the current word as a bash command } \begin{lstlisting} :nmap ,ee :! \end{lstlisting} \begin{lstlisting} nmap ,ee :echo man =expand("") \end{lstlisting} \section{Uppercase And Lowercase} Warning: :s///... etc is affected by the setting of 'ignorecase' in the vim settings. Type ':set' and if 'ignorecase' appears the all searches and replaces are going to be case insensitive. \emph{ Turn off and on case insensitivity in searches with :s/// } \begin{lstlisting} :set ic \end{lstlisting} \begin{lstlisting} :set ignorecase ~(the same) \end{lstlisting} \begin{lstlisting} :set noic \end{lstlisting} \emph{ Show lines which contain only uppercase letters or spaces } \begin{lstlisting} g/^\(\u\| \)\+$/p \end{lstlisting} \emph{ Make all text in a file lowercase } \begin{lstlisting} :%s/[A-Z]/\L&/g ~(only works for 'ascii' text) \end{lstlisting} \begin{lstlisting} :%s/\a/\L&/g ~(the same, but should work for international text) \end{lstlisting} \emph{ Make all words 'capital case', that is with the first letter in uppercase } \begin{lstlisting} :%s/\<\a\+/\u&/gc ~(this turns 'hello you' into 'Hello You') \end{lstlisting} Note that \textbackslash u \textbackslash U \textbackslash l \textbackslash L have different meanings depending on context. In the right hand side of a s/// expression they mean ... \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ escape codes }} \\ \hline \texttt{ \textbackslash l } & Turn only the next character in the match to lower case \\ \texttt{ \textbackslash L } & Turn all the characters in the match to lower case \\ \texttt{ \textbackslash u } & Convert only the first character in the match to upper case \\ \texttt{ \textbackslash u } & Convert all the characters in the match to upper case \\ \hline \end{tabular} \end{center} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Changing The Case Of Text }} \\ \hline \texttt{ guu } & Make the current line lower-case \\ \texttt{ gUU } & Uppercase line \\ \texttt{ guap } & Make lowercase the current paragraph \\ \texttt{ Vu } & Make the current line lower-case with visual mode \\ \texttt{ VU } & Uppercase this line using visual mode \\ \texttt{ g$\sim$$\sim$ } & Flip case line \\ \texttt{ vEU } & Upper Case Word \\ \texttt{ vE$\sim$ } & Flip Case Word \\ \texttt{ ggguG } & Lowercase entire file \\ \hline \end{tabular} \end{center} \emph{ Make title case visually selected text (map for .vimrc) } \begin{lstlisting} vmap ,c :s/\<\(.\)\(\k*\)\>/\u\1\L\2/g \end{lstlisting} \emph{ Make the current line title case } \begin{lstlisting} nmap ,t :s/.*/\L&/:s/\<./\u&/g \end{lstlisting} \emph{ Uppercase first letter of sentences } \begin{lstlisting} :%s/[.!?]\_s\+\a/\U&\E/g \end{lstlisting} \section{Text Indentation} Vim has various options and commands for automatically indenting (that is adding spaces or tabs at the beginning of a line) as you type or for using with commands like 'gqap' (reformat a paragraph). In fact, there are so many indentation options, that one can sometimes become frustated when vim constantly indents lines in an unexpected way. \emph{ See the value of the current shift-width (used to in/decrease indentation) } \begin{lstlisting} :set sw \end{lstlisting} \begin{lstlisting} :set shiftwidth ~(the same) \end{lstlisting} \emph{ View help for the 'shiftwidth' configuration option } \begin{lstlisting} :help 'sw' \end{lstlisting} \emph{ Convert all tabs in a document to an equivalent number of spaces } \begin{lstlisting} :retab ~(this may change indentation) \end{lstlisting} \subsection{Automatic Indentation} \emph{ View help for the 'autoindent' configuration option } \begin{lstlisting} :help 'ai' \end{lstlisting} \emph{ Make the next line after the current line have the same indentation } \begin{lstlisting} :set ai ~(when you are typing, the next indent is 'aligned') \end{lstlisting} \begin{lstlisting} :set autoindent ~(the same) \end{lstlisting} \emph{ Make sure that vim uses spaces and not annoying tabs for indentations } \begin{lstlisting} :set expandtab \end{lstlisting} \begin{lstlisting} :set et ~(the same) \end{lstlisting} \emph{ Reformat a paragraph while preserving the current indentation of the text } \begin{lstlisting} :set ai [esc] gqap :set noai ~(or just leave 'autoindent' set to on) \end{lstlisting} (reformatting means making each line of a similar length) \emph{ Turn off automatic indentation of the next line when typing } \begin{lstlisting} :set noai \end{lstlisting} \subsection{Manual Indentation} \emph{ Increase the indentation for the current paragraph by one shift-width } \begin{lstlisting} >ap ~(you can repeat this operation by just typing .) \end{lstlisting} \emph{ Decrease the indentation for this paragraph and the next 3 paragraphs } \begin{lstlisting} <4ap ~(the indent is decreased by a 'shiftwidth') \end{lstlisting} \emph{ Decease the indentation by 1 shiftwidth for all lines above the current } \begin{lstlisting} > \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ some indentation options }} \\ \hline \texttt{ shiftwidth } & (sw) the number of tabs or spaces for an increase or decrease \\ \texttt{ cindent } & Automatically indent c code files \\ \texttt{ smartindent } & Automatically indent other types of files \\ \texttt{ autoindent } & Align the indent of the next line to the current \\ \texttt{ expandtab } & Use spaces not tabs for indentations \\ \hline \end{tabular} \end{center} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ indentation commands }} \\ \hline \texttt{ retab } & Replace all tabs in the file with an equivalent number of spaces \\ \texttt{ $>$$>$ } & Shift the current line \\ \texttt{ $>$ } & Shift a range of lines \\ \hline \end{tabular} \end{center} \emph{ Shifting text in visual mode (with built-in repeat) } \begin{lstlisting} :vnoremap < >gv \end{lstlisting} \emph{ Also } \begin{lstlisting} >% and <% \end{lstlisting} \subsection{My Favourite Settings And Tricks} This section contains recipes which are probably repeated elsewhere in this booklet, but which are my favourite settings and commands which have made vim considerably more enjoyable to use, at least for me. \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://bumble.sf.net/books/vim/vimrc.txt}] This contains an example .vimrc configuration file with a number of settings, commands and mappings which I have found useful. \end{description} \emph{ Make 'jj' or 'fj' do the same as the $<$esc$>$ key when in insert mode } \begin{lstlisting} :imap jj \end{lstlisting} \begin{lstlisting} :imap fj \end{lstlisting} \emph{ Make 'T' in normal mode swap between open files } \begin{lstlisting} nmap T :bn \end{lstlisting} If you actually want to type a 'jj' or 'fj' into your document then you have to do it slowly. \emph{ Set the shift-width to 1, with spaces not tabs, align next line below } \begin{lstlisting} :set shiftwidth=1 expandtab autoindent \end{lstlisting} \begin{lstlisting} :set sw=1 et ai ~(the same, but terse) \end{lstlisting} Setting the shift-width to 1 makes it easy to indent a paragraph as much or as little as you want with the following \emph{ Indent a paragraph by 1 shift-width } \begin{lstlisting} >ap \end{lstlisting} \emph{ Stop the annoying 'K' help look up and make 'K' go down 30 lines } \begin{lstlisting} :map K 30+zz \end{lstlisting} \emph{ Map ',r' to make it easy to find and replace the word under the cursor } \begin{lstlisting} :nmap ,r :%s/=expand("")//gc \end{lstlisting} \emph{ Swap quickly between 2 files which are open in vim } \begin{lstlisting} vim a.txt b.txt :n [control] ^ \end{lstlisting} \emph{ Make a normal mode command ',o' to open a file with the right program } \begin{lstlisting} :nmap ,f :!xdg-open \end{lstlisting} \begin{lstlisting} :nmap ,f :!open ~(for Mac OSX) \end{lstlisting} \emph{ Turn on and off spell-checking by typing ',ss' } \begin{lstlisting} :nmap ,ss :set spell! \end{lstlisting} \begin{lstlisting} nmap ,ss :set spell! ~(put this in your 'vimrc' file) \end{lstlisting} \section{Working With Text Data} \emph{ Duplicating the columns (fields) of a space delimited file } \begin{lstlisting} :%s= [^ ]\+$=&&= - duplicate end column \end{lstlisting} \begin{lstlisting} :%s= \f\+$=&&= - same thing \end{lstlisting} \begin{lstlisting} :%s= \S\+$=&& - usually the same \end{lstlisting} \emph{ Working with Columns sub any str1 in col3 } \begin{lstlisting} :%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2: \end{lstlisting} \emph{ Swapping first \& last column (4 columns) } \begin{lstlisting} :%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1: \end{lstlisting} \emph{ Format a mysql query } \begin{lstlisting} :%s#\\|\\|\\|\<\inner join\>#\r&#g \end{lstlisting} \emph{ Substitute string in column 30 } \begin{lstlisting} :%s/^\(.\{30\}\)xx/\1yy/ \end{lstlisting} \emph{ Decrement numbers by 3 } \begin{lstlisting} :%s/\d\+/\=(submatch(0)-3)/ \end{lstlisting} \emph{ Increment numbers by 6 on certain lines only } \begin{lstlisting} :g/loc\|function/s/\d/\=submatch(0)+6/ \end{lstlisting} \emph{ Better } \begin{lstlisting} :%s#txtdev\zs\d#\=submatch(0)+1#g \end{lstlisting} \begin{lstlisting} :h /\zs \end{lstlisting} \emph{ Increment only numbers gg\textbackslash d\textbackslash d by 6 (another way) } \begin{lstlisting} :%s/\(gg\)\@<=\d\+/\=submatch(0)+6/ \end{lstlisting} \begin{lstlisting} :h zero-width \end{lstlisting} \emph{ Rename a string with an incrementing number } \begin{lstlisting} :let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1 # convert yy to 10,11,12 etc \end{lstlisting} \emph{ As above but more precise } \begin{lstlisting} :let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1 # convert xxyy to xx11,xx12, \end{lstlisting} xx13 \subsection{Numbers} \emph{ Increment the number which is under cursor } \begin{lstlisting} \end{lstlisting} \emph{ Decrement the number which is under cursor } \begin{lstlisting} \end{lstlisting} If the cursor is over a number such as '124' in the document then one can press $<$control-x$>$ to decrement that number to '123' These dont work on Microsoft computers. \emph{ Perform an arithmetic calculation on the 'command' line } \begin{lstlisting} :=5*5 \end{lstlisting} \emph{ Incrementing numbers (type '$<$c-a$>$' as 5 characters) } \begin{lstlisting} :'a,'bg/\d\+/norm! ^A \end{lstlisting} \emph{ Increment all numbers in a document which are at the start of the line } \begin{lstlisting} :1,$g/^\d/exe "norm! \" \end{lstlisting} \subsection{Sorting Text} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Sorting with external unix sort command }} \\ \hline \texttt{ :g/\^{}\$/;,/\^{}\$/-1!sort } & Sort each block (note the crucial ;) \\ \hline \end{tabular} \end{center} \emph{ Sort the whole file using external sort } \begin{lstlisting} :%!sort -u \end{lstlisting} \emph{ Sort all text between the bookmarks 'a' and 'b' } \begin{lstlisting} :'a,'b!sort -u \end{lstlisting} \emph{ Sort text after the cursor in the current paragraph } \begin{lstlisting} !} sort -u \end{lstlisting} \emph{ Sort the current and next paragraphs } \begin{lstlisting} !2ap sort -u \end{lstlisting} The command above uses the 'ap' paragraph text object. The paragraph text object will sort the entire paragraph where the cursor is currently located, whereas the '$\}$' paragraph movement command will only sort the text which is located after the cursor in the current paragraph. \emph{ Sort all lines on second column using vims internal 'sort' command } \begin{lstlisting} :sort /.*\%2v/ \end{lstlisting} \subsection{Csv Data Files} \emph{ Highlight a particular csv column (put in .vimrc) } \begin{lstlisting} function! CSVH(x) execute 'match Keyword /^\([^,]*,\)\{'.a:x.'}\zs[^,]*/' execute 'normal ^'.a:x.'f,' endfunction command! -nargs=1 Csv :call CSVH() \end{lstlisting} \emph{ Columnise a csv file for display only as may crop wide columns } \begin{lstlisting} :let width = 20 :let fill=' ' | while strlen(fill) < width | let fill=fill.fill | endwhile :%s/\([^;]*\);\=/\=strpart(submatch(1).fill, 0, width)/ge :%s/\s\+$//ge \end{lstlisting} \emph{ Call with } \begin{lstlisting} :Csv 5 ~( highlight fifth column) \end{lstlisting} \section{Filtering Text} \emph{ Remove all consecutive blank lines in the current file } \begin{lstlisting} :%!cat -s ~(type 'u' undo to see how many lines would be deleted) \end{lstlisting} \begin{lstlisting} :1,$!cat -s ~(the same) \end{lstlisting} \begin{lstlisting} gg!G cat -s ~(the same, using motions instead of ranges) \end{lstlisting} \emph{ Remove all extra spaces (consecutive spaces) in the current file } \begin{lstlisting} :%! tr -s ' ' \end{lstlisting} \emph{ Reformat all lines after the current one, wrapping lines } \begin{lstlisting} :.,$!par ~(par knows how to reformat 'bash comments' for example) \end{lstlisting} \emph{ Insert the result of the 'ls' bash command at the cursor position } \begin{lstlisting} :r !ls | tr '\n' ' ' \end{lstlisting} \emph{ Execute the current line as a bash command (doesnt insert results) } \begin{lstlisting} :.w !bash \end{lstlisting} \emph{ Filter a block of lines between 2 blank lines adding a '\#' } \begin{lstlisting} ?^ *?+1,/^ *$/-1w !sed 's/^/\#/' \end{lstlisting} \begin{lstlisting} !apsed 's/^/\#/' ~(the same, using the 'ap' textobject) \end{lstlisting} \emph{ Add comment characters to this paragraph and append to 'test.txt' } \begin{lstlisting} ?^ *?+1,/^ *$/-1w !sed 's/^/\#/' >> test.txt \end{lstlisting} \section{Line Numbers} \emph{ Inserting line number into file } \begin{lstlisting} :g/^/exec "s/^/".strpart(line(".")." ", 0, 4) \end{lstlisting} \begin{lstlisting} :%s/^/\=strpart(line(".")." ", 0, 5) \end{lstlisting} \begin{lstlisting} :%s/^/\=line('.'). ' ' \end{lstlisting} \emph{ Make the function key 12 turn on or off the display of line numbers } \begin{lstlisting} :map :set number! \end{lstlisting} \emph{ Numbering lines VIM way } \begin{lstlisting} :set number ~(show line numbers) \end{lstlisting} \begin{lstlisting} :%s/^/\=strpart(line('.')." ",0,&ts) \end{lstlisting} \emph{ Numbering lines (with perl) starting from arbitrary number } \begin{lstlisting} :'a,'b!perl -pne 'BEGIN{$a=223} substr($_,2,0)=$a++' \end{lstlisting} \emph{ Produce a list of numbers } \emph{ Type in number on line say 223 in an empty file } \begin{lstlisting} qqmnYP`n^Aq ~( in recording q repeat with @q) \end{lstlisting} \emph{ Increment existing numbers to end of file (type $<$c-a$>$ as 5 characters) } \begin{lstlisting} :.,$g/^\d/exe "normal! \" \end{lstlisting} \emph{ A tip for advanced incrementing } \begin{lstlisting} http://vim.sourceforge.net/tip_view.php?tip_id=150 \end{lstlisting} \emph{ Eg create list starting from 223 incrementing by 5 between markers a,b } \begin{lstlisting} :let I=223 \end{lstlisting} \begin{lstlisting} :'a,'bs/^/\=INC(5)/ \end{lstlisting} \emph{ Generate a list of numbers from 23 to 64 } \begin{lstlisting} o23qqYpq40@q \end{lstlisting} \emph{ Number lines } \begin{lstlisting} :new | r!nl # \end{lstlisting} \section{Reformatting Text} In this context the 'format' of the text means the length in characters of each line, whether the line is aligned to the centre, to the left, the amount of spaces between words and sentences and similar things. \emph{ Remove extra spaces between words in the current paragraph } \begin{lstlisting} !ap tr -s ' ' \end{lstlisting} \begin{lstlisting} !ap tr -s '[:blank:]' ~(the same but handles tabs) \end{lstlisting} \begin{lstlisting} !ap s/[ ]\+/[ ]/g ~(the same but harder to type) \end{lstlisting} \subsection{Wrapping Text} In this context 'wrapping text' means the process of realigning text so that no line is more than a certain number of characters long. and the amount of indentation of each line. The vim 'gq' command takes into account the current screen size and font size when wrapping the lines. For reformatting source code see:``working with source code'' \emph{ Set the text width for the document to 70 characters } \begin{lstlisting} set tw=70 \end{lstlisting} \emph{ See the current line character-width setting (0 means 'automatic') } \begin{lstlisting} set tw \end{lstlisting} \emph{ Set the line character-width setting back to its default } \begin{lstlisting} set tw& \end{lstlisting} \emph{ Wrap all lines in the current paragraph to a certain character width } \begin{lstlisting} gqap \end{lstlisting} \emph{ Wrap all lines in the current document to a certain character width } \begin{lstlisting} gggqG \end{lstlisting} The lines will be wrapped according to the text character width set with the 'set tw' command \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ line wrapping formatting tools }} \\ \hline \texttt{ par } & A formatting tool \\ \texttt{ fmt } & A tool which respects indents \\ \texttt{ gq } & The built in vim formatting tools \\ \hline \end{tabular} \end{center} The tools mentioned above are unix-type tools but are also available for a microsoft operating system. \emph{ Format the current paragraph respecting current indentation } \begin{lstlisting} !apfmt \end{lstlisting} \emph{ Format the next paragraph of text (fill and break lines) } \begin{lstlisting} !}fmt ~(uses external program 'fmt') \end{lstlisting} \begin{lstlisting} !}par ~(the same, but 'par' can do more than format) \end{lstlisting} \emph{ Format the until the end of the paragraph with the vim formatter } \begin{lstlisting} gq} ~(formats only after the cursor) \end{lstlisting} \emph{ Format the current paragraph with the vim formatter } \begin{lstlisting} gqap ~(this also formats before the cursor) \end{lstlisting} \emph{ Format the text until the bookmark 'a' } \begin{lstlisting} gq'a \end{lstlisting} \emph{ Format the entire file } \begin{lstlisting} gggqG \end{lstlisting} \subsection{Indentation} \emph{ Turn on autoindenting } \begin{lstlisting} :set ai ~(useful with 'gq', since it preserves the current indent) \end{lstlisting} \subsection{Alignment} \emph{ Centre align the whole file with a width of 40 } \begin{lstlisting} :%center 40 \end{lstlisting} \begin{lstlisting} :%left 40 ~(left alignment) \end{lstlisting} \begin{lstlisting} :%right 40 \end{lstlisting} \emph{ Center the current line } \begin{lstlisting} :ce \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ commands to fix line-break and space problems }} \\ \hline \texttt{ :\%s/\textbackslash r/\textbackslash r/g } & Turn DOS returns \^{}M into real returns \\ \texttt{ :\%s= *\$== } & Delete end of line blanks \\ \texttt{ :\%s= \textbackslash +\$== } & Same thing \\ \texttt{ :\%s\#\textbackslash s*\textbackslash r\textbackslash ?\$\#\# } & Clean both trailing spaces AND DOS returns \\ \texttt{ :\%s\#\textbackslash s*\textbackslash r*\$\#\# } & Same thing \\ \hline \end{tabular} \end{center} \section{Moving Around} This section is about various movement commands available in Vim. Movement commands can follow other commands (such as deleting, or copying) to provide a range for that command. That is, any movement (including a search with '/') can be combined with another command to alter text in the document. This is an important vim concept. For example \emph{ Delete all text up until the next occurance of the text 'big' } \begin{lstlisting} :d/big \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ the basic movement commands }} \\ \hline \texttt{ j } & One line down \\ \texttt{ k } & One line up \\ \texttt{ h } & One character left \\ \texttt{ l } & Once character right \\ \hline \end{tabular} \end{center} \emph{ Go to the beginning of the file } \begin{lstlisting} gg \end{lstlisting} \emph{ Go to the end of the file } \begin{lstlisting} G \end{lstlisting} \emph{ Go to line 33 } \begin{lstlisting} 33G \end{lstlisting} \emph{ Jump to the last modification line } \begin{lstlisting} '. \end{lstlisting} \emph{ Jump back to where you just were (before jumping) } \begin{lstlisting} '' ~(i find this very handy) \end{lstlisting} \emph{ Cycle through recent modifications, forwards and backwards } \begin{lstlisting} g; g, \end{lstlisting} \emph{ Set a bookmark named 'a' at the current position } \begin{lstlisting} ma ~(or mb, mc, etc) \end{lstlisting} \emph{ Jump to the position indicated by the bookmark a } \begin{lstlisting} 'a \end{lstlisting} \emph{ Go to the end of the paragraph } \begin{lstlisting} } \end{lstlisting} \emph{ Go to the next instance of the character 'g' on the line } \begin{lstlisting} fg \end{lstlisting} \emph{ Repeat this operation } \begin{lstlisting} ; \end{lstlisting} \emph{ Go BACK to the next instance of the character 'g' on the line } \begin{lstlisting} Fg \end{lstlisting} \emph{ Move to the matching parenthesis $\{$,[,( } \begin{lstlisting} % \end{lstlisting} \emph{ Scroll scroll the current line to the top of the window } \begin{lstlisting} zt \end{lstlisting} \emph{ Jump to the next instance of the word under the cursor } \begin{lstlisting} * \end{lstlisting} \emph{ Return to last edit position (You want this!) } \begin{lstlisting} autocmd BufReadPost * \ if line("'\"") > 0 && line("'\"") <= line("$") | \ exe "normal! g`\"" | \ endif \end{lstlisting} \subsection{Moving By Searching} \emph{ Search for 'joe' and put the cursor at the end of the 1st match } \begin{lstlisting} /joe/e \end{lstlisting} \emph{ Put the cursor 1 character after the end of the 1st match of 'frog' } \begin{lstlisting} /frog/e+1 \end{lstlisting} \emph{ Put the cursor 2 character before the start of the 1st match of 'bill' } \begin{lstlisting} /bill/s-2 - cursor set to Start of match minus 2 \end{lstlisting} \emph{ Put the cursor 3 lines after the end of the 1st match of 'ball' } \begin{lstlisting} /ball/+3 \end{lstlisting} \section{Refering To Chunks Of Text} Chunks of text can be referred to by line numbers, motion commands, or 'text objects'. \emph{ Delete lines 4 to 9 } \begin{lstlisting} :4,9d \end{lstlisting} \emph{ Delete until the next word 'stop' (not including the word) } \begin{lstlisting} d/stop \end{lstlisting} \subsection{Text Objects} A 'text object' is just a chunk of text such as a paragraph, sentence or word. The text objects are very useful because they allow you to refer to a chunk of text without knowing the line numbers, or having to position the cursor at the start of the chunk. \emph{ Get help about the available 'text objects' } \begin{lstlisting} :help text-objects \end{lstlisting} \emph{ Delete the current paragraph (before and after the cursor) } \begin{lstlisting} dap ~('ap' refers to a paragraph) \end{lstlisting} \emph{ Delete the current paragraph and the next 2 paragraphs } \begin{lstlisting} 3dap \end{lstlisting} \emph{ Change the current sentence (before and after the cursor) } \begin{lstlisting} cas \end{lstlisting} \emph{ Change the current sentence and the next one } \begin{lstlisting} 2cas \end{lstlisting} \emph{ Change the current single quotes quotation } \begin{lstlisting} ci' ~(leaves the quotation marks) \end{lstlisting} \begin{lstlisting} ca' ~(deletes the quotation marks) \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ available textobjects }} \\ \hline \texttt{ aw } & A word \\ \texttt{ aW } & A long word (including punctuation) \\ \texttt{ iW } & A long word without white space \\ \texttt{ as } & A sentence \\ \texttt{ ap } & A sentence \\ \texttt{ ip } & A sentence, without the blank lines \\ \texttt{ a$>$ } & A angle braket block \\ \texttt{ a$\}$ or aB } & A brace block \\ \texttt{ i$\}$ or iB } & A brace block \\ \texttt{ a] } & A square bracket block \\ \texttt{ a) } & A bracket block \\ \texttt{ i) } & A bracket block not including the brackets \\ \texttt{ a" or a' } & A quotation (one line only) \\ \texttt{ i" or i' } & A quotation not including the quotes \\ \hline \end{tabular} \end{center} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ text objects }} \\ \hline \texttt{ :h text-objects } & Get help \\ \texttt{ daW } & Delete contiguous non-whitespace \\ \texttt{ di$<$ yi$<$ ci$<$ } & Delete/Yank/Change HTML tag contents \\ \texttt{ da$<$ ya$<$ ca$<$ } & Delete/Yank/Change whole HTML tag \\ \texttt{ dat dit } & Delete HTML tag pair \\ \texttt{ diB daB } & Empty a function $\{$$\}$ \\ \texttt{ das } & Delete a sentence \\ \hline \end{tabular} \end{center} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://vim.wikia.com/wiki/Indent_text_object}] How to define a new text object \end{description} \section{Inserting} \emph{ Insert the current date in a new line } \begin{lstlisting} :r !date \end{lstlisting} \begin{lstlisting} :.r !date ~(the same) \end{lstlisting} \begin{lstlisting} :read !date ~(the same) \end{lstlisting} \emph{ Insert the current date in at the end of the document } \begin{lstlisting} :$r !date \end{lstlisting} \emph{ Insert the full names of 10 random image files in the document } \begin{lstlisting} :r !locate '*.jpg' | shuf | head -10 \end{lstlisting} \emph{ Insert the current date after the next blank line } \begin{lstlisting} :/^ *$/r !date ~(doesnt work with tab characters) \end{lstlisting} \begin{lstlisting} :/^\s*$/r !date ~(handles any kind of whitespace) \end{lstlisting} \begin{lstlisting} :/^[:space:]*$/r !date ~(the same) \end{lstlisting} \begin{lstlisting} :/^[[:space:]]*$/r !date ~(the same, again) \end{lstlisting} \emph{ Insert todays date after every blank line in the file } \begin{lstlisting} :g/^\s*/r !date ~(this seems a bit slow) \end{lstlisting} \emph{ Insert all the text files in the current directory } \begin{lstlisting} :r *.txt ~(but why would you do this?!) \end{lstlisting} \begin{lstlisting} cat *.txt >> big.txt ~(similar but not the same, from bash) \end{lstlisting} \emph{ Insert a file listing of the current folder at the top of the file } \begin{lstlisting} :1r !ls \end{lstlisting} \emph{ The following doesnt work because vim is running as a different user } \begin{lstlisting} :r !history \end{lstlisting} \emph{ Insert after the cursor, lines 200-300 of the file 'tree.txt' } \begin{lstlisting} :r !sed -n 200,300p tree.txt \end{lstlisting} \emph{ Insert an attachment within an email message in vim } \begin{lstlisting} :r !uuencode binfile binfile \end{lstlisting} \subsection{Autocompletion} \emph{ Insert the name of a file in current directory into the document } \begin{lstlisting} [control] x [control] f ~(a text list box appears with names) \end{lstlisting} \section{Inserting From The Web} \emph{ Insert the contents of a webpage as plain text at the end of the file } \begin{lstlisting} :$r !lynx -dump http://server.net/page.html \end{lstlisting} \emph{ Insert the text file 'file.txt' from the web at the cursor position } \begin{lstlisting} :r http://nowhere.org/file.txt ~(this may use 'curl') \end{lstlisting} \subsection{Inserting A File Into Itself} \emph{ Double the current file (append the file to the end of itself) } \begin{lstlisting} :$r !cat % \end{lstlisting} \emph{ Insert all comment lines in the file after the cursor } \begin{lstlisting} :r !grep '^ *#' % \end{lstlisting} \begin{lstlisting} :r !cat % | grep '^ *#' ~(the same) \end{lstlisting} In the command above, lines beginning with the '\#' comment character are copied in the same order to the current cursor position. Exactly why you would want to do this remain unclear but I thought that it was interesting. \subsection{Random Text} \emph{ Make a command 'Rand' which inserts some random words in the document } \begin{lstlisting} :com! -nargs=1 Rand r !shuf -n /usr/share/dict/words | tr '\n' ' ' \end{lstlisting} This command can be executed with 'Rand 200' which inserts 200 random words for the dictionary file into the current file after the cursor. \section{Deleting} \emph{ Delete the current paragraph (deletes before and after the cursor) } \begin{lstlisting} dap ~('ap' refers to a paragraph) \end{lstlisting} \emph{ Delete the paragraph after the cursor } \begin{lstlisting} d} \end{lstlisting} \emph{ Delete the current line and the next line } \begin{lstlisting} dj \end{lstlisting} \emph{ Delete the current line and the line above it } \begin{lstlisting} dk \end{lstlisting} \emph{ Delete the rest of the line after the cursor } \begin{lstlisting} D \end{lstlisting} \emph{ Delete several lines, using visual mode } \begin{lstlisting} [shift]+v, move down (j) or up (k) to select text, press d \end{lstlisting} \emph{ Delete up to the line number 234 } \begin{lstlisting} d234G \end{lstlisting} \emph{ Delete from current line until the bookmark 'c' } \begin{lstlisting} d'c \end{lstlisting} \emph{ Delete first 2 characters of 10 successive lines } \begin{lstlisting} 010j2ld \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Deleting non-ascii characters (some invisible) }} \\ \hline \texttt{ :\%s/[\textbackslash x00-\textbackslash x1f\textbackslash x80-\textbackslash xff]/ /g } & Type this as you see it \\ \texttt{ :\%s/[$<$C-V$>$128-$<$C-V$>$255]//gi } & Where you have to type the Control-V \\ \texttt{ :\%s/[-ÿ]//gi } & Should see a black square \& a dotted y \\ \texttt{ :\%s/[$<$C-V$>$128-$<$C-V$>$255$<$C-V$>$01-$<$C-V$>$31]//gi } & All pesky non-asciis \\ \texttt{ :exec "norm /[\textbackslash x00-\textbackslash x1f\textbackslash x80-\textbackslash xff]/" } & Same thing \\ \hline \end{tabular} \end{center} \emph{ Delete the current line without destroying default buffer contents } \begin{lstlisting} "_dd \end{lstlisting} \emph{ Delete the current word without overwriting the current clipboard } \begin{lstlisting} "_daw \end{lstlisting} \section{Editing} \emph{ Change the rest of the line after the cursor } \begin{lstlisting} C \end{lstlisting} \emph{ Shift the next paragraph right } \begin{lstlisting} >} ~(change the shift width with :set sw=4) \end{lstlisting} \emph{ Lower case a line } \begin{lstlisting} guu \end{lstlisting} \emph{ Upper case a line } \begin{lstlisting} gUU \end{lstlisting} \emph{ Make the current paragraph uppercase } \begin{lstlisting} gUap \end{lstlisting} \emph{ Make the next word uppercase } \begin{lstlisting} gUw \end{lstlisting} \emph{ Protect a file from unintentional changes } \begin{lstlisting} :set ro ~(read only) \end{lstlisting} \subsection{Repeating Edits} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Summary of editing repeats }} \\ \hline \texttt{ . } & Last edit (magic dot) \\ \texttt{ :\& } & Last substitute \\ \texttt{ :\%\& } & Last substitute every line \\ \texttt{ :\%\&gic } & Last substitute every line confirm \\ \texttt{ g\% } & Normal mode repeat last substitute \\ \texttt{ g\& } & Last substitute on all lines \\ \texttt{ @@ } & Last recording \\ \texttt{ @: } & Last command-mode command \\ \texttt{ :!! } & Last :! command \\ \texttt{ :$\sim$ } & Last substitute \\ \texttt{ :help repeating } \\ \hline \end{tabular} \end{center} \subsection{The Edit Changes List} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ commands to manage changes to the document }} \\ \hline \texttt{ '. } & Jump to last modification line \\ \texttt{ `. } & Jump to exact spot in last modification line \\ \texttt{ g; } & Cycle through the recent changes (oldest first) \\ \texttt{ g, } & Cycle through the recent changes (newest first) \\ \texttt{ :changes } & Show what changes have been made to the document \\ \texttt{ :h changelist } & Help for above \\ \texttt{ $<$C-O$>$ } & Retrace your movements in file (starting from most recent) \\ \texttt{ $<$C-I$>$ } & Retrace your movements in file (reverse direction) \\ \hline \end{tabular} \end{center} \section{Cut Copy And Paste} In vim, copying text to the clipboard is known as ``yanking''. This text can then be pasted into the text with the "p" command. \emph{ Copy the current line to the clipboard. } \begin{lstlisting} yy \end{lstlisting} \begin{lstlisting} ""yy ~(the same, but unnecessary) \end{lstlisting} \emph{ Paste text into the file after the current position } \begin{lstlisting} p \end{lstlisting} \begin{lstlisting} ""p ~(the same, naming explicitly the default register "") \end{lstlisting} \emph{ Paste text into the file before the current position } \begin{lstlisting} P \end{lstlisting} \emph{ Paste text after current position and adjust the indent } \begin{lstlisting} ]p \end{lstlisting} \emph{ Copy to the clipboard all text until the next occurrence of ``stop'' } \begin{lstlisting} y/stop ~(the word "stop" is not included in the copied text) \end{lstlisting} \emph{ Copy all text of the current line until the next ":" character } \begin{lstlisting} yf: \end{lstlisting} \section{Registers} Registers are buffers or 'clipboards' which can hold text or commands. A register can be pasted into the document or executed (if they hold valid vim commands). Registers have one letter names from a to z. A macro can be recorded and and stored in a register with the 'q' command \emph{ Display contents of all registers } \begin{lstlisting} :reg \end{lstlisting} \begin{lstlisting} :di ~(the same ??) \end{lstlisting} \emph{ Display contents of register b } \begin{lstlisting} :reg b \end{lstlisting} \emph{ Copy the current line into register 'd' } \begin{lstlisting} "dyy \end{lstlisting} \emph{ Delete the current line and store in register d and the default reg. } \begin{lstlisting} "cdd \end{lstlisting} \emph{ Store text that is to be changed or deleted in register a } \begin{lstlisting} "act< ~(change until the '<' character) \end{lstlisting} \begin{lstlisting} "acf< ~(almost the same) \end{lstlisting} \emph{ Change the word under the cursor, store a copy of the old one in reg b } \begin{lstlisting} "bcaw ~(a copy of the old word is stored in the default register) \end{lstlisting} \emph{ Strip leading '$>$$>$' from a line, copy it into a register and execute it } \begin{lstlisting} :s/[ ]*>>// | normal u"ayy@a \end{lstlisting} This is useful for executing shell commands in the document which have some prefix \emph{ Copy (yank) from the cursor to the second instance of ' on the line } \begin{lstlisting} y2f' ~(the text is copied in the default register "") \end{lstlisting} \emph{ Copy text on the line up to the next quote and put it in register 'k' } \begin{lstlisting} "kyf' \end{lstlisting} \emph{ Yank 5 lines into "a" then add a further 5 } \begin{lstlisting} "a5yy \end{lstlisting} \begin{lstlisting} 10j \end{lstlisting} \begin{lstlisting} "A5yy \end{lstlisting} \subsection{Putting Text Into Registers} \emph{ Use a register as a map (pre-load registers in .vimrc) } \begin{lstlisting} :let @m=":'a,'bs/" \end{lstlisting} \begin{lstlisting} :let @s=":%!sort -u" \end{lstlisting} \emph{ Append all lines containing 'tree' to register a } \begin{lstlisting} :g/tree/y A \end{lstlisting} \begin{lstlisting} :g/tree/y A | :let @*=@a ~(put into paste buffer) \end{lstlisting} \emph{ Put the command ``:\%!sort -u'' into register 's' } \begin{lstlisting} :let @s=":%!sort -u" \end{lstlisting} We can then execute this command by typing '@s' \subsection{Displaying Registers} \emph{ Display the contents of register 'a' } \begin{lstlisting} :echo @a \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ listing the contents of the registers }} \\ \hline \texttt{ :reg } & Display contents of all registers \\ \texttt{ :reg a } & Display content of register a \\ \texttt{ :reg 12a } & Display content of registers 1,2 \& a \\ \texttt{ ``5p } & Retrieve 5th ''ring" \\ \texttt{ "1p.... } & Retrieve numeric registers one by one \\ \texttt{ :let @y='yy@"' } & Pre-loading registers (put in .vimrc) \\ \texttt{ qqq } & Empty register "q" \\ \texttt{ qaq } & Empty register "a" \\ \texttt{ :reg .-/\%:*" } & The seven special registers \\ \texttt{ :reg 0 } & What you last yanked, not affected by a delete \\ \texttt{ "\_dd } & Delete to blackhole register "\_ , don't affect any register \\ \hline \end{tabular} \end{center} \subsection{Appending Text To The Registers} \emph{ Append the current line to the register 'a' } \begin{lstlisting} "Ayy \end{lstlisting} \emph{ Delete the current line and append it to the register 'x' } \begin{lstlisting} "Xdd \end{lstlisting} \emph{ Change the word under the cursor and append it to the register 'q' } \begin{lstlisting} "Qcaw \end{lstlisting} \subsection{Altering The Contents Of Registers} \emph{ Empty the contents of the 'a' register } \begin{lstlisting} :let @a='' \end{lstlisting} \emph{ Transfer the contents of the 'a' register to the 'b' register } \begin{lstlisting} :let @a=@b | :let @a='' \end{lstlisting} \emph{ Remove only the 1st space from the contents of the 'a' register } \begin{lstlisting} :let @a = substitute(@a,'[[:space:]]','','') \end{lstlisting} \emph{ Remove all space characters from the contents of the 'a' register } \begin{lstlisting} :let @a = substitute(@a,'[[:space:]]','','g') \end{lstlisting} \emph{ Remove leading spaces and '$>$$>$' character from beginning of 'a' register } \begin{lstlisting} :let @a = substitute(@a,'^[ ]*>>','','') \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ manipulating registers }} \\ \hline \texttt{ :let @a=@\_ } & Clear register a \\ \texttt{ :let @a="" } & Clear register a \\ \texttt{ :let @a=@" } & Save unnamed register \\ \texttt{ :let @*=@a } & Copy register a to paste buffer \\ \texttt{ :let @*=@: } & Copy last command to paste buffer \\ \texttt{ :let @*=@/ } & Copy last search to paste buffer \\ \texttt{ :let @*=@\% } & Copy current filename to paste buffer \\ \hline \end{tabular} \end{center} \subsection{Pasting Registers} \emph{ Paste the contents of the register 'k' in the document after the cursor } \begin{lstlisting} "kp \end{lstlisting} \begin{lstlisting} :put k ~(the same) \end{lstlisting} \begin{lstlisting} :pu k ~(the same) \end{lstlisting} \emph{ Paste the current line into the default register and execute it } \begin{lstlisting} yy@" ~(watch out this could have very strange results- user 'u' to undo) \end{lstlisting} \emph{ Paste the contents of register 'b' into the document after the cursor } \begin{lstlisting} "bp \end{lstlisting} \emph{ Paste the contents of register 'j' into the document before the cursor } \begin{lstlisting} "jP \end{lstlisting} \emph{ Paste the contents of the default register from 'insert' mode } \begin{lstlisting} [control]r" ~(press the 'control' key, then 'r', then '"') \end{lstlisting} \emph{ Paste the contents of the register p from 'insert' mode } \begin{lstlisting} [control]rp ~(press the 'control' key, then 'r', then 'p') \end{lstlisting} \emph{ Create a new buffer, paste a register "q" into it, then sort new buffer } \begin{lstlisting} :new +put q|%!sort \end{lstlisting} \subsection{The Numeric Registers} The numeric registers (``0 ''1 "2 etc) hold the text which was previously in the default register ("") before being replaced with a new yank into the default register. \emph{ Paste what was formerly in the default register into the document } \begin{lstlisting} "0p \end{lstlisting} \subsection{Executing Registers} The registers may also be executed, if they contain a series of valid vim or shell commands. One can record a macro into a register and then execute it. \emph{ Record a macro to be stored in the register 'y' } \begin{lstlisting} qy ~(type 'q' to stop recording the macro) \end{lstlisting} \emph{ Execute the contents of the register 'y' } \begin{lstlisting} @y \end{lstlisting} \begin{lstlisting} :@y ~(the same) \end{lstlisting} \emph{ Copy the current line into a register and execute it } \begin{lstlisting} "ayy@a \end{lstlisting} \begin{lstlisting} yy@" ~(same thing using unnamed register) \end{lstlisting} \emph{ Strip a '\#' character of the current line and execute as a vim command } \begin{lstlisting} :s/\s*#\s*// | normal "ayy@a \end{lstlisting} \begin{lstlisting} execute command just typed in \end{lstlisting} \begin{lstlisting} u@. \end{lstlisting} \section{Character And Text Information} \emph{ Show information for the character under the cursor } \begin{lstlisting} ga \end{lstlisting} \emph{ Count words in a text file } \begin{lstlisting} g \end{lstlisting} \section{Translating With Vim} \emph{ Load the file 'eg.txt' to translate. } \begin{lstlisting} :e eg.txt \end{lstlisting} \emph{ Save a copy of the file with the name 'eg.en.txt' } \begin{lstlisting} :sav eg.en.txt \end{lstlisting} \subsection{Dictionaries For Translation} \emph{ Use curl to look up a dictionary definition of 'tree' } \begin{lstlisting} :!curl dict://dict.org/d:Tree \end{lstlisting} \emph{ Show all available dictionaries at 'dict.org' } \begin{lstlisting} :!curl dict://dict.org/show:db \end{lstlisting} \emph{ Show the definition of 'bash' from the free online computer dictionary } \begin{lstlisting} :!curl dict://dict.org/d:bash:foldoc \end{lstlisting} \emph{ Show all words beginning with 'bash' } \begin{lstlisting} :!curl dict://dict.org/m:bash::prefix \end{lstlisting} \begin{lstlisting} :!dict -ms prefix tree ~(the same) \end{lstlisting} \emph{ Show all ways of searching the dictionaries } \begin{lstlisting} curl dict://dict.org/show:strat \end{lstlisting} \emph{ Show definition of 'elephant' using the dict tool } \begin{lstlisting} :!dict tree \end{lstlisting} \emph{ Find out what dictionaries are available to query } \begin{lstlisting} :!dict -D \end{lstlisting} \emph{ Query the spanish english dictionary at 'freedict.org' for word 'hora' } \begin{lstlisting} :!dict -d spa-eng hora \end{lstlisting} \emph{ Make a command ':Es' to query a dict server for the given word } \begin{lstlisting} :com! -nargs=1 Es !dict -d spa-eng \end{lstlisting} To use this command we can type ':Es obligar' to look up the meaning of the word 'obligar' in the spanish english dictionary Unfortunately the 'freedict' dictionaries are not very comprehensive. \emph{ Show some information about the spanish english dictionary } \begin{lstlisting} :!dict -i spa-eng hora \end{lstlisting} (not very interesting information) \emph{ Search the word reference site for the spanish word 'obligar' } \begin{lstlisting} :!lynx -useragent="Mozilla/4.73 [en]" -dump "http://www.wordreference.com/es/en/translation.asp?spen=obligar" | sed '1,/Pocket Oxford/d;/Subscribe/,$d' | less \end{lstlisting} The wordreference site is very comprehensive, but doesnt like 'lynx' visiting it. \emph{ A command to search the word reference to translate a spanish word } \begin{lstlisting} :com! -nargs=1 Esw !lynx -useragent="Mozilla/4.73 [en]" -dump "http://www.wordreference.com/es/en/translation.asp?spen=" | less \end{lstlisting} \subsection{Preparing A Document For Translation} \emph{ Then put the text '$>$$>$' in front of each text line } \begin{lstlisting} :g/\S/s/^/>> / \end{lstlisting} \emph{ Double space all lines which contain some text (not just spaces) } \begin{lstlisting} :g/\S/put_ \end{lstlisting} \emph{ Triple space a file } \begin{lstlisting} :g/\S/put_ | put_ \end{lstlisting} \emph{ Double space all lines of the document (including empty lines) } \begin{lstlisting} :g/^/put_ \end{lstlisting} \emph{ A command ``:Tr'' to 'quote' ($>$$>$) on all lines and double space the file } \begin{lstlisting} :com! Tr g/\S/s/^/>> / | put_ \end{lstlisting} \emph{ Translate each line underneath the original line } \emph{ Move all the untranslated (quoted) lines to the end of the document } \begin{lstlisting} :g/^>>/m$ \end{lstlisting} \subsection{Spell Checking Foreign Languages} If you do not have a spell checking dictionary for a particular language, modern versions of Vim should offer to download it for you when you try to turn on spell checking for that language. \emph{ Turn on spell checking using a spanish dictionary } \begin{lstlisting} :set spell spelllang=es \end{lstlisting} \begin{lstlisting} :set spell spl=es ~(this is the same) \end{lstlisting} \emph{ Turn on spell checking both spanish and english spell-checking } \begin{lstlisting} :set spell spelllang=es,en \end{lstlisting} \emph{ Turn on spell checking for british english and spanish } \begin{lstlisting} :se spell spl=es,en_gb \end{lstlisting} \emph{ Find out what the current spell-check language is (or languages) } \begin{lstlisting} set spl \end{lstlisting} \emph{ Return the spell-check language back to the default (original) } \begin{lstlisting} set spl& \end{lstlisting} \emph{ A mapping ',es' to turn on/off spell checking for english and spanish } \begin{lstlisting} :nnoremap ,es :se spell! spl=es,en_gb \end{lstlisting} This mapping can be placed in the 'vimrc' configuration file and then the user can type ',es' in normal mode to toggle on or off spell checking for spanish and british english \emph{ Suggest a better spelling for the word under the cursor } \begin{lstlisting} z= \end{lstlisting} \emph{ Find out what spelling dictionaries you have installed } \begin{lstlisting} :!find ~ -type f -name '*.spl' \end{lstlisting} \section{Foreign Languages And Character Sets} Since vim supports the 'utf8' unicode character-set, it should be possible to edit a document written in any language and with any set of characters in the world. \emph{ Show unicode information for all characters relating to chess } :!unicode chess \emph{ Insert chess characters into the current document } \begin{lstlisting} :r !unicode -m0 chess | tr -d '[:alnum:][:space:][:punct:]' \end{lstlisting} The above will produce this: ♔♕♖♗♘♙♚♛♜♝ \emph{ A vim command to insert unicode glyphs pertaining to a term } \begin{lstlisting} com! -nargs=1 Uni r !unicode -m0 |tr -d '[:alnum:][:space:][:punct:]' \end{lstlisting} \subsection{Right To Left Characters} Some languages (such as arabic, as only one example) are written from the right side of the page to the left. Vim is capable of editing documents written in these languages. \emph{ Display the current file as right-to-left text } \begin{lstlisting} :set rl! \end{lstlisting} \section{Special Characters} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://www.fileformat.info/info/unicode/char/00e9/index.htm}] Character information for an e-acute character \end{description} \emph{ Display invisible and special characters (such as line-endings) } \begin{lstlisting} :set list \end{lstlisting} \emph{ View help for which characters will be displayed with ':set list' } \begin{lstlisting} :h listchars \end{lstlisting} \emph{ View hex value of the character under the cursor } \begin{lstlisting} ga \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Digraphs (non alpha-numerics) }} \\ \hline \texttt{ :digraphs } & Display table \\ \texttt{ :h dig } & Help \\ \texttt{ i$<$control-K$>$e' } & Enters é \\ \hline \end{tabular} \end{center} \emph{ Display a table of special 'digraph' characters } \begin{lstlisting} :dig \end{lstlisting} \emph{ Enter an e-acute 'é' character into the document } \begin{lstlisting} i233 ~(on a Unix/Linux/Apple computer) \end{lstlisting} \begin{lstlisting} i233 ~(on a Microsoft Windows computer) \end{lstlisting} \emph{ Pull a non-ascii character onto search bar } \begin{lstlisting} yl/" \end{lstlisting} \emph{ Search for all non-printable ascii characters } \begin{lstlisting} /[^a-zA-Z0-9_[:space:][:punct:]] \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Deleting non-ascii characters (some of which are invisible) }} \\ \hline \texttt{ :\%s/[-ÿ]//gi } & Should see a black square \& a dotted y \\ \hline \end{tabular} \end{center} \emph{ Delete all ascii characters from 128 to 255 } \begin{lstlisting} :%s/[128-255]//gi \end{lstlisting} \emph{ Delete all ascii characters 1 to 31 and 128 to 255 } \begin{lstlisting} :%s/[128-25501-31]//gi \end{lstlisting} \begin{lstlisting} :%s/[\x00-\x1f\x80-\xff]/ /g ~(the same using hex codes) \end{lstlisting} \begin{lstlisting} :exec "norm /[\x00-\x1f\x80-\xff]/" ~(same thing) \end{lstlisting} \section{Spell Checking} \emph{ Get help on spell checking } \begin{lstlisting} :help spell \end{lstlisting} \emph{ Turn on spell checking with the default language } \begin{lstlisting} :set spell \end{lstlisting} \emph{ Suggest alternatives to a badly spelled word } \begin{lstlisting} z= \end{lstlisting} \subsection{Spell Check Language} \emph{ View the vim help for the spell-check language option } \begin{lstlisting} :help spl \end{lstlisting} \emph{ Turn on spell checking, with US English, only for the current buffer } \begin{lstlisting} :setlocal spell spelllang=en_us \end{lstlisting} \emph{ Turn on spell checking, with british english } \begin{lstlisting} :set spell spelllang=en_gb \end{lstlisting} \emph{ Set the spell checking language to english or spanish } \begin{lstlisting} :set spelllang=en_us,nl,medical \end{lstlisting} \emph{ Set the spell checking language to American English, Dutch and Medical } \begin{lstlisting} :set spelllang=en_us,nl,medical \end{lstlisting} \emph{ Toggle British English spell } \begin{lstlisting} :set spell! spelllang=en_gb \end{lstlisting} \begin{lstlisting} :set spell! spl=en_gb ~(the same) \end{lstlisting} \emph{ Find out what language is currently being spell checked } \begin{lstlisting} :set spelllang \end{lstlisting} \emph{ Return the spelling language to its default } \begin{lstlisting} :set spelllang& \end{lstlisting} If you set spelllang to a language for which there is not spelling word list, then vim may prompt you to download the file. \subsection{Activating Spell Checking} \emph{ Turn off spell checking only for the current file } \begin{lstlisting} :setlocal nospell \end{lstlisting} \emph{ Turn off spell checking } \begin{lstlisting} :set nospell \end{lstlisting} \subsection{Spell Checking Commands} \emph{ Move to the next badly spelled word } \begin{lstlisting} ]s \end{lstlisting} \emph{ Suggest a better spelling for the current word (near the cursor) } \begin{lstlisting} z= \end{lstlisting} \emph{ In a vim script, find a better spelling for a word } \begin{lstlisting} spellsuggest() \end{lstlisting} \subsection{Configuring Spell Checking} \emph{ Add the current word to personal dictionary as a good word } \begin{lstlisting} zg \end{lstlisting} \emph{ Make a normal mode command ',ss' to turn on or off spell checking } \begin{lstlisting} :nmap ,ss :set spell! \end{lstlisting} The user can use this mapping by typing ',ss' when the Vim editor is in normal mode (neither an '--INSERT--' nor a ':' is visible at the bottom of the screen). If spell checking is off is will be turned on, and if spell checking is on, it will be turned off \emph{ Make a mapping ',ss' to turn on or off British English spell-checking } \begin{lstlisting} :nmap ,ss :set spell! spelllang=en_gb \end{lstlisting} \begin{lstlisting} :nmap ,ss :set spell! spl=en_gb ~(this is the same) \end{lstlisting} \emph{ A mapping to toggle spell checking and suggest a better spelling } \begin{lstlisting} :nmap ,ss :set spell!z= \end{lstlisting} Word lists for vim are kept in '.spl' files \emph{ View the help for how spell-checking files are found } \begin{lstlisting} help spell-load \end{lstlisting} \emph{ A spanish spell checking file in a utf8 computer should be called } \begin{lstlisting} es.utf-8.spl or es.ascii.spl \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ some places vim may look for spell files }} \\ \hline \texttt{ $\sim$/.vim/spell/pl.iso-8859-2.spl } \\ \texttt{ /usr/share/vim70/spell/pl.iso-8859-2.spl } \\ \texttt{ $\sim$/.vim/spell/pl.iso-8859-2.add.spl } \\ \texttt{ /usr/share/vim70/spell/pl.iso-8859-2.add.spl } \\ \texttt{ $\sim$/.vim/after/spell/pl.iso-8859-2.add.spl } \\ \hline \end{tabular} \end{center} \section{Configuring Vim} Configurations made with :set ... only apply for the current vim editing session. To make them permanent these set's need to be placed one of the vim configuration files (either for the current user or for all users). \subsection{Getting Help For Configurations} \emph{ View help on setting } \begin{lstlisting} :help options \end{lstlisting} \emph{ See a brief description of all vim configuration options } \begin{lstlisting} :help option-list \end{lstlisting} This also shows the long and short names of an option. \emph{ See a very detailed description of every single configuration option } \begin{lstlisting} :help option-summary \end{lstlisting} \emph{ See detailed help for the 'autoindent' configuration option } \begin{lstlisting} :help 'autoindent' ~(note the quote characters. they are often needed) \end{lstlisting} \begin{lstlisting} :help 'ai' ~(the same) \end{lstlisting} \begin{lstlisting} :help 'noai' ~(the same again) \end{lstlisting} \begin{lstlisting} :help ai ~(also works, but sometimes doesnt) \end{lstlisting} \emph{ See detailed help for the 'cindent' configuration option } \begin{lstlisting} :help 'cindent' \end{lstlisting} \begin{lstlisting} :help 'cin' ~(the same) \end{lstlisting} \begin{lstlisting} :help 'nocin' ~(the same) \end{lstlisting} \begin{lstlisting} :help nocin ~(also works) \end{lstlisting} \begin{lstlisting} :help cindent ~(No!! shows documentation for the 'cindent' function) \end{lstlisting} \emph{ See what settings for configuration options are currently in force } \begin{lstlisting} :set ~(only shows the modified settings) \end{lstlisting} \begin{lstlisting} :set all ~(show all settings, modified and unmodified) \end{lstlisting} \emph{ See what the current value of the 'shiftwidth' option is } \begin{lstlisting} :set sw \end{lstlisting} \emph{ See what the value for the autoindent option value is } \begin{lstlisting} :set ai? \end{lstlisting} \begin{lstlisting} :set autoindent? ~(the same) \end{lstlisting} (note: ':set ai' doesnt work, because it turns on autoindent) \subsection{Vimrc File} The 'vimrc' file is the file where all permanent configurations are stored. This can be tricky because there is a global config file at /etc/vim/vimrc and a local user config file at ``$\sim$/.vimrc'' \emph{ Show which vimrc file you are using (global or local) } \begin{lstlisting} :echo $MYVIMRC \end{lstlisting} \emph{ Put commands and configurations in the file, or somewhere else } \begin{lstlisting} ~/.vimrc ~(this only affects one user, not everybody) \end{lstlisting} \emph{ Edit the global vim configuration file with the needed permissions } \begin{lstlisting} !sudo vim /etc/vim/vimrc \end{lstlisting} \emph{ Make a command to edit the global vim configuration file (not reload it) } \begin{lstlisting} com! Vimrc !sudo vim /etc/vim/vimrc ~(executed with ':Vimrc') \end{lstlisting} \begin{lstlisting} command! Vimrc !sudo vim /etc/vim/vimrc ~(the same) \end{lstlisting} \emph{ A command 'So' to reload the vimrc file easily } \begin{lstlisting} command! So so /etc/vim/vimrc ~(execute with ':So') \end{lstlisting} \emph{ Reload the vim configuration file } \begin{lstlisting} :so $MYVIMRC \end{lstlisting} \begin{lstlisting} :source $MYVIMRC ~(the same) \end{lstlisting} \begin{lstlisting} :source ~/.vimrc ~(reload the users personal config file) \end{lstlisting} \subsection{Basic Configuration} \emph{ Dont insert any tabs } \begin{lstlisting} :set expandtab \end{lstlisting} \begin{lstlisting} set expandtab [in the 'vimrc' file] ~(note there is no colon ':') \end{lstlisting} \emph{ Set more than one option at a time } \begin{lstlisting} :set expandtab autoindent \end{lstlisting} These 2 options turn tabs into spaces, and auto-indents the text. \emph{ Turn on line numbering if it is off, or turn it off it is on } \begin{lstlisting} :set number! \end{lstlisting} \begin{lstlisting} :set invnumber ~(the same) \end{lstlisting} The process of turning something off when it is on, or on when it is off, it often referred to as 'toggling'. \emph{ Set line numbering to its default value } \begin{lstlisting} :set number& \end{lstlisting} \emph{ Turn on the spell checking option } \begin{lstlisting} :set spell \end{lstlisting} \emph{ Find the location of the start up configuration files } \begin{lstlisting} :version \end{lstlisting} \emph{ Change the number of spaces for a shift to 4 (with '$>$$>$' for example) } \begin{lstlisting} :set sw=4 \end{lstlisting} \begin{lstlisting} :set shiftwidth=4 ~(the same) \end{lstlisting} \emph{ Show line numbers for the whole file } \begin{lstlisting} :set number \end{lstlisting} \begin{lstlisting} :set nu ~(the same) \end{lstlisting} \emph{ Show tabs and ends of lines } \begin{lstlisting} :set list ~(':set nolist' to turn it off) \end{lstlisting} \emph{ Show partial commands in the status bar } \begin{lstlisting} :set showcmd \end{lstlisting} \emph{ Dont show the matching parenthesis when moving around the file } \begin{lstlisting} :NoMatchParen \end{lstlisting} (for some reason, this is not working in my ``vimrc'' file) \emph{ DO show the matching parenthesis when moving around the file } \begin{lstlisting} :DoMatchParen \end{lstlisting} see also :set showmatch \emph{ Some mappings to make editing the .vimrc file easier } \begin{lstlisting} :nmap ,s :source $MYVIMRC \end{lstlisting} \begin{lstlisting} :nmap ,v :arge $MYVIMRC \end{lstlisting} \begin{lstlisting} :command Vimrc arge $MYVIMRC \end{lstlisting} \emph{ Save your sessions in vim to resume later } \begin{lstlisting} :mksession! \end{lstlisting} \emph{ Make sure that vim never beeps } \begin{lstlisting} :set vb t_vb=". \end{lstlisting} \emph{ Make tab completion ignore '.o' and '.exe' and '.bak' files } \begin{lstlisting} :set wildignore=*.o,*.bak,*.exe \end{lstlisting} \subsection{The Status Line} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{hacking}] vim possibly a good book about vim \end{description} The status line is the line at the bottom of the vim window which can display information about the current file, and commands being typed by the user. \emph{ View the vim help for the status line } \begin{lstlisting} :help statusline \end{lstlisting} \emph{ Force vim to actually show a status line, } \begin{lstlisting} :set laststatus=2 \end{lstlisting} \emph{ Set a complex status line for vim } \begin{lstlisting} set statusline=[%02n]\ %f\ %(\[%M%R%H]%)%=\ %4l,%02c%2V\ %P%* \end{lstlisting} \emph{ A verbose status line with file-name, file-format, file-type (vim), ascii and } \emph{ Hex under the cursor, row and column, length of file in lines } \begin{lstlisting} :set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [ASCII=\%03.3b]\ [HEX=\%02.2B]\ [POS=%04l,%04v][%p%%]\ [LEN=%L] \end{lstlisting} \subsection{Advanced Configurations} \emph{ How to have a variant in your .vimrc for different PCs } \begin{lstlisting} if $COMPUTERNAME == "NEWPC" ab mypc vista else ab mypc dell25 endif \end{lstlisting} \subsection{Debugging The Configuration} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ find where an option was set }} \\ \hline \texttt{ :scriptnames } & List all plugins, .vimrcs loaded \\ \texttt{ :verbose set history? } & Reveals value of history and where set \\ \texttt{ :function } & List functions \\ \texttt{ :func SearchCompl } & List particular function \\ \hline \end{tabular} \end{center} \subsection{The Configuration File} In vim, the configuration file (or files) is called 'vimrc'. There maybe several configuration files, one for the current user, and one global file for all users. \emph{ Find out where your vim configuration file is } \begin{lstlisting} :echo $MYVIMRC \end{lstlisting} \begin{lstlisting} :!find / -name '*vimrc*' ~(if the above produces no information) \end{lstlisting} \emph{ Make it easy to update/reload .vimrc } \begin{lstlisting} :nmap ,s :source $VIM/.vimrc \end{lstlisting} \begin{lstlisting} :nmap ,v :e $VIM/.vimrc \end{lstlisting} \begin{lstlisting} :e $MYVIMRC ~(may edit your .vimrc whereever it might be ) \end{lstlisting} \subsection{Viminfo History File} The viminfo file is where the vim command history is stored as well as other session information. \section{Folding Text} http://www.linux.com/archive/articles/114138 'Folds' in text are a way to hide sections of text in a big document to make the document easier to read. When the text is hidden the fold is said to be 'closed' and when the text in the fold is visible then it is 'open'. \subsection{Getting Help} \emph{ View the vim help for folding } \begin{lstlisting} :help folding \end{lstlisting} \subsection{Basic Usage} \emph{ Create a fold which hides the next 2 lines } \begin{lstlisting} zf2j ~(the fold is created and the text is hidden) \end{lstlisting} \emph{ Open all folds in a document } \begin{lstlisting} zR \end{lstlisting} \emph{ Close all folds in the document } \begin{lstlisting} zM \end{lstlisting} \emph{ Open the current fold (where the cursor is) } \begin{lstlisting} zo ~(the fold is still there and can be closed again with 'zc') \end{lstlisting} \emph{ Open all the nested folds on the current line } \begin{lstlisting} zO \end{lstlisting} \emph{ Make the current paragraph a fold } \begin{lstlisting} zfap \end{lstlisting} \emph{ Create a fold from line 1 to 10 } \begin{lstlisting} :1,10 fo \end{lstlisting} \emph{ Close a fold (hide the contents of the fold) } \begin{lstlisting} zc \end{lstlisting} \emph{ Delete the fold at the cursor } \begin{lstlisting} zd \end{lstlisting} \emph{ Delete all folds } \begin{lstlisting} zE \end{lstlisting} \emph{ Delete all the text in a fold (when the fold is closed) } \begin{lstlisting} dd \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ more fold commands }} \\ \hline \texttt{ zf$\}$ } & Fold paragraph using motion \\ \texttt{ v$\}$zf } & Fold paragraph using visual \\ \texttt{ zf'a } & Make a fold up to a bookmark \\ \hline \end{tabular} \end{center} \subsection{Moving Between Folds} \emph{ Move to the previous fold (even if it is open) } \begin{lstlisting} zk \end{lstlisting} \emph{ Move to the next fold } \begin{lstlisting} zj \end{lstlisting} \subsection{Creating Folds Automatically} \emph{ Creates a fold at each indent level in the document } \begin{lstlisting} :set foldmethod=indent \end{lstlisting} \begin{lstlisting} :set fdm=indent ~(the same) \end{lstlisting} The above method is usually only useful for computer programming languages, which are indented in a consistent manner. \emph{ Create folds in a document one by one with the 'zf' command } \begin{lstlisting} :set foldmethod=manual \end{lstlisting} \emph{ Create folds between the '$<$$<$$<$' and '$>$$>$$>$' markers } \begin{lstlisting} :set foldmethod=marker foldmarker=<<<,>>> \end{lstlisting} \emph{ Create folds between '$\{$' and '$\}$' characters (this is useful for 'css') } \begin{lstlisting} :set foldmethod=marker foldmarker={,} \end{lstlisting} \subsection{Advanced Folds} \emph{ A folding method } \begin{lstlisting} vim: filetype=help foldmethod=marker foldmarker=<<<,>>> A really big section closed with a tag <<< --- remember folds can be nested --- Closing tag >>> \end{lstlisting} \section{Source Code And Vim} The vim editor is often used to write 'code' in programming languages such as c, java, or html to name only a few. The vim editor contains a number of features to make editing source code easier. \emph{ Adjust the indent level of pasted code to the file } \begin{lstlisting} ]p \end{lstlisting} \emph{ Go to the definition/declaration of the function/var under the cursor } \begin{lstlisting} gd \end{lstlisting} \emph{ Align braces in source code } \begin{lstlisting} [shift]+v, select lines, = ~([shift]+v enters visual mode) \end{lstlisting} \emph{ Use the brace-block text objects to work with blocks of code } \begin{lstlisting} diB ~(deletes everything between { and }, not including braces) \end{lstlisting} \begin{lstlisting} di} ~(the same) \end{lstlisting} \begin{lstlisting} da) ~(deletes everything between ( and ), including braces) \end{lstlisting} \emph{ Delete between quotation marks and enter new text } \begin{lstlisting} ci" ~(the cursor can be anywhere within the quotation) \end{lstlisting} \emph{ Another way to get rid of tabs } \begin{lstlisting} :set expandtab|retab \end{lstlisting} \emph{ Toggle source code folds } \begin{lstlisting} zi ~(a 'fold' temporarily hides the content of a function or method) \end{lstlisting} \emph{ Fold code on indented sections } \begin{lstlisting} :set foldmethod=indent ~(each indentation level becomes a 'fold') \end{lstlisting} \emph{ Execute 'make', and jump to the first error found } \begin{lstlisting} :make ~(make is usually used for compiling c code) \end{lstlisting} \emph{ Display the next or previous error } \begin{lstlisting} :cn :cp \end{lstlisting} \subsection{Searching Source Code} \emph{ Search for declaration of subroutine/function under cursor } \begin{lstlisting} :nmap gx yiw/^\(sub\function\)\s\+" \end{lstlisting} \subsection{File Types} \emph{ File location of specific file-type configuration files } \begin{lstlisting} /etc/ftplugin/java \end{lstlisting} \subsection{Indenting And Formatting Source Code} In order for programming source code to be easer to read and understand, it should normally be 'formatted' according to certain conventions. This is generally referred to as 'formatting' or 'indenting' the source code, although is sometimes also called 'pretty-printing'. \emph{ View which program will perform indenting with the '=' command } \begin{lstlisting} :set equalprg \end{lstlisting} (if the response is 'equalprg=' then an internal formatter will be used) \emph{ Indent the whole file using the '=' formatter } \begin{lstlisting} gg=G \end{lstlisting} \emph{ Indent the current paragraph using the built in formatter } \begin{lstlisting} ap= \end{lstlisting} \emph{ Indent the current brace $\{$$\}$ block } \begin{lstlisting} a}= \end{lstlisting} \emph{ Reformat (break and fill lines) a bash comment (starting with \#) } \begin{lstlisting} !ap par ~(the par formatter leaves the '#' at the start of the lines) \end{lstlisting} \subsection{Syntax Highlighting} When different parts of programming code is displayed in different colours or fonts according, the code may be easier to read and understand. This is referred to a 'syntax highlighting'. \emph{ See what type of source code Vim thinks the file is } \begin{lstlisting} :set filetype \end{lstlisting} (if the response is 'filetype=' then Vim cant guess) \emph{ Tell Vim that the file is java source code } \begin{lstlisting} :set filetype=java ~(this normally shouldnt be necessary) \end{lstlisting} \emph{ Turn on syntax highlighting } \begin{lstlisting} :syntax enable \end{lstlisting} \begin{lstlisting} :syntax on ~(doesnt respect the current colour-scheme) \end{lstlisting} \emph{ Turn off syntax highlighting (its pretty annoying really) } \begin{lstlisting} :syntax off \end{lstlisting} \emph{ An example of setting your own highlighting } \begin{lstlisting} :syn match DoubleSpace " " \end{lstlisting} \begin{lstlisting} :hi def DoubleSpace guibg=#e0e0e0 \end{lstlisting} \emph{ Force syntax coloring for a file that has no extension .pl } \begin{lstlisting} :set syntax=perl \end{lstlisting} \emph{ Change coloring scheme (any file in $\sim$vim/vim??/colors) } \begin{lstlisting} :colorscheme blue \end{lstlisting} \emph{ Force HTML Syntax highlighting by using a modeline } \begin{lstlisting} # vim:ft=html: \end{lstlisting} \emph{ Force syntax automatically (for a file with non-standard extension) } \begin{lstlisting} au BufRead,BufNewFile */Content.IE?/* setfiletype html \end{lstlisting} \subsection{Converting Highlighted Syntax To Html} \emph{ View the help for converting highlighted syntax } \begin{lstlisting} :help TOhtml \end{lstlisting} \emph{ Convert highlighted syntax to html (html opens in a new window) } \begin{lstlisting} :TOhtml \end{lstlisting} \begin{lstlisting} :runtime! syntax/2html.vim ~(the same, more or less) \end{lstlisting} \emph{ Convert the current line to syntax highlighted html } \begin{lstlisting} :.TOhtml \end{lstlisting} \emph{ Convert syntax to HTML using style sheets not $<$font$>$ tags } \begin{lstlisting} :let html_use_css = 1 \end{lstlisting} \begin{lstlisting} :TOhtml \end{lstlisting} \emph{ Convert with no line numbers, xhtml and css } \begin{lstlisting} :let html_number_lines = 0 \end{lstlisting} \begin{lstlisting} :let use_xhtml = 1 \end{lstlisting} \begin{lstlisting} :let html_use_css = 1 \end{lstlisting} \emph{ Convert code to syntax-coloured HTML } \begin{lstlisting} :source $VIM/syntax/2html.vim ~(untested) \end{lstlisting} \subsection{C And Cpp} \emph{ Format the next paragraph of code with the 'indent' c code formatter } \begin{lstlisting} !}indent \end{lstlisting} \begin{lstlisting} :%!indent ~(format the whole file) \end{lstlisting} \subsection{Java} Although 'indent' is designed for 'c' code it does a reasonable job with Java code as well \emph{ Format the whole file with the external program 'astyle' } \begin{lstlisting} :%!astyle ... \end{lstlisting} (astyle appears to go crazy with anonymous inner java classes) \emph{ Format the current code block (between matching $\{$$\}$ ) with 'indent' } \begin{lstlisting} !i}indent ~(see:"text objects" for an explanation of 'i}') \end{lstlisting} \emph{ Increase the indent of a code block } \begin{lstlisting} :set sw=1; >i} \end{lstlisting} \emph{ Decrease the indent of a code block } \begin{lstlisting} $' greater than and less than characters to insert tags in documents. An example of an html tag pair is '$<$em$>$big$<$/em$>$' which would display the text 'big' in an emphasized way (such as in an italic of bold font). Because of the massive growth of the web and Internet, html has become and important plain text format. In order to properly transform html one needs to actually parse it, rather than just using regular expressions. However for cases where 'near enough is good enough', one can use vim patterns to edit html files. Xml (extensible mark-up language) is similar to html and many of the commands below may also be used for xml documents \emph{ Change all the text between '$<$' and '$>$' characters } \begin{lstlisting} ci< \end{lstlisting} \emph{ Delete the text between 2 html tags } \begin{lstlisting} dit \end{lstlisting} If the original html text was 'the $<$em$>$that$<$/em$>$ big' then after the 'dit' command the text would be 'the $<$em$>$$<$/em$>$ tree' \emph{ Delete all html tags in the document, leaving text (non-greedy) } \begin{lstlisting} :%s#<[^>]\+>##g \end{lstlisting} \emph{ Delete html tags which may span several lines (non-greedy) } \begin{lstlisting} :%s#<\_.\{-1,}>##g \end{lstlisting} \emph{ Delete possibly multi-line html comments (that is: $<$!-- to --$>$) } \begin{lstlisting} :%s/// \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ using text objects with html }} \\ \hline \texttt{ di$<$ yi$<$ ci$<$ } & Delete/yank/change html tag contents \\ \texttt{ da$<$ ya$<$ ca$<$ } & Delete/Yank/Change whole HTML tag \\ \texttt{ dat dit } & Delete HTML tag pair \\ \hline \end{tabular} \end{center} \emph{ Filter all html form elements into paste register } \begin{lstlisting} :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 \end{lstlisting} \emph{ Convert a text file to html } \begin{lstlisting} :runtime! syntax/2html.vim \end{lstlisting} \emph{ Show help for converting to html } \begin{lstlisting} :h 2html \end{lstlisting} \emph{ Commands to neutralise $<$ for HTML display and publish } \emph{ Use yy@" to execute following commands } \begin{lstlisting} :w!|sav! page.html|:/^__BEGIN__/,/^__END__/s#<#\<#g|:w!|:!vimtipsftp \end{lstlisting} \emph{ Type table,,, to get $<$table$>$$<$/table$>$ } \begin{lstlisting} imap ,,, bdwa<pa>pa>kA \end{lstlisting} \section{Ascii Art} Using normal letters and characters in order to draw pictures or text effects is known as ascii art. \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ tools }} \\ \hline \texttt{ gnuplot } & Create ascii graphs and charts \\ \texttt{ figlet } & Bubble ascii text \\ \texttt{ asciiview } & View images converted to ascii art \\ \hline \end{tabular} \end{center} \emph{ Insert the text 'hello' as ascii bubble text in the document } \begin{lstlisting} :r !figlet 'hello' \end{lstlisting} \emph{ Convert the current line to ascii bubble text } \begin{lstlisting} :. !figlet \end{lstlisting} \emph{ Insert the current word as ascii bubble text in the document } \begin{lstlisting} :r !figlet "" \end{lstlisting} \emph{ Insert an ascii penguin saying hello in the at the current cursor pos } \begin{lstlisting} :r !cowsay -f tux 'hello' \end{lstlisting} \emph{ View a random jpg image as ascii art } \begin{lstlisting} :!asciiview "$(locate '*.jpg'|shuf|head -1)" \end{lstlisting} \section{Colours} \emph{ Display the RGB (Red-Green-Blue) colour under the cursor. eg \#445588 } \begin{lstlisting} :nmap c :hi Normal guibg=#=expand("") \end{lstlisting} The recipe above probably only works in the vimgui version \section{Images And Vim} Vim is a plain text editor, and so cannot display images, but it is simple to use another program to display them. \emph{ A mapping ',o' to display the image file name under the cursor } \begin{lstlisting} :nmap ,o :!feh \end{lstlisting} \emph{ Map `` i'' $<$space$>$ i to search for the image file name under the cursor } \begin{lstlisting} :nmap i :!locate '' \end{lstlisting} \emph{ Map ``,i'' to search for jpg images named like the word, and display 1 } \begin{lstlisting} :nmap ,i :!locate '.jpg'\|head -1\|xargs display \end{lstlisting} \emph{ Map ``,i'' to search for the current image and display the 1st match } \begin{lstlisting} :nmap ,i :!locate ''\|head -1\|xargs feh \end{lstlisting} \emph{ Map ``,i'' to search for the current image and display a random match } \begin{lstlisting} :nmap ,i :!locate ''\|shuf\|head -1\|xargs feh \end{lstlisting} \emph{ Map ``,i'' to search for the current image and display a random match } \begin{lstlisting} :nmap ,i :!locate ''\|shuf\|head -1\|xargs feh \end{lstlisting} \emph{ Map ``,i'' to search for png images whose names contain the text } \emph{ Of the current word, and to display the first 200 of them } \begin{lstlisting} :nmap ,i :!feh -m $(locate '**.png'\|head -200) \end{lstlisting} text \emph{ The same as above but display in a random order } \begin{lstlisting} :nmap ,i :!feh -m $(locate '**.png'\|shuf\|head -200) \end{lstlisting} \section{Latex And Vim} LaTeX is a system for typesetting documents into publish-quality pdf and postscript format. \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://www.vmunix.com/vim/howto/latex.html}] \end{description} \emph{ Set up a mapping to run \LaTeX{} on the current file } \begin{lstlisting} :map ,rl :!latex % \end{lstlisting} \emph{ Automatically assign a command to the $<$f1$>$ key when .tex file is opened } \begin{lstlisting} :autocmd bufenter *.tex map :!latex % \end{lstlisting} \section{Using The Shell} One of the great powers of the vim text editor is that it allows interaction with the operating system 'shell'. (A shell is a program which interprets commands typed by the user in a (usually) black box called a 'terminal'). The commands below are oriented towards using the 'bash' shell on a Unix style operating system such as Mac OSX or Linux but some of these commands could be modified to run on a Microsoft Windows computer, especially if 'cygwin' is installed. \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Get output from shell commands }} \\ \hline \texttt{ :put=glob('**') } & Same as above \\ \texttt{ !!date } & Replace the current line with todays date \\ \hline \end{tabular} \end{center} \emph{ Insert a list of all the files in the current folder } \begin{lstlisting} :r!ls -R \end{lstlisting} \emph{ Insert all lines from the text file 'eg.txt' which start with 'one' } \begin{lstlisting} :r !grep "^ *one" eg.txt \end{lstlisting} The matching lines from the text file 'eg.txt' are inserted in the current document at the current cursor position. \emph{ Execute the previous shell command } \begin{lstlisting} :!! \end{lstlisting} \emph{ Execute the current document as a unix bash script } \begin{lstlisting} :w !bash \end{lstlisting} \begin{lstlisting} :w !sh ~(nearly the same) \end{lstlisting} \emph{ Execute the current line (where the cursor is) as a bash command } \begin{lstlisting} :.w !bash \end{lstlisting} \emph{ Empty the text file 'test.txt' (beware, all content is lost) } \begin{lstlisting} :!>test.txt \end{lstlisting} \emph{ Map function-key 9 to process the current file with the php interpreter } \begin{lstlisting} map :w:!c:/php/php % ~(on microsoft windows) \end{lstlisting} \begin{lstlisting} map :w:!php % ~(on a mac osx or linux) \end{lstlisting} \emph{ Map function-key 2 to process the current file with perl } \begin{lstlisting} map :w:!perl -c % \end{lstlisting} \emph{ Create a new file for each line of file eg 1.txt,2.txt,3,txt etc } \begin{lstlisting} :g/^/exe ".w ".line(".").".txt" \end{lstlisting} \subsection{Bash And Vim} 'Bash' is the most widely used unix-type shell. By default it is installed on Apple Macintosh OsX and on the majority of Linux installations. It can be run on Microsoft windows in a variety of ways, one of which is to install the 'cygwin' package. \emph{ A bash function to search for the file and open in vi editor. } \begin{lstlisting} vifind() { vi $(find . -name "$1") } \end{lstlisting} \subsection{Batch Mode} Batch mode means running vim from the command-line non-interactively. This document is oriented towards running vim in a Unix-type environment such as Mac OSX or Linux. \emph{ Get help for the command-line vim options } \begin{lstlisting} vim -h \end{lstlisting} \begin{lstlisting} man vim \end{lstlisting} \emph{ Open 2 files into a split window } \begin{lstlisting} vim -o file1 file2 \end{lstlisting} \begin{lstlisting} gvim -o file1 file2 ~(the same using graphical vim) \end{lstlisting} \emph{ Edit only some lines of the input stream } \begin{lstlisting} cat xx | vim - -c "v/^\d\d\|^[3-9]/d " \end{lstlisting} \emph{ Edit the list of files and folders using 'graphical vim' } \begin{lstlisting} ls | gvim - \end{lstlisting} \emph{ Execute 2 vim command after opening the file 'test.c' } \begin{lstlisting} vim -c "%s/ABC/DEF/ge | update" test.c \end{lstlisting} \emph{ Automate editing of a file (Ex commands in convert.vim) } \begin{lstlisting} vim -s "convert.vim" file.c \end{lstlisting} \emph{ Load VIM without the .vimrc or any plug-ins } \begin{lstlisting} vim -u NONE -U NONE -N \end{lstlisting} \emph{ Access paste buffer contents (put in a script/batch file) } \begin{lstlisting} gvim -c 'normal ggdG"*p' c:/aaa/xp \end{lstlisting} \emph{ Print paste contents to the default printer } \begin{lstlisting} gvim -c 's/^/\=@*/|hardcopy!|q!' \end{lstlisting} \emph{ Substitue 'ABC' with 'DEF' on all '.c' files in the current folder } \begin{lstlisting} vim -c "argdo %s/ABC/DEF/ge | update" *.c \end{lstlisting} \emph{ Remove blocks of text from all '.c' files in the current folder } \begin{lstlisting} vim -c "argdo /begin/+1,/end/-1g/^/d | update" *.c \end{lstlisting} \subsection{Piping Text Fragments} It is possible to take a section or chunk of the document being edited and 'pipe' it to a program or script running in the bash (or other shell). This is an important technique since it allows the user to employ the power of the linux shell to perform some task with text from the document. Using this technique the text within the document is unchanged (unlike the 'filtering' technique, which is similar, and which is treated elsewhere in this document). \emph{ Pipe lines 22,25 though the 'sed' bash shell command } \begin{lstlisting} :22,25w !sed 's/e/E/g' ~(the original lines are not changed) \end{lstlisting} \emph{ Display all following lines without any '\^{}' carat characters } \begin{lstlisting} :.,$w !s/\^//g' ~(the lines are piped through 'sed') \end{lstlisting} \emph{ Save lines after this one in 'new.txt' after removing comment (\#) lines } \begin{lstlisting} :.,$w !grep -v '^#' >> new.txt \end{lstlisting} \emph{ Execute the current line as a bash command and insert results } \begin{lstlisting} :. !bash \end{lstlisting} \emph{ Execute the current line as a bash command (doesn't insert results) } \begin{lstlisting} :.w !bash \end{lstlisting} \emph{ Pipe all lines from current to next blank line to sed } \begin{lstlisting} :.,/^ *$/w ! sed 's/e/E/g' \end{lstlisting} \begin{lstlisting} :.,/^\s$/w ! sed 's/e/E/g' ~(the same, almost) \end{lstlisting} \emph{ Pipe all lines from current back to previous blank line to 'sed' } \begin{lstlisting} :.,/^\s$/w ! sed 's/e/E/g' ~(prompts the user to swap order) \end{lstlisting} \emph{ View lines in this and next 2 paragraphs with lines having 'tree' } \begin{lstlisting} !3apw !grep -v tree | less \end{lstlisting} \emph{ Compile the current paragraph with pdflatex and save as 'new.pdf' } \begin{lstlisting} !apw !pdflatex -jobname new \end{lstlisting} \emph{ Pipe from the line after the 1st previous line having a '*' star } \emph{ To the line before the next line containing a ',' comma } \begin{lstlisting} ?\*?+1,/,/-1w !sed 's/e/E/g' ~(this is quite a complex range) \end{lstlisting} \emph{ Make a command to append a paragraph from this file to 'snip.txt' } \begin{lstlisting} :com! Append ?^ *$?+1,/^ *$/-1w !cat - >> ~/snip.txt \end{lstlisting} \emph{ Make a command to append a paragraph from this file to another file } \begin{lstlisting} :com! -nargs=1 Append ?^ *$?+1,/^ *$/-1w !cat - >> ~/ \end{lstlisting} \emph{ A mapping ',x' to append a paragraph from this file to 'snip.txt' } \begin{lstlisting} :nmap ,x :?^ *$?+1,/^ *$/-1w !cat - >> ~/snip.txt \end{lstlisting} \emph{ A simpler way to do the same thing } \begin{lstlisting} :nmap ,x !apw !cat - >> ~/snip.txt \end{lstlisting} \begin{lstlisting} :nmap ,x !apw !cat - >> ~/snip.txt \end{lstlisting} \emph{ A mapping ',x' to append 3 paragraphs from this file to 'snip.txt' } \begin{lstlisting} :nmap ,x !3apw !cat - >> ~/snip.txt \end{lstlisting} This can be run with the command ':Append junk.txt' which will append the current paragraph to the file 'junk.txt' in the users home folder. \subsection{Gotchas} In the following recipes, the space before the '!' exclamation mark is very important, since without it the command does something very different and possibly destructive. \emph{ Remember the space } \begin{lstlisting} :22,25w!sed 's/e/E/g' ~(No!!! wrong, may truncate the current file) \end{lstlisting} \section{Using External Programs} \emph{ Sort the current file } \begin{lstlisting} :%!sort -u \end{lstlisting} \emph{ Sort the current paragraph (before and after the cursor) } \begin{lstlisting} !apsort -u \end{lstlisting} \emph{ Look up help for the keyword under the cursor } \begin{lstlisting} K \end{lstlisting} \emph{ Change the program used to look up keyword help with 'K' } \begin{lstlisting} :set keywordprg=info \end{lstlisting} The default help program is usually 'man' \emph{ Map ',ee' to execute the word under the cursor in bash } \begin{lstlisting} :map ,ee :! \end{lstlisting} \emph{ Execute 2 shell commands (change to parent folder, and show 'tree.txt') } \begin{lstlisting} :!cd ..; cat tree.txt \end{lstlisting} \subsection{Opening Files} \emph{ Make a normal mode command ',o' to open a file with the right program } \begin{lstlisting} :nmap ,f :!xdg-open \end{lstlisting} \begin{lstlisting} :nmap ,f :!open ~(for Mac OSX) \end{lstlisting} If the cursor is positioned over some text which says '[a:/usr/share/httpd/icons/hand.up.png]' for example, and the user types ',f' in normal mode, then the file /usr/share/.../hand.up.png will be opened in an image view program. \section{Modes In Vim} The concept of modes in vim is important, but is quite a complex topic. \subsection{Switching Between Modes} \emph{ Switch to normal mode from command mode } \begin{lstlisting} :normal \end{lstlisting} \subsection{Insert Mode} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ editing/moving within the current insert }} \\ \hline \texttt{ $<$C-U$>$ } & Delete all entered \\ \texttt{ $<$C-W$>$ } & Delete last word \\ \texttt{ $<$c-leftarrow$>$$<$c-rightarrow$>$ } & Jump one word backwards/forwards \\ \texttt{ $<$C-X$>$$<$C-E$>$,$<$C-X$>$$<$C-Y$>$ } & Scroll while staying put in insert \\ \texttt{ $<$C-N$>$$<$C-P$>$ } & Completes a word in insert mode \\ \texttt{ $<$C-X$>$$<$C-L$>$ } & Complete the line in insert mode \\ \hline \end{tabular} \end{center} \subsection{Normal Mode} One of the particularly confusing things about vim is that 'normal' mode does not seem at all normal, in the sense that one is unable to type normally to insert text in the document. When vim first starts it is in 'normal' mode, and you can enter commands such as 'dd' which deletes the current line, or 'j' which moves down 1 line in the document. To actually type text into the document you need to enter 'insert' mode by typing 'i'. \emph{ How to paste ``normal commands'' without entering insert mode } \begin{lstlisting} :norm qqy$jq \end{lstlisting} \subsection{Command Mode} In vim command mode (which seems very similar to 'ex' mode) is entered when you type a ':' colon character in 'normal' mode. \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ pulling objects onto command/search line }} \\ \hline \texttt{ $<$C-R$>$$<$C-W$>$ } & Pull word under the cursor into a command line or search \\ \texttt{ $<$C-R$>$$<$C-A$>$ } & Pull WORD under the cursor into a command line or search \\ \texttt{ $<$C-R$>$- } & Pull small register (also insert mode) \\ \texttt{ $<$C-R$>$[0-9a-z] } & Pull named registers (also insert mode) \\ \texttt{ $<$C-R$>$\% } & Pull file name (also \#) (also insert mode) \\ \texttt{ $<$C-R$>$=somevar } & Pull contents of a variable (eg :let sray=``ray[0-9]'') \\ \hline \end{tabular} \end{center} \emph{ A map to delete all lines containing only current word } \begin{lstlisting} nmap ,dd :g/^ *$/d \end{lstlisting} \section{Visual Mode} Visual is the newest and supposedly the most intuitive editing mode. It allows you to select text in the document by 'highlighting' it and them copying, deleting and pasting or anything else. Once you have selected an area of the text by highlighting it, you can then apply any normal vim command and it will be applied to that area. \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Basic Visual Mode Commands }} \\ \hline \texttt{ v } & Enter visual mode \\ \texttt{ $<$escape$>$ } & Exit visual mode \\ \texttt{ vv } & Exit visual mode \\ \texttt{ v\$ } & Enter visual mode and select to the end of the line \\ \texttt{ vap } & Enter visual mode and select the current paragraph \\ \texttt{ vapd } & Delete the current paragraph after highlighting it \\ \texttt{ V } & Enter visual mode and select the whole line \\ \texttt{ gv } & Reselect last visual area \\ \texttt{ o } & Navigate visual area \\ \texttt{ ``*y or ''+y } & Yank visual area into paste buffer \\ \texttt{ V\% } & Visualise what you match \\ \texttt{ v$\}$j } & Join visual block \\ \texttt{ v$\}$gj } & Join visual block w/o adding spaces \\ \texttt{ `[v`] } & Highlight last insert \\ \texttt{ :\%s/\textbackslash \%Vold/new/g } & Do a substitute on last visual area \\ \hline \end{tabular} \end{center} \emph{ Select a line visually } \begin{lstlisting} V ~(then use 'k' and 'j' to select lines above and below as well) \end{lstlisting} \emph{ Select until the end of the line visually } \begin{lstlisting} v$ \end{lstlisting} \emph{ Visually select until the end of the file } \begin{lstlisting} VG \end{lstlisting} \emph{ Substituting a visual area } \emph{ Select visual area as usual (:h visual) then type :s/Emacs/Vim/ etc } \begin{lstlisting} :'<,'>s/emacs/vim/g ~(remember you dont type the '<.'>) \end{lstlisting} \begin{lstlisting} gv ~( Re-select the previous visual area ) \end{lstlisting} \emph{ Overwrite a visual-block of text with another such block } \begin{lstlisting} Pick the first block: control-v y \end{lstlisting} \begin{lstlisting} Pick the second block: control-v P \end{lstlisting} \emph{ Operating a recording on a visual block } \begin{lstlisting} 1) define recording/register qq:s/ to/ from/g^Mq 2) Define Visual BLOCK V} 3) hit : and the following appears :'<,'> 4)Complete as follows :'<,'>norm @q \end{lstlisting} \emph{ Visual searching } \begin{lstlisting} :vmap // y/" ~( search for visually highlighted text) \end{lstlisting} \begin{lstlisting} :vmap // y/=escape(@", '\\/.*$^~[]') : with spec chars \end{lstlisting} \emph{ Pull visually highlighted text into the left-hand side of a substitute } \begin{lstlisting} :vmap z :%s/\<*\>/ \end{lstlisting} \emph{ Copy a set of columns using a visual block } \emph{ Visual block (or column-wise selection) (NOT BY ordinary v command) } \begin{lstlisting} \end{lstlisting} Then select the block with motion commands (win32 $<$C-Q$>$) and then a command such as c,d,y,r ... \emph{ Wrap the html tags '$<$b$>$' and '$<$/b$>$' around visually selected text } \begin{lstlisting} :vmap sb "zdiz \end{lstlisting} \emph{ Wrap $<$?= ?$>$ around VISUALLY selected Text } \begin{lstlisting} :vmap st "zdiz ?> \end{lstlisting} \section{Vim Sessions} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Following 4 maps enable text transfer between VIM sessions }} \\ \hline \texttt{ :map $<$f7$>$ :'a,'bw! c:/aaa/x } & Save text to file x \\ \texttt{ :map $<$f8$>$ :r c:/aaa/x } & Retrieve text \\ \texttt{ :map $<$f11$>$ :.w! c:/aaa/xr$<$CR$>$ } & Store current line \\ \texttt{ :map $<$f12$>$ :r c:/aaa/xr$<$CR$>$ } & Retrieve current line \\ \texttt{ :map , } & List of maps beginning , \\ \hline \end{tabular} \end{center} \section{Command Mappings} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_1)}] \end{description} A 'mapping' allows the user to use a key or keys to carry out a command or a series of commands. They are like 'shortcuts'. Put mappings in $\sim$/.vimrc (without the first colon) to make them permanent. When mapping a keystroke or a combination of keys, you should consider what that combination already does (if anything) and whether you really want to override that default action \emph{ Show the vim help for creating command mappings } \begin{lstlisting} :help key-mapping \end{lstlisting} \emph{ Show current macros, or mappings } \begin{lstlisting} :map \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ some example mappings }} \\ \hline \begin{lstlisting} :map dd - map to delete a line. \end{lstlisting} \begin{lstlisting} :map dd - map to delete a line. \end{lstlisting} \begin{lstlisting} :map dd - map to delete a line. \end{lstlisting} \hline \end{tabular} \end{center} \emph{ Remove the mapping for 'hh' } \begin{lstlisting} unmap hh \end{lstlisting} \emph{ Map the function key f5 to delete a line } \begin{lstlisting} :map dd \end{lstlisting} \emph{ Map ',hh' to insert 'hello' (from insert mode) } \begin{lstlisting} :map ,hh ihello \end{lstlisting} \emph{ Map a $<$space$>$ followed by an 'n' to switch to the next open file } \begin{lstlisting} :nmap n :bn \end{lstlisting} \emph{ Create a mapping which calls a command } \begin{lstlisting} :map ,test :Test \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ different types of mappings }} \\ \hline \texttt{ :cmap } & Make a mapping in command mode \\ \texttt{ :Imap } & Make a macro in insert and command line mode \\ \texttt{ :imap } & Make a macro in insert mode \\ \hline \end{tabular} \end{center} \emph{ Map ',w' to search for . or , or ; but only apply to this buffer } \begin{lstlisting} :map ,w /[.,;] \end{lstlisting} \emph{ Map ',h' to search for 'Header' but dont echo on the command line } \begin{lstlisting} :map ,h /Header \end{lstlisting} \subsection{Using Functions In Mappings} To use a Vim function within a mapping, the idiom $<$C-R$>$=functionname(...) needs to be used \emph{ Map [f2] to insert the current date and time after the cursor } \begin{lstlisting} :map a=strftime("%c") \end{lstlisting} \emph{ Map ',r' to type the start of a replacement with a word under the cursor } \begin{lstlisting} :nmap ,r :%s/=expand("")//gc \end{lstlisting} \emph{ Cword, cWORD, cfile } \begin{lstlisting} is the word under the cursor \end{lstlisting} \begin{lstlisting} is the path under the cursor \end{lstlisting} \subsection{Example Mappings} \emph{ Map ,ww to write out text from the cursor until 'big' to 'junk.txt' } \begin{lstlisting} map ,ww !/bigw junk.txt \end{lstlisting} \begin{lstlisting} map ,ww !/bigw junk.txt ~(the same) \end{lstlisting} \emph{ Mapping 2 commands, ',mm' saves the file and goes to the next word 'big' } \begin{lstlisting} map ,mm w /big \end{lstlisting} \emph{ Map ',ll' to underline the current line with dashes '-' } \begin{lstlisting} map ,ll yyp:s/[ ]*$// \| s/[ ]*$// \| s/[^ ]/-/g \| s/- /--/g \end{lstlisting} (the dashed underline will have gaps if the words have 2 space gaps) \emph{ Map $<$space$>$l to add the current paragraph from this file to 'snip.txt' } \begin{lstlisting} :nmap l :?^ *$?+1,/^ *$/-1w !cat - >> ~/snip.txt \end{lstlisting} \begin{lstlisting} :nmap l !apw !cat - >> ~/snip.txt ~(the same) \end{lstlisting} \subsection{Saving Mappings} To save mappings, place them in the 'vimrc' file and then they will be available everytime you use vim. In the 'vimrc' file the mappings should not begin with a ':' colon. \emph{ Write current mappings and settings to file 'map.txt' } \begin{lstlisting} :mk map.txt \end{lstlisting} \subsection{Imap} Imapping's occur when the vim editor is in 'insert' mode, that is, when you are entering text into the document. \emph{ Remove an insert mode mapping for the 'jj' key combination } \begin{lstlisting} :iunmap jj \end{lstlisting} \emph{ Map tab to show all available vim functions } \begin{lstlisting} :imap \end{lstlisting} \subsection{Nmap} Nmap is used to create 'mappings' when the vim editor is in 'normal' mode, that is the mode when you can move about the document with 'jklh' etc. \emph{ Map ',c' to paste the current document line into the command line } \begin{lstlisting} :nmap ,c yy:" \end{lstlisting} \begin{lstlisting} :nmap ,c "byy:b ~(the same, but a bit better) \end{lstlisting} \emph{ Search for declaration of subroutine/function under cursor } \begin{lstlisting} :nmap gx yiw/^\(sub\function\)\s\+" \end{lstlisting} \subsection{Advanced Mappings} \emph{ A function which checks if a mapping exists } \begin{lstlisting} function! CheckMap() if empty(mapcheck('', 'i')) return "No" else return "Yes" endif endfunction \end{lstlisting} \subsection{Traps With Mappings} \emph{ In a map it is necessary to backslash the '\textbackslash ' character } \begin{lstlisting} map /price only\\|versus/ \end{lstlisting} \section{Keycodes} Vim uses special key codes when including certain keys in mappings or commands. The case of the special key-codes is not important, so you may write either '$<$esc$>$' or '$<$ESC$>$' in your mappings. \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://www.vim.org/htmldoc/intro.html\#\%3CBar\%3E}] a list of all special key codes for use in mappings and commands \end{description} \emph{ Show all the special key codes usable in mappings and commands } \begin{lstlisting} :help keycodes \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ mapping special keys }} \\ \hline \texttt{ $<$esc$>$ } & The $<$escape$>$ key \\ \texttt{ $<$enter$>$ or $<$cr$>$ or $<$return$>$ } & The \Enter key \\ \texttt{ $<$space$>$ } & The space key \\ \texttt{ $<$left$>$ } & The cursor left \\ \texttt{ $<$right$>$ } & The cursor right \\ \texttt{ $<$LEADER$>$ } & Normally \ \\ \texttt{ $<$SILENT$>$ } & No hanging shell window \\ \texttt{ $<$BACKSPACE$>$ } & Backspace \\ \texttt{ $<$BAR$>$ } & The '|' pipe character \\ \hline \end{tabular} \end{center} \section{Abbreviations} Abbreviations in Vim allow you to automatically replace a piece of text which you type in a document with another piece of text. This is useful for corrected very common spelling errors or for quickly typing long repetitive words or phrases. \emph{ Automatically replace the text ``dont'' with ``don't'' } \begin{lstlisting} :ab dont don't \end{lstlisting} An abbreviation is activated after typing a space or newline after the abbreviation. \emph{ Stop automatically replacing the word 'dont' with something else } \begin{lstlisting} :unab dont \end{lstlisting} \emph{ Automatically exchange the text 'frr' for 'Fiscal Responsibility' } \begin{lstlisting} :ab frr Fiscal Responsibility \end{lstlisting} \begin{lstlisting} :abbr frr Fiscal Responsibility ~(the same) \end{lstlisting} \subsection{Viewing Abbreviations} \emph{ Show all abbreviations which are currently available } \begin{lstlisting} :abbr \end{lstlisting} \emph{ Show all abbreviations which begin with 'php' } \begin{lstlisting} :ab php \end{lstlisting} \subsection{Making New Abbreviations} \emph{ Define an abbreviation which inserts several lines of text } \begin{lstlisting} :ab poem froth and foamhere alone \end{lstlisting} \emph{ Create an abbreviation which inserts text then searches for 'rain' } \begin{lstlisting} :ab sss snake/rain \end{lstlisting} \emph{ Define an abbreviation in the 'vimrc' file, without the colon ':' } \begin{lstlisting} ab doesnt doesn't \end{lstlisting} \emph{ Activate different abbreviations in your .vimrc for different PCs } \begin{lstlisting} if $COMPUTERNAME == "NEWPC" ab mypc vista else ab mypc dell25 endif \end{lstlisting} \section{Creating New Commands} A command is anything written after a colon ':'. New commands can be created in Vim. User defined commands must begin with a capital letter. \emph{ Define the command 'Boo' to delete the current sentence } \begin{lstlisting} :com! Boo normal das \end{lstlisting} (normal switches from command to normal mode) (this command can be used by typing '\Esc:Boo') \emph{ A command 'Test' which find the next occurrence of '==' } \begin{lstlisting} :com! Look normal /== \end{lstlisting} \begin{lstlisting} :com! Look normal /==/ ~(exactly the same) \end{lstlisting} \emph{ A command 'TT' which puts 'tree' after the next line starting with '\#' } \begin{lstlisting} :com! TT normal /^ *#otree \end{lstlisting} \emph{ The command 'J' adds 'tree' after next blank line and saves the file } \begin{lstlisting} com! J normal /^ *$/otree:w \end{lstlisting} \emph{ The command 'Gr' adds 'grass' 2 lines after the next blank line } \begin{lstlisting} com! J normal /^ *$/+2otree \end{lstlisting} \emph{ View help on how to make user defined commands } \begin{lstlisting} :help command \end{lstlisting} \emph{ See the currently user defined commands } \begin{lstlisting} :command \end{lstlisting} \begin{lstlisting} :com ~(the same) \end{lstlisting} \emph{ Delete all new commands which have been defined by the user } \begin{lstlisting} :comclear \end{lstlisting} \emph{ Create a new command 'Folder' which lists the files in the current folder } \begin{lstlisting} :com Folder !ls \end{lstlisting} \begin{lstlisting} :command Folder !ls ~(the same) \end{lstlisting} \begin{lstlisting} :command! Folder !ls ~(the same, but over-rides an existing command) \end{lstlisting} \emph{ Define command 'squeeze' which combines multiple consecutive empty lines } \begin{lstlisting} :command! Squeeze g/^\s*$/,/\S/-j|s/.*// \end{lstlisting} \emph{ Define command 'Nocomment' which lists the current file without comments } \begin{lstlisting} command! Nocomment !cat % | grep -v '^ *#' | less \end{lstlisting} This command can be executed with ':Nocomment' within vim \emph{ Define a command which shows lines having only uppercase letters } \begin{lstlisting} command! Upper !sed -n ';/^ *[[:upper:] ]\{2,\}$/p' % | less \end{lstlisting} \emph{ Delete everything after the current line to the end of the file } \begin{lstlisting} :com Ddel +,$d \end{lstlisting} \emph{ A command to insert the file 'book.txt' at the current cursor position } \begin{lstlisting} :com Get r book.txt \end{lstlisting} \emph{ A command to insert the contents of the url which is under the cursor } \begin{lstlisting} :com Get r \end{lstlisting} \begin{lstlisting} :Get ~(execute the command just defined) \end{lstlisting} \emph{ A command to echo the url which is under the cursor } \begin{lstlisting} :com Get echo expand("") \end{lstlisting} \subsection{With Arguments} \emph{ Rename the current buffer with filename completion } \begin{lstlisting} :com -nargs=1 -bang -complete=file Ren f |w \end{lstlisting} \emph{ Define a command 'Say' with one argument which just echos the given text } \begin{lstlisting} :com -nargs=1 Say :echo "" \end{lstlisting} \begin{lstlisting} :command -nargs=1 Say :echo "" ~(the same) \end{lstlisting} (This command can be invoked with :Say text) \emph{ Create a command 'Book bookfile' which edits a text file } \begin{lstlisting} command! -nargs=1 Book arge ~/.txt \end{lstlisting} So we can use this command by typing ':Book tree' to edit the file $\sim$/tree.txt \emph{ Create a new command 'Sing' which accepts a variable number of arguments } \begin{lstlisting} com -nargs=* Sing \end{lstlisting} \subsection{With Line Ranges} \emph{ Define command 'Rep' which replaces a range with the contents of a file } \begin{lstlisting} :com -range -nargs=1 -complete=file Rep -pu_|,d|r |d \end{lstlisting} \emph{ Define command 'Lines' which counts the number of lines in a range } \begin{lstlisting} :com! -range -nargs=0 Lines echo - + 1 "lines" \end{lstlisting} (this can be executed with ':.,\$ Lines' for example) \emph{ A command 'Comp' which pipes the given range to 'sed' } \begin{lstlisting} :com! -range -nargs=0 Comp ,w !sed 's/e/E/g' \end{lstlisting} \begin{lstlisting} :com! -range Comp ,w !sed 's/e/E/g' ~(the same) \end{lstlisting} (this could be executed with ':.,\$ Comp' for example) \emph{ Make a command to compile to pdf the given range and save as 'new.pdf' } \begin{lstlisting} :com! -range Pdf ,w !pdflatex -jobname new \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ special command parameters }} \\ \hline \texttt{ $<$line1$>$ } & The first line of the range, with '-range' option \\ \texttt{ $<$line2$>$ } & Another line in the range \\ \texttt{ $<$bang$>$ } & \\ \hline \end{tabular} \end{center} \subsection{Commands Using Commands} We can define new commands which can then be used in other new commands, for example: \emph{ Use a previous user-defined command in another for finding images } \begin{lstlisting} command! -nargs=1 Findi !find ~ -name '*.' \end{lstlisting} \begin{lstlisting} command! Findjpg Findi jpg \end{lstlisting} \subsection{Commands And Mappings} Commands can use argument specified after the command name but mappings cannot (since they are entered in 'normal' mode) Mappings can also use a previously defined command. \section{Recording And Using Macros} A 'macro' in vim is a series of commands which a user carries out while 'recording'. The user is then able to replay that series of commands by invoking the macro. In vim, the names of macros are single letters and are invoked with '@n' where 'n' is the name of the macro. \emph{ Start recording a macro named 'q' } \begin{lstlisting} qq \end{lstlisting} \emph{ Stop recording a macro } \begin{lstlisting} q \end{lstlisting} \emph{ Execute (replay) the macro } \begin{lstlisting} @q \end{lstlisting} \emph{ Repeat the macro } \begin{lstlisting} @@ \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ macro commands }} \\ \hline \texttt{ @q } & To execute \\ \texttt{ @@ } & To Repeat \\ \texttt{ 5@@ } & To Repeat 5 times \\ \texttt{ qQ@qq } & Make an existing recording q recursive \\ \hline \end{tabular} \end{center} \emph{ Editing a register/recording } \begin{lstlisting} "qp ~(display contents of register q (normal mode)) \end{lstlisting} \begin{lstlisting} q ~(display contents of register q (insert mode)) \end{lstlisting} \emph{ You can now see recording contents, edit as required } \begin{lstlisting} "qdd ~(put changed contacts back into q) \end{lstlisting} \begin{lstlisting} @q ~(execute recording/register q) \end{lstlisting} \emph{ Combining a recording with a map (to end up in command mode) } \begin{lstlisting} :nnoremap ] @q:updatebd \end{lstlisting} \section{Autocommands} An 'autocommand' is a way of specifying a command which will get automatically executed when a particular event occurs, for example, when a particular file or type of file is opened etc. \emph{ An autocommand to place a book mark 'H' in the help files when leaving } \begin{lstlisting} au BufLeave * if &ft == "help" | mark H | endif \end{lstlisting} \emph{ Automatically assign commands to function keys when '.tex' files opened } \begin{lstlisting} :autocmd bufenter *.tex map :!latex % \end{lstlisting} \begin{lstlisting} :autocmd bufenter *.tex map :!xdvi -hush %<.dvi& \end{lstlisting} \emph{ Automatically delete trailing Dos-returns,whitespace } \begin{lstlisting} autocmd BufRead * silent! %s/[\r \t]\+$// \end{lstlisting} \begin{lstlisting} autocmd BufEnter *.php :%s/[ \t\r]\+$//e \end{lstlisting} \emph{ Perform an action on a particular file or file type } \begin{lstlisting} autocmd VimEnter c:/intranet/note011.txt normal! ggVGg? \end{lstlisting} \begin{lstlisting} autocmd FileType *.pl exec('set fileformats=unix') \end{lstlisting} \section{Functions} These functions can be used in mappings, and scripts. User defined functions need to start with a Capital letter.` \subsection{Help For Functions} \emph{ Get help on the built-in functions for vim } \begin{lstlisting} :help functions ~(an alphabetical function list) \end{lstlisting} \begin{lstlisting} :help function-list ~(function list categorized by purpose) \end{lstlisting} \begin{lstlisting} :h functions ~(the same) \end{lstlisting} \emph{ Get help for the 'substitute' function } \begin{lstlisting} :h substitute() \end{lstlisting} \emph{ Get help for the 'getline' function } \begin{lstlisting} :h getline() \end{lstlisting} \begin{lstlisting} :h getline \end{lstlisting} Sometimes it is possible to omit the parenthesis \emph{ See all user defined functions } \begin{lstlisting} :functions \end{lstlisting} \emph{ List the code for the Leapyear function } \begin{lstlisting} :function Leapyear \end{lstlisting} \emph{ Delete the Leapyear function } \begin{lstlisting} :delfuncton Leapyear \end{lstlisting} \emph{ Call a function for a range } \begin{lstlisting} :10,15call Func(...) \end{lstlisting} \emph{ Redefine a function } \begin{lstlisting} :function! Func() \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ vim functions }} \\ \hline \texttt{ getline(".") } & Returns the text of the current line \\ \texttt{ line(".") } & Returns the number of the current line \\ \hline \end{tabular} \end{center} \emph{ See a pop-up box with lots of inbuilt vim functions } \begin{lstlisting} [control-x] [control-v] \end{lstlisting} \subsection{Using Functions} \emph{ Display the line under the cursor } \begin{lstlisting} :echo getline(".") \end{lstlisting} \subsection{Built In Functions} Vim contains a large selection of built in functions which are available for use in commands, mappings, scripts etc \emph{ Get help for the 'line' function } \begin{lstlisting} help line \end{lstlisting} \emph{ Display the line number of the last line in the file using 'line' } \begin{lstlisting} :echo line('$') \end{lstlisting} \emph{ Insert the line number of the last line into the document. } \begin{lstlisting} :.put=line('$') \end{lstlisting} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ values usable with the 'line' function }} \\ \hline \texttt{ . } & The cursor position \\ \texttt{ \$ } & The last line in the current buffer \\ \texttt{ 'x } & Position of mark x (if the mark is not set, 0 is returned) \\ \texttt{ w0 } & First line visible in current window \\ \texttt{ w\$ } & Last line visible in current window \\ \hline \end{tabular} \end{center} \subsection{Creating New Functions} \begin{lstlisting} help keycodes \end{lstlisting} \emph{ Function to delete duplicate lines } \begin{lstlisting} function! Del() if getline(".") == getline(line(".") - 1) norm dd endif endfunction \end{lstlisting} \emph{ A function to save word under cursor to a file } \begin{lstlisting} function! SaveWord() normal yiw exe ':!echo '.@0.' >> word.txt' endfunction map ,p :call SaveWord() \end{lstlisting} \emph{ An example of creating and calling a function with a range } \begin{lstlisting} :function Mynumber(arg) : echo line(".") . " " . a:arg :endfunction :1,5call Mynumber(getline(".")) \end{lstlisting} \emph{ A function to toggle syntax highlight on and off } \begin{lstlisting} function! ToggleSyntax() if exists("g:syntax_on") syntax off else syntax enable endif endfunction nmap ;s :call ToggleSyntax() ,,,, This function includes a mapping to make it easy to call the function. EXAMPLE FUNCTIONS .... * advanced incrementing. put the following in the vimrc \begin{lstlisting} let g:I=0 function! INC(increment) let g:I =g:I + a:increment return g:I endfunction \end{lstlisting} \section{Scripting Vim} Vim, like all good overblown software, has its own scripting language built into it, which may be of use if you wish to automate some editing process and you are unable to do it with mappings, macros, abbreviations, user-defined commands, bash shell filters, or any of the other myriad tools available with vim. \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{www.ibm.com/developerworks/linux/library/l-vim-script-1/index.html}] a good article about scripting in vim \end{description} \emph{ View some help for programming with vim } \begin{lstlisting} :help eval \end{lstlisting} \emph{ View an introduction for scripting vim } \begin{lstlisting} :h script \end{lstlisting} \emph{ Insert ip range using vim } \begin{lstlisting} :for i in range(1,255) | .put='192.168.0.'.i | endfor \end{lstlisting} \emph{ Increase the current line by one } \begin{lstlisting} + \end{lstlisting} \emph{ Put the cursor on the 15th character of the current line) } \begin{lstlisting} :call cursor(line("."), 15) \end{lstlisting} \emph{ Simple vim script } \begin{lstlisting} :let i = 1 :while i < 5 : echo "count is" i : let i += 1 :endwhile \end{lstlisting} Execute this by yanking it with 'y4j' for example and then '@"'. The colons ':' are not necessary in a vim script file (such as the 'vimrc' configuration file) \subsection{Executing Scripts} \emph{ Execute the script file '$\sim$/scr/eg.vim' } \begin{lstlisting} :so ~/scr/eg.vim \end{lstlisting} \begin{lstlisting} :source ~/scr/eg.vim ~(this is the same) \end{lstlisting} \emph{ Create mapping ';s' to execute the script 'eg.vim' } \begin{lstlisting} :nmap ;s :source ~/path/to/eg.vim \end{lstlisting} \emph{ Another mapping style } \begin{lstlisting} :nmap \b :call MyBackupFunc(expand('%'), { 'all': 1 }) \end{lstlisting} \subsection{Comments In Scripts} \emph{ Put a comment at the start of a line } \begin{lstlisting} :"this is comment \end{lstlisting} \emph{ Put a comment after a command } \begin{lstlisting} echo "> " |"Print generic promp \end{lstlisting} \subsection{Variable Assignment In Vim Scripts} \emph{ A mapping to set the tabstop to 1 \&tabstop is a pseudo var } \begin{lstlisting} nmap ]] :let &tabstop += 1 \end{lstlisting} \emph{ Assigning vars } \begin{lstlisting} let name = "Damian" let height = 165 let interests = [ 'Cinema', 'Literature', 'World Domination', 101 ] let phone = { 'cell':5551017346, 'home':5558038728, 'work':'?' } \end{lstlisting} \emph{ Assign an integer to a variable and display the value } \begin{lstlisting} :let s=7 | echo s \end{lstlisting} \emph{ Set s to the line number of the current line } \begin{lstlisting} let s = line(".") \end{lstlisting} \emph{ Subtract 1 from a variable s } \begin{lstlisting} let s=s-1 \end{lstlisting} \emph{ Create a global variable } \begin{lstlisting} let g:I=0 \end{lstlisting} \section{String Variables} \emph{ See what functions are available for manipulating strings } \begin{lstlisting} :h function-list \end{lstlisting} \emph{ Assign a string to a variable 's' and display the value of 's' } \begin{lstlisting} :let s="green" | echo s \end{lstlisting} \emph{ Assign the unicode smiley face to variable s and display it } \begin{lstlisting} :let s="\u263A" | echo s \end{lstlisting} \emph{ Assign a listing of files in the current folder to variable 's' } \begin{lstlisting} :let s=system("ls") \end{lstlisting} \emph{ A more complex 'system' command } \begin{lstlisting} :let flist = system("find " . shellescape(a:dir) . " -type f -name '*.pm' | sort") \end{lstlisting} \emph{ Embedd newline characters in a string variable } \begin{lstlisting} :let s="1\n2\n3" | echo s \end{lstlisting} \emph{ Set the variable s to be the string 'grass' and display it } \begin{lstlisting} :let s='grass' | echo s \end{lstlisting} \emph{ Set s to be 'eat' and display the string length of s (which is '3') } \begin{lstlisting} :let s='eat' | echo strlen(s) \end{lstlisting} With single quotes there is no interpolation. \section{Array Variables} In the vim language, arrays are called 'lists' \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ useful list functions }} \\ \hline \texttt{ :let r = call(funcname, list) } & Call a function with an argument list \\ \texttt{ :if empty(list) } & Check if list is empty \\ \texttt{ :let l = len(list) } & Number of items in list \\ \texttt{ :let big = max(list) } & Maximum value in list \\ \texttt{ :let small = min(list) } & Minimum value in list \\ \texttt{ :let xs = count(list, 'x') } & Count nr of times 'x' appears in list \\ \texttt{ :let i = index(list, 'x') } & Index of first 'x' in list \\ \texttt{ :let lines = getline(1, 10) } & Get ten text lines from buffer \\ \texttt{ :call append('\$', lines) } & Append text lines in buffer \\ \texttt{ :let list = split(``a b c'') } & Create list from items in a string \\ \texttt{ :let string = join(list, ', ') } & Create string from list items \\ \texttt{ :let s = string(list) } & String representation of list \\ \texttt{ eval.txt [Help][RO] } \\ \hline \end{tabular} \end{center} \subsection{Get Help For Lists} \emph{ View extensive information about list variable in vim } \begin{lstlisting} :help List ~(notice the capital 'L' in 'List') \end{lstlisting} \subsection{List Information} \emph{ Display the number of elements in a list } \begin{lstlisting} echo len(l) \end{lstlisting} \subsection{Creating Lists} \emph{ Create a new list (array) with 4 elements } \begin{lstlisting} :let mylist = [1, "two", 3, "four"] \end{lstlisting} \emph{ Create a new list with no elements } \begin{lstlisting} :let emptylist = [] \end{lstlisting} \subsection{Getting Elements From Lists} \emph{ Set a variable 'item' to the value of the 1st element of the list } \begin{lstlisting} :let item = mylist[0] \end{lstlisting} \emph{ Set a variable to the 3rd element of a list variable } \begin{lstlisting} :let i = mylist[2] \end{lstlisting} \emph{ Get the last item from the list } \begin{lstlisting} :let i = alist[-1] \end{lstlisting} \emph{ Get the first four items from a list } \begin{lstlisting} :let l = mylist[:3] \end{lstlisting} \subsection{Joining Lists Together} \emph{ Join or concatenate 2 lists together } \begin{lstlisting} :let longlist = mylist + [5, 6] \end{lstlisting} \emph{ Add 2 new elements to a list } \begin{lstlisting} :let mylist += [7, 8] \end{lstlisting} \emph{ Get all elements from a list from the 3rd to the last } \begin{lstlisting} :let shortlist = mylist[2:-1] \end{lstlisting} \begin{lstlisting} :let shortlist = mylist[2:] ~(the same) \end{lstlisting} \emph{ Assign variable a the 1st value and variable b the 2nd value } \begin{lstlisting} :let [a, b] = mylist \end{lstlisting} \subsection{Changing List Items} \emph{ Set the 5th element of the list to 'grass' } \begin{lstlisting} :let list[4] = "grass" \end{lstlisting} \section{Hashes Or Dictionaries} Dictionaries are what are sometimes known in other languages as 'hashes' or 'associative arrays'. They are a set of items, each of which has a key and a value. \emph{ View good help for the dictionary data type, notice the capital D } \begin{lstlisting} help Dictionary \end{lstlisting} \emph{ Loop over a dictionary } \begin{lstlisting} :for key in keys(mydict) : echo key . ': ' . mydict[key] :endfor \end{lstlisting} \emph{ Loop over a dictionary } \begin{lstlisting} :for key in keys(mydict) | echo key.':'.mydict[key] | endfor \end{lstlisting} \subsection{If Tests} All programming and scripting languages have an 'if' test, which either executes or doesnt a block of code based on a test which is either true or false. This all based on logic invented by the greeks or somebody. \emph{ Test if the variable 's' consists entirely of whitespace } \begin{lstlisting} if s !~ "^\\s*$" ... endif \end{lstlisting} \emph{ Test if the variable 's' equals 0 } \begin{lstlisting} if s == 0 ... endif \end{lstlisting} \section{Exe Or Eval} In vim the classic 'eval' statement is called 'exe'. It allows you to exectute some vim script code which has been constructed from a string. But there is also an 'eval' statement. Its complicated. \emph{ Execute a new vimscript command } \begin{lstlisting} :exe 'let sum = ' . join(nrlist, '+') \end{lstlisting} \subsection{Loops} \emph{ A for loop to insert an ip range in the document, one per line } \begin{lstlisting} :for i in range(1,255) | .put='192.168.0.'.i | endfor \end{lstlisting} \emph{ Loop through each item in 'list' calling a function } \begin{lstlisting} :for item in list : call Doit(item) :endfor \end{lstlisting} \emph{ Loop through each item in 'list' calling a function } \begin{lstlisting} :for item in list | call Doit(item) | endfor \end{lstlisting} \emph{ While loop } \begin{lstlisting} while p > 0 ... endwhile \end{lstlisting} \section{Other Stuff} \emph{ Edit a script that's somewhere in your path. } \begin{lstlisting} vim `which scriptfile` \end{lstlisting} \begin{lstlisting} vim $(which scriptfile) ~(the same) \end{lstlisting} \emph{ Lazy man's vim } \begin{lstlisting} function v { if [ -z $1 ]; then vim; else vim *$1*; fi } \end{lstlisting} \emph{ Download a sequence of vim patches } \begin{lstlisting} seq -f"ftp://ftp.vim.org/pub/vim/patches/7.1/7.1.%03g" 176 240 | xargs -I {} wget -c {}; \end{lstlisting} \section{Apple Mac With Vim} \emph{ Map the [apple] [space] combination to do the same as \Esc } \begin{lstlisting} :imap \end{lstlisting} \section{Microsoft And Vim} On a microsoft operating system the '.vimrc' configuration file is called '\_vimrc' \emph{ Allow use of F10 for mapping (win32) } \begin{lstlisting} set wak=no ~( :h winaltkeys ) \end{lstlisting} \emph{ Inserting DOS Carriage Returns } \begin{lstlisting} :%s/$/\&/g ~(that's what you type for Win32) \end{lstlisting} \begin{lstlisting} :%s/$/\^M&/g ~(what you'll see where ^M is ONE character) \end{lstlisting} \emph{ A mapping to launch microsoft internet explorer from vim } \begin{lstlisting} :nmap ,f :update:silent !start c:\progra~1\intern~1\iexplore.exe file://%:p \end{lstlisting} \begin{lstlisting} :nmap ,i :update: !start c:\progra~1\intern~1\iexplore.exe \end{lstlisting} \emph{ Reading Ms-Word documents from unix/linux/macosx, requires antiword } \begin{lstlisting} :autocmd BufReadPre *.doc set ro \end{lstlisting} \begin{lstlisting} :autocmd BufReadPre *.doc set hlsearch! \end{lstlisting} \begin{lstlisting} :autocmd BufReadPost *.doc %!antiword "%" \end{lstlisting} \emph{ Using gVIM with Cygwin on a Windows PC } \begin{lstlisting} if has('win32') source $VIMRUNTIME/mswin.vim behave mswin set shell=c:\\cygwin\\bin\\bash.exe shellcmdflag=-c shellxquote=\" endif \end{lstlisting} \emph{ Open joe.c and jump to the first instance of the text 'main' } \begin{lstlisting} gvim.exe -c "/main" joe.c \end{lstlisting} \emph{ To access sourceforge from vim on MS Windows put in the vimrc file } \begin{lstlisting} let g:netrw_cygwin = 0 \end{lstlisting} \begin{lstlisting} let g:netrw_scp_cmd = "E:\\tools\\putty\\pscp.exe -pw some -batch \end{lstlisting} \section{Alternatives To Vim} You may find that Vim is simply too frustrating or counter-intuitive for you, in which case, there are many free and open-source Linux text editors to choose from. \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ other text editors }} \\ \hline \texttt{ gedit } & The Linux Gnome notepad-like text editor \\ \texttt{ kate } & The KDE notepad-like text editor \\ \texttt{ emacs } & A large capable and widely-used unix editor \\ \texttt{ sam } & A text editor used by old Unix and C veterans \\ \texttt{ nano } & Small simple editor from the pine email program \\ \hline \end{tabular} \end{center} \section{Vim Versions} \subsection{Gvim} gvim is a 'graphical' version of vim; that is to say that it runs in its own window rather than in the shell window on the operating system. gvim also generally includes some 'menus' at the top of the window which duplicate functionality which is available through other vim commands. \emph{ Make the gui file-open dialog use the current directory } \begin{lstlisting} :set browsedir=buffer \end{lstlisting} \emph{ Creating your own gui tool-bar entry } \begin{lstlisting} amenu Modeline.Insert\ a\ VIM\ modeline ggOvim:ff=unix ts=4 ss=4vim60:fdm=markergg \end{lstlisting} \emph{ Gvim difference function } \begin{lstlisting} gvim -d file1 file2 ~( vimdiff (compare differences)) \end{lstlisting} \begin{lstlisting} dp ~( "put" difference under cursor to other file) \end{lstlisting} \begin{lstlisting} do ~( "get" difference under cursor from other file) \end{lstlisting} \subsection{The Paste Buffer} The paste buffer may only be available in gvim \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ Redirection \& Paste register * }} \\ \hline \texttt{ :redir @* } & Redirect commands to paste buffer \\ \texttt{ :redir END } & End redirect \\ \texttt{ :redir $>$$>$ out.txt } & Redirect to a file \\ \hline \end{tabular} \end{center} \emph{ Working with Paste buffer } \begin{lstlisting} "*yy ~(yank curent line to paste) \end{lstlisting} \begin{lstlisting} "*p ~(insert from paste buffer) \end{lstlisting} \emph{ Yank to paste buffer (ex mode) } \begin{lstlisting} :'a,'by* : Yank range into paste \end{lstlisting} \begin{lstlisting} :%y* : Yank whole buffer into paste \end{lstlisting} \begin{lstlisting} :.y* : Yank Current line to paster \end{lstlisting} \emph{ Filter non-printable characters from the paste buffer } \emph{ Useful when pasting from some gui application } \begin{lstlisting} :nmap p :let @* = substitute(@*,'[^[:print:]]','','g')"*p \end{lstlisting} \section{Vi Keys} The vim or vi key strokes are available in a number of other software tools, such as 'less', 'mutt' (an email client) ... \emph{ Use the info help viewer with vi key-bindings (key strokes) } \begin{lstlisting} info --vi-keys \end{lstlisting} \section{Vim Jargon} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{buffer}] A buffer is a document or piece of text which we are currently editing. Usually we create a new buffer by opening a file to edit. A file is the document saved on the disk of the computer. After editing a buffer we normally 'write' (save) that buffer to the file. If you type ':e .' a new buffer is created with a list of files in the current folder. You can then save this buffer with ':w test.txt'. The difference between a buffer and a file is important. \item[\url{plain}] text Plain text is text which does not have embedded formatting information in it. On a Microsoft Windows computer anything which can be edited with 'Notepad' is considered to be plain text, but documents created with 'Microsoft Word' are generally not plain text. Vim is designed to edit documents which are plain text. \item[\url{mode}] Vim has several modes. In one mode ('insert') you can enter text. In another mode you can type commands etc. \item[\url{option}] Something which you can set with :set option to change the behavior of vim. \item[\url{regular}] expression This means a pattern which is used to search for (and possibly replace) text in a document. Regular expressions are widely used in all unix-style operating systems and modern programming languages, such as Perl/Python/Java \item[\url{greedy}] pattern A regular expression which matches the maximum amount of text, instead of the minimum amount of text (non-greedy) \item[\url{Unix-style}] operating system This is any operating system which is based on a Unix design. Examples are Apple OSX, Linux, FreeBSD (Berkeley Standard Distribution of Unix) \item[\url{ex}] command line This is the line which appears after a colon ':' character as the bottom of the screen. \end{description} \section{Enigmas And Curiosities} Vim is such a complex piece of software that completely plumbing its mysteries is perhaps impossible for one person. Below are some incomprehensible and strange recipes. \emph{ Just another vim hacker } \begin{lstlisting} vim -c ":%s%s*%Cyrnfr)fcbafbe[Oenz(Zbbyranne%|:%s)[[()])-)Ig|norm Vg?" \end{lstlisting} \emph{ Display some vim easter eggs } \begin{lstlisting} :h 42 ##( also http://www.google.com/search?q=42 ) :h holy-grail :h! \end{lstlisting} \section{The Vim Cause} The maker of vim supports various humanitarian project in uganda. \emph{ View information about vims ugandan humanitarian projects } \begin{lstlisting} helpg uganda \end{lstlisting} \section{Vim People} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{bill}] joy wrote the vi text editor, which built apon 'ex' \item[\url{bram}] moolenaar created the vim editor \item[\url{david}] rayner david at rayninfo.co.uk wrote some good tips about using the vim editor \end{description} \subsection{Knowledgable People} sbutler at ask.metafilter.com jepler at ask.metafilter.com david a rogers - at vimtips \section{Information Sources} \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://groups.google.com/group/vim_use}] a users newsgroup \item[\url{comp.editors}] a text editor newsgroup \item[\url{http://vim.wikia.com/}] the vim wiki \item[\url{vim.wiki.com/wiki/VimTip...}] a good collection of vim tips \item[\url{http://www.newriders.com/books/opl/ebooks/0735710015.html}] a vim book \item[\url{http://vimdoc.sourceforge.net/cgi-bin/vim2html2.pl}] searchable docs \item[\url{http://gav.brokentrain.net/projects/vimtips/vimtips.pdf}] some printable tips \end{description} \section{Things To Investigate} .. imap .. nmap .. nnoremap .. autocommand \emph{ An imap example } \begin{lstlisting} :imap \end{lstlisting} \section{Blogs And Diaries With Vim} \emph{ Update your journal by creating a new file with todays date } \begin{lstlisting} vi ~/journal/$(date +%F) \end{lstlisting} \emph{ A bash function to write a journal entry for today } \begin{lstlisting} blog() { vi ~/journal/$(date +%F); } \end{lstlisting} \emph{ Create journal entry in a file 2009-jan-12 for example } \begin{lstlisting} vi ~/journal/$(date +%Y-%b-%d) \end{lstlisting} \section{History} The Vim editor is a reimplementation and improvement of the 'vi' text editor which was written by Bill Joy. Bill Joy was a important figure in the early development of the Berkeley Standard Distribution of Unix, since he contributed a lot of code while a student. His other achievements include writing the first successful implementation of the tcp/ip protocol suite as well as founding sun microsystems and playing an important role in the sponsoring the development of the Java programming language. Vi inturn was influenced by the 'ed' line oriented text editor, one of the very early unix editors. \section{Vim And Vi Clones} \arrayrulecolor{gray} \begin{center} \begin{tabular}{ |rl| } \multicolumn{2}{c}{\textbf{ clones }} \\ \hline \texttt{ elvis } & A small vi clone \\ \hline \end{tabular} \end{center} \subsection{Javascript Clones} Two basic javascript versions of vi are available for using embedded in web-pages, but they are not particularly good and don't appear to be maintained. \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{http://gpl.internetconnection.net/vi/}] a vi like clone written in javascript to run on a webpage doesnt have "J" for example, and yank doesnt work well \item[\url{http://gpl.internetconnection.net/vi/vi.js}] the source code for the javascript vi clone \item[\url{http://vian.sourceforge.net/}] another javascript vi clone \end{description} \section{Other Text Editors} The are many text editors which have originated on Unix/Linux systems. Here we mention only a tiny selection \begin{description}[labelindent=1cm, leftmargin=2cm, style=nextline] \item[\url{emacs}] 'Editing MACros' This is usually considered to be vims main 'rival' in the world of traditional unix program editors. It is a large and complex application with many knowledgable technical users. \item[\url{sam}] This is a little known editor written by Rob Pike and used by Brian Kernighan among others http://sam.cat-v.org/. It seems very difficult to obtain. \item[\url{sed}] A non interactive editor worth knowing about. \end{description} \section{Modeline} \emph{ Mode-line (make a file read-only etc) must be in first/last 5 lines } \begin{lstlisting} vim:noai:ts=2:sw=4:readonly: \end{lstlisting} \emph{ Says use HTML Syntax highlighting } \begin{lstlisting} " vim:ft=html: \end{lstlisting} \emph{ Get help for the modeline option } \begin{lstlisting} :h modeline \end{lstlisting} \section{Mystery} This section contains some recipes which may be mysterious but educational. \emph{ Reproduce the previous line word by word } \begin{lstlisting} imap ] @@@hhkyWjl?@@@P/@@@3s \end{lstlisting} \begin{lstlisting} nmap ] i@@@hhkyWjl?@@@P/@@@3s \end{lstlisting} \emph{ Pull full path name into paste buffer for attachment to email etc } \begin{lstlisting} nnoremap :let @*=expand("%:p") ~(?? error) \end{lstlisting} \begin{lstlisting} nnoremap :let @*=substitute(expand("%:p"), "/", "\\", "g") ~(win32) \end{lstlisting} \emph{ Simple PHP debugging: display all variables yanked into register a } \begin{lstlisting} iab phpdb exit("
Debug a "); \end{lstlisting} \end{document}