Saturday 9/9/2006
This documentation is for Vim (VI iMprovied). The documentation outlines vim(1) configuration, plugins, programming and general use. Vim's configuration file by default is ~/.vimrc for unix-like platforms and %USERPROFILE%\_vimrc for windows. In more recent ports of vim (e.g., vim 6.3 and greater, win32 can reference the configuration file as either of the %USERPROFILE%\_vimrc or %USERPROFILE%\.vimrc files. The configuration directory (for unix) is typically $HOME/.vim and %USERPROFILE%\vimfiles for win32. Refer to runtimepath to determine the actual value for the current vim execution. E.g.,
:set runtimepath
Will print the current search path for the executing vim environment. Note, that the following environment variables are automatically configured by vim at startup. These variables should not be set explicitly.
$VIM $VIMRUNTIME
Quick Note: The information in this document is accurate and was written using VIM 6.3 as a reference. Further, some of the sections need reworking as they either too long or just plain wordy. Also the section on NetRW needs reworking as it still refers to the old hacked netrw.vim
The plugin directory can be in any of the directories in the runtimepath option. All directories contained within the runtimepath are scanned for plugins.
To determine the runtimepath:
:set runtimepath runtimepath=/etc/vim,~/.vim,/usr/local/share/vim/vim60
In the above, the runtimepath consists of the following 3 directories, (all of which are scanned for plugins to be loaded on startup):
Note that the last one is the value of $VIMRUNTIME which has been expanded. To set the plugin paths, add an entry of the form set runtimepath=/p1,/p2 to ~/.vimrc
The directory ~/.vim/ftplugin is for filetype specific plugins. For example, a file called ~/.vim/ftplugin/java.vim is soured whenever file types of .java are loaded. See #2 Filetypes below.
Filetype detection occurs based on the setting of filetype. The filetype and plugin detection and filetype plugin indent can be enabled in the local ~/.vimrc. To show the current filetype, plugin and indent settings, execute:
:filetype
The above produces output similar to:
filetype detection:ON plugin:ON indent:ON
The filetypes are set based on the vim runtime settings and by the user settings. The user settings are in:
The settings in ~/.vim/filetype.vim can be used to detect files based on their extensions. Entries in this file configure the au! type settings, for example:
au! BufRead,BufNewFile *.mine setfiletype mine
Which sets set the filetype to mine if a file with an extension of .mine is loaded. Filetype detection in scripts.vim is more flexible and regular expressions can be used to determine the filetype based on the content of the file. For example, an entry like:
if getline(1) =~ '^#!.*\<mine\>'
setfiletype mine
endif
Sets the filetype to mine if the first line of the file being read starts with #! and then includes the text <mine> somewhere on the line.
The ftdetect directory contains entries that perform filetype detection in a similar manner to filetype.vim. The directory contains files named for ext.vim where ext is the extension of the file to set the filetype for. E.g., an entry like:
x.vim
Sets the filetype for any file of the form name.x where x is a literal and name is some filename.
The netrw.vim plugin delivered with the vim runtime can be used to edit remote files using a variety of protocols including amongst others ftp and more usefully scp.
Quick note: vim requires double-forward slash characters in the username and host part of a network file, the pathname is standard single forward-slashes (although double-forward slashes can be used as well).
The username and hostname component of a network file is separarated from the pathname by a single forward slash - so, a double forward-slash after the hostname refers to the root. E.g.:
network file: scp://foo@transmission/.vimrc
Refers to protocol + user name + hostname i.e., scp://foo@transmission/ followed by .vimrc (relative pathname from the users's login directory). Some examples of netrw file pathnames are:
The next two netrw paths are equivelant to each other:
Vim's NetRW plugin $VIMRUNTIME/plugins/netrw.vim, allows reading files using a variety of tcp protocols. Some of these protocols allow writingas well. The file transfer mechanism for getting at the remote files is wget(1) so access is limted to whatever wget contrains. The list of supported netrw protocols are:
Accessing a file via scp will use the scp option -q.
Hack note: If additional options are required then it's probably possible to set some varible but hacking the netrw.vim script (put a copy in ~/.vim/plugins/netrw.vim) and set the parameters that are needed in there is easiest. E.g., scp -P 2222 -q if a special port is required. Also, accessing files via scp is a little different. Vim accepts these protocols as the file to start vim with, or via the :r and :e and :w commands. However, to access a file that is not relative to the user's home directory requires a double path separator (i.e., //) and not the more usual ssh : separator. So, to access a file /tmp/foo.txt on host bar.com as user fred, start vim with:
bash $ vim scp://fred@bar.com//tmp/foo.txt
Compare this with the usual scp of scp fred@bar.com:/tmp/foo.txt. Setting options for the scp command with the hacked version is pretty simple. In the .vimrc, set the variable:
netrw_scp_options
To whatever options are needed. Note, that these options are at the start of the scp command. To tell scp to "go via port 2222", simply set the netrw_scp_options variable in the .vimrc as follows:
let netrw_scp_options = " -P 2222 "
This results in the netrw_scp_cmd, which is netrw's scp command to execute, being scp -P 2222 -q. Another way to set the scp options is to define the command explicitly in the .vimrc. E.g.,
let netrw_scp_cmd = "scp -P 2222 -q -r "
Which ensures that the scp command is always set to perform a recursive copy via ssh port 2222 on the remote machine.
Accessing files via http uses "http get" and is limited to read-only. So, get the index.html from a sever "web.com", we could:
vim http://web.com/index.html
The http "get" protocol is useful for getting text for vim plugins. For example, the vim help on netrw says "get the Decho.vim script which is available as: http://vim.sourceforge.net/scripts/script.php?script_id=120". Using vim with netrw, it's a simple matter to get the file and save it with:
vim http://vim.sourceforge.net/scripts/script.php?script_id=120
This will start vim with the Decho.vim script in a buffer which can then be written to disk.
Vim has several special variables. These can be used to reference objects like the current word under the cursor.
see :help <cword> in vim(1) help for more special variables
This example shows command completion (command as in :something). A command called Id is defined to call a function ListUsers, which exec's the system command id(1). The following defines the command and function:
To define the Id command, use the :com (command) action:
:com -complete=custom,ListUsers -nargs=1 Identify !id <args>
The following defines the ListUsers function, using the fun keyword
:fun ListUsers(A,L,P)
: return system("cut -d: -f1 /etc/passwd")
:endfun
The Id command (which is configured to call ListUsers, can be invoked in vim(1) with:
<esc>:!id
Mappings can be defined at the buffer level with noremap or the command level with cnoremap. the buffer level mappings operate with normal buffer commands like i for insert and blah text and <ESC> for Escape and so on. The command level mappings execute from the : prompt. E.g.,
cnoremap <LocalLeader>c let x = '1'<CR>
Which sets the variable x to 1 when <ESC>:\c is executed.
noremap <buffer> <LocalLeader>c o/**<CR><CR><CR><afile><CR>/<Esc>X3ka @return<ESC>4jo<ESC>a
Which inserts a javadoc style command when \c is typed in the buffer (not in insert mode)
Vim is available via remote cvs from sourceforge (cvs.sf.net). To checkout the repository, create a directory like cvs or similar and then:
bash $ cvs -z3 -d:pserver:anonymous@cvs.sf.net:/cvsroot/vim checkout vim
The above will grab the vim source and put it into a directory called vim within the current directory. To update the repository:
bash $ cvs -z3 -d:pserver:anonymous@cvs.sf.net:/cvsroot/vim update vim
To build vim, go to the source, i.e., the directory with Makefile in it, and execute make(1):
bash $ cd <vim cvs checkout location> bash $ ./configure bash $ make bash $ make install
The vim script directory is the place where vimscripts should be added. By convention. For unix platforms, this is typically:
$HOME/.vim/scripts
For the win32 port, this directory is typically
"%USERPROFILE%"\vimfiles
Scripts inside the script directory can be referenced via the runtime directive from within the .vimrc, like so:
runtime scripts/avimscript.vim
Vim can support the display and editing of unicode character sets like UTF-8. Vim must be started in a terminal that supports unicode character rendering for this to actually work. Terminal apps like mlterm, gnome-terminal and uxterm support unicode. In fact, these days, most terminal apps support unicode so this is not so much of a problem. Just be sure that the terminal font supports unicode characters and ensure that LANG is not set to something like C. A more preferable setting for LANG is something like ''en_AU.UTF-8'
Vim must configured correctly before it can display unicode characters. The options fileencoding, encoding and terminalencoding must be set to utf-8 and vim must be compiled with the +multi_byte switch. The vimscript set_utf8.vim can be used to configure vim for unicode support. Add set_utf8.vim to the vim scripts directory:
bash $ cp set_utf8.vim ~/.vim/scripts
And then edit .vimrc, adding the following:
runtime scripts/set_utf8.vim
Another option is to set the following explictly in .vimrc:
fileencoding=utf-8 encoding=utf-8 terminalencoding=utf-8
Setting these options allows vim to correctly render unicode characters. However, entering them is another matter. One approach to entering weirdo characters in (e.g.,) the utf-8 character set (when using a standard US keyboard) is to use dagraphs. The following is a summary of the input methods:
The vimscripts provided in polish_keymaps.zip provide a simple means for entering polish accented characters (using files encoded either in UTF-8 or iniso-8859-2). To install:
Characters can be entered with tilda ~ (E.g., ź stripe is ~x (yes x) and ż dot is ~z). Character mappings can be viewd with:
:lmap
Digraphs are used to enter wierdo characters containing circumflex, grave and other accents, strange characters like the German double-S, as well as currency symbols and etc. The vim digraph option must be enabled and a digraph character can be entered with 3-key strokes, with the middle (2nd) character being backspace. For example, to enter the German double-s (ß) character:
:set digraph s<backspace>s
There are heaps and heaps of digraphs, use vim's :digraphs command to list them.
ctags(1) can be used to build an index of methods inside a .java (or c, or c++) source file. To use ctags, a tags index file must be created and made known to vim. This can be done with the ctags(1) program. E.g.,
bash $ ctags MyClass.java
Which builds a file called tags in the current directory. Then to jump to a method (assume MyClass>>foo() is defined):
bash $ vim -t foo
It's probably possible to write the ctags to a different location and then specify the ctag file to use, rather than tags in the current directory.
A more sophisticated tag index (containing methods, classes, fields and so on) for Java source can be constructed for all files recursively in multiple directories. Assume a tag index is required for all the .java files contained in ./src and ./generate directories:
bash $ ctags -R --extra=q --java-kinds=+l --fields=+im src generate
Vim can make use of multiple tag index files, and this is done by specifying the tags variable. This is comma separated list of pathnames pointing to tag index files. The current value of the tags setting can be viewed with
:echo &tags
The following .vimrc excerpt configures vim to use two tag files, located in /home/foo.tags and /tmp/bar.tags. After setting up the tag index file locations, the tagstack option can be set so that tag moves are recorded and can be poped off a stack using ctrl+] to jump to a tag and ctrl+T to pop back.
let &tags = "/home/foo.tags,/tmp/bar.tags" set tagstack " Record tag moves so that ctrl+T pops back
Vim will be able to make use of the tags files, after they've been created with ctags(1), and once tags file and tagstack variables have been speciried (e.g., via .vimrc). Specifying the -t tag option on the VIm command line will force vim to edit the file where tag is defined. If there there are multiple matches, then specify the :tselect command. E.g.,
bash $ vim -t MySpecialTagOfInterest
Then, in VIm command mode (ESC), typing :tselect (or :tn) opens a window presenting identifiication markers on the left followed by definition kind, see ctags(1) for a more complete definition but simply F=field, C=class. The current selection is indicated by > the marker. To load a different file, simply select the number in the left column (the # column)
# pri kind tag file
> 1 F C f String src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Type.java
class:Type
public static final Type String = new StringType();
2 F c String src/com/sun/org/apache/xpath/internal/operations/String.java
inherits:UnaryOperation
public class String extends UnaryOperation
3 F m String src/com/sun/security/auth/PolicyParser.java
new String(new char[] {(char)lookahead}));
Navigating the tagstack:
:tselect - presents a selection list, which will load the relevent file containing the tag by user-entered number :tnext - move to the next file in the tag stack. Short cut :tn :tprev - load the previous file in the tag stack. Short cut :tp :tjump tag - present a selection list matching tag. The :tjump command also supports tab completion
Vim supports code folds in a number of ways (manually defined, by expression and by shiftwidth). For manual fold definitions, add a comment (in the revelant syntax of the file being edited) and add the vim magic marker for code fold, which is {{{. E.g., for bash, a code fold might be:
# The foo function vim code fold {{{1
foo() {
echo This is foo
}
To activate the fold, place the cursor anywhere after the magic marker and create the fold with zf. The fold will collapse and the text prior to the marker will appear with a +---. To open the fold, place the cursor on the fold (e.g., on the line with +---) and issue zo. To open all folds in the current window issue zR. Once a fold is created, it can be closed with the zc command (with the cursor anywhere after the marker). A summary of these commands are:
It's also possible to perform a fold of a number of lines of code using the nzf<down> command, where n is the integer number of lines to fold. E.g.,
10zf<down>
will fold 10 lines from the current cursor position. Open the fold in the usual way, e.g., by using the zo command with the cursor on the +--- fold line.
All code folds from the cursor position down can be closed with either :foldclose or with zC
All code folds from the current cursor position down can be opened with either :foldopen or zn (use zN to restore folds to previous state).
Quick Note: This section needs a re-write
A. Group names
The following text is extracted from the vim 6.4 user guides to syntax highlighting, section *group-name* in Vim manaul "usr_44.txt".
The names marked with * are the preferred groups; the others are minor groups. For the preferred groups, the "syntax.vim" file contains default highlighting. The minor groups are linked to the preferred groups, so they get the same highlighting. You can override these defaults by using ":highlight" commands after sourcing the "syntax.vim" file.
Note that highlight group names are not case sensitive. "String" and "string" can be used for the same group. The following names are reserved and cannot be used as a group name: NONE ALL, ALLBUT, contains, contained
Group Name | Description ------------+-------------- *Comment any comment
*Constant any constant String a string constant: "this is a string" Character a character constant: 'c', '\n' Number a number constant: 234, 0xff Boolean a boolean constant: TRUE, false Float a floating point constant: 2.3e10 *Identifier any variable name Function function name (also: methods for classes) *Statement any statement Conditional if, then, else, endif, switch, etc. Repeat for, do, while, etc. Label case, default, etc. Operator "sizeof", "+", "*", etc. Keyword any other keyword Exception try, catch, throw *PreProc generic Preprocessor Include preprocessor #include Define preprocessor #define Macro same as Define PreCondit preprocessor #if, #else, #endif, etc. *Type int, long, char, etc. StorageClass static, register, volatile, etc. Structure struct, union, enum, etc. Typedef A typedef *Special any special symbol SpecialChar special character in a constant Tag you can use CTRL-] on this Delimiter character that needs attention SpecialComment special things inside a comment Debug debugging statements *Underlined text that stands out, HTML links *Ignore left blank, hidden *Error any erroneous construct *Todo anything that needs attention (e.g., TODO, FIXME, XXX)
Stuart Moorfoot © 9 September 2006 foo@bund.com.au