## 11.9. Programming Assistance

vim has extensive facilities for both the edit-compile-debug cycle and syntax highlighting.

### 11.9.1. Edit-Compile Speedup

The facilities in vim were inspired by the "quick fix" mode of the Manx Aztec C compiler for the Amiga. In fact, the vim documentation refers to this feature as "quick fix" mode. The features are quite flexible, allowing you to tailor them to your programming environment (see Table 11.12).

#### Table 11.12. vim Program Development Commands

Command | Function
--- | ---
`mak`[`e`] [`arguments`] | Run make, based on the settings of several options as described below, then go to the location of the first error.
`cf`[`ile`][`!`] [`errorfile`] | Read the error file and jump to the first error. With an errorfile, use that file for errors and set the `errorfile` option to it. The `!` forces vim to move to another buffer if the current one has been modified but not saved.
`cl`[`ist`][`!`] | List the errors that include a filename. With `!`, list all errors.
[`count`]`cn`[`ext`][`!`] | Display the countth next error that includes a filename. If there are no filenames at all, go to the countth next error.
[`count`]`cN`[`ext`][`!`] | Display the countth previous error that includes a filename. If there are no filenames at all, go to the countth previous error.
[`count`]`cp`[`revious`][`!`]
`clast`[`!`] [`n`] | Display error n if supplied. Otherwise, display the last error.
`crewind`[`!`] [`n`] | Display error n if supplied. Otherwise, display the first error.
`cc`[`!`] [`n`] | Displays error n if supplied, otherwise redisplays the current error.
`cq`[`uit`] | Quit with an error code, so that the compiler will not compile the same file again. This is intended primarily for use with the Amiga compiler.

Like elvis, as you move through the errors vim also compensates for changes in the file, so that when you go to the next error, you end up on the correct line.

The vim options that control the `:make` command are presented in Table 11.13.

#### Table 11.13. vim Program Development Options

Option | Value | Function
--- | --- | ---
`shell` | `/bin/sh` | The shell to use to execute the command for rebuilding your program.
`makeprg` | `make` | The program that will actually handle all the recompilation.
`shellpipe` | `2>&1| tee` | Whatever is needed to cause the shell to save both standard output and standard error from the compilation in the error file.
`makeef` | `/tmp/vim##.err` | The name of a file which will contain the compiler output. The `##` causes vim to create unique filenames.
`errorformat` | `%f:%l:\ %m` | A description of what error messages from the compiler look like. This example value is for GCC, the GNU C compiler.

When you execute `:make`, vim constructs a command by concatenating the various pieces described above. Any arguments you supply are passed to make in the appropriate place. It then echoes this command to your screen. For example, if you type `:make -k`, you might see something like this:

>     :!make -k 2>&1| tee /tmp/vim34215.err
>     ...

By using the tee(1) program, the output from make and the compiler is saved in the error file (/tmp/vim34215.err), and also sent to standard output, in this case your screen.

When the make finishes, vim reads the error file, and goes to the location of the first error. It uses the value of the `errorformat` option to parse the contents of the error file, in order to find file names and line numbers. (The format of this variable is described in full in `:help errorformat`.) You can then use the `:cc` command to see the error messages, and the `:cnext` command to move to the next error.

### 11.9.2. Syntax Highlighting

Highlighting in vim is based primarily on colors. To enable syntax highlighting, put `syntax on` into your .vimrc file. This will cause vim to read the syntax.vim file, which defines the default highlight coloring and then sets things up to use highlighting appropriate to each language.

vim has a very powerful sub-language for defining syntax highlighting. The syntax.txt help file in vim 5.1 that describes it is over 1,500 lines long. Therefore, we won't attempt to give all the details here. Instead, the sample file below should give you some taste for what vim can do. The example consists of portions of the syntax file for Awk:

>     " Vim syntax file
>     " Language:	awk, nawk, gawk, mawk
>     " Maintainer:	Antonio Colombo <antonio.colombo@jrc.org>
>     " Last change:	1997 November 29

>     " Remove any old syntax stuff hanging around
>     syn clear

>     " A bunch of useful Awk keywords
>     syn keyword awkStatement        break continue delete exit
>     ...

>     syn keyword awkFunction         atan2 close cos exp int log rand sin \
>                                     sqrt srand
>     ...

>     syn keyword awkConditional      if else
>     syn keyword awkRepeat           while for do

>     syn keyword awkPatterns         BEGIN END
>     syn keyword awkVariables        ARGC ARGV FILENAME FNR FS NF NR
>     ...

>     " Octal format character.
>     syn match   awkSpecialCharacter contained "\\[0-7]\{1,3\}"
>     " Hex   format character.
>     syn match   awkSpecialCharacter contained "\\x[0-9A-Fa-f]\+"

>     syn match   awkFieldVars        "\$[0-9]\+"

>     syn match   awkCharClass        contained "\[:[^:\]]*:\]"
>     syn match   awkRegExp	contained "/\^"ms=s+1
>     syn match   awkRegExp	contained "\$/"me=e-1
>     syn match   awkRegExp	contained "[?.*{}|+]"
>     ...

>     " Numbers, allowing signs (both -, and +)
>     " Integer number.
>     syn match  awkNumber            "[+-]\=\<[0-9]\+\>"
>     " Floating point number.
>     syn match  awkFloat             "[+-]\=\<[0-9]\+\.[0-9]+\>"
>     ...

>     syn match  awkComment	"#.*" contains=awkTodo

>     if !exists("did_awk_syntax_inits")
>       let did_awk_syntax_inits = 1
>       " The default methods for highlighting.  Can be overridden later
>       hi link awkConditional        Conditional
>       hi link awkFunction           Function
>       hi link awkRepeat             Repeat
>       hi link awkStatement          Statement
>       ...
>       hi link awkNumber             Number
>       hi link awkFloat              Float
>       ...

>       hi link awkComment            Comment
>       ...
>     endif

>     let b:current_syntax = "awk"

The file above uses `syntax keyword` to give names to certain classes of keywords (such as real Awk keywords and built-in functions), and `syntax match` to give names to regular expressions that match certain kinds of objects (such as numbers). Then the `hi link` statements link the named classes of objects to the predefined highlighting conventions.

The syntax.vim file predefines the standard conventions, with a number of lines like these:

>     hi Comment	term=bold ctermfg=Cyan guifg=#80a0ff
>     hi Constant	term=underline ctermfg=Magenta guifg=#ffa0a0
>     hi Special	term=bold ctermfg=LightRed guifg=Orange
>     hi Identifier	term=underline ctermfg=DarkCyan guifg=#40ffff
>     ...

The first argument defines the class, and the rest define what kind of highlighting to do on what kind of terminal. `term` is for a normal terminal, `cterm` is for a color terminal (in this case, the ForeGround color), and `gui` is for vim's GUI interface.

In vim, the syntax colors are global attributes. Changing the `Comment` color changes the color for all comments in all windows, no matter what programming language you're editing.

Since the syntax descriptions use attribute linking, you can make language-specific changes. For example, to change the comment color for Awk, you can define attributes for `awkComment`, like this:

>     hi awkComment guifg=Green

vim comes with a large number of syntax descriptions for different languages. The coloring for Awk is slightly psychedelic (lots of red and pink), although the coloring for context diffs is actually rather pleasant, as is the color scheme for UNIX mailbox files. The HTML mode is also pretty interesting. Overall, it's quite a lot of fun to use.

Copyright © 2003 O'Reilly & Associates. All rights reserved.