Customizing the vi editor
Developer's Daily

vi background

For years Unix/Solaris/Linux users have had a love/hate relationship with the vi editor - in general, they've loved to hate it. As the standard Unix/Solaris editor, many of the problems Unix users have with vi can be alleviated by learning how to set a few configuration options in the vi editor's startup file, `.exrc`. Unfortunately, many users never learn about this vi startup file, and how much easier it makes the vi editor.

In this Unix/Solaris/Linux tutorial, we'll learn some of the most useful vi editor startup options. We'll also create a few vi macros, and learn how to define the `F1` function key to display a "Help" screen to make the vi editor much easier to use.

The vi configuration file

When you start the vi editor, the editor searches for the environment variable `$EXINIT` and uses the contents of the file it points to as configuration commands, if it exists. If `EXINIT` is not defined, vi looks for the `.exrc` file in your `HOME` directory, and uses its configuration commands. Finally, vi looks in your current directory for a file named `.exrc` and executes the commands in that file, if it exists. In this manner, you can have a different vi configuration for each directory or project that you're working on. In this article we'll modify the .exrc file in our home directory, which will effect all of our vi editing sessions.

The `.exrc` file can contain comments, last-line commands (those entered on the last line of the vi editor and beginning with a ":", such as ":set showmode"), and macro definitions.

Comments in the `.exrc` file are those lines that begin with a `"` character (double-quote character). All characters after the `"` are ignored by vi. You can include as many comments in the `.exrc` file as you like.

Showing the current mode

One of the biggest complaints about vi is that you never know what mode you're in - there's nothing on screen to indicate if you're in "command mode" or "insert mode". This complaint is easily cured by the "`set showmode`" command.

When you're in vi, the "`:set showmode`" command shows what mode vi is in when you're typing - insert mode, append mode, etc. If you're in command mode, like you are when you first enter vi, you won't see anything different. But as soon as you enter insert mode, the words "INSERT MODE" are displayed in the lower-right corner on your screen.

You enable this useful feature by putting the "set showmode" command in the `.exrc` file, as shown in Figure 1. That's all there is to it. The next time you enter the vi editor, the `.exrc` file will be read automatically, and this feature will be enabled for you. One warning - don't put any blank lines in the `.exrc` file. vi doesn't care for blank lines in the configuration file at all, and your configuration options may be ignored.

`"` `" This line is a comment. Commented lines begin with the " character` `" in the first column.` `"` `" Use the 'showmode' command to display what mode I'm in when using vi.` `"` `set showmode` `"` `" Block messages from other users to keep my display clean.` `"` `set nomesg` `"`

Figure 1: | A sample `.exrc` file.

The "`:set nomesg`" command shown in Figure 1 is also very useful. It keeps other users from writing information onto your screen (such as when using the "talk" command, for example) when you're using vi.

Map commands

"Map" commands let you customize the vi editor by allowing you to redefine the meaning of keys when you're in command mode. In Figure 2, we define the `F1` function key to be a "Help" key, and the `F2` function key to be a shortcut to write our current edit changes to a file, similar to the "`:w!`" command, but shorter and easier.

`"`
`" This line is a comment. Commented lines begin with the " character`
`" in the first column.`
`"`
`" Use the 'showmode' command to display what mode I'm in when using vi.`
`"`
`set showmode`
`"`
`" Block messages from other users to keep my display clean.`
`"`
`set nomesg`
`"`
`" Define the F1 key to show a customized "help" file`
`"`
`:map #1 :!more ~/.vi_help^M`
`"`
`" Define the F2 key to be a shortcut to save current changes to file`
`" (uses the current filename)`
`"`
`:map #2 :w^M`
`"`

Figure 2: | This sample `.exrc` file shows how to change the behavior of your function keys with the `map` command.

Both of these new function key definitions are created with the "`:map`" command. Let's break down the "map" commands in our sample file to see what they're really doing.

In the `.exrc` file, #1 refers to function key `F1`, and #2 refers to the `F2` function key. So the "`:map #1`" portion of the first line means "map the function key `F1`", and "`:map #2`" means "map the function key `F2`".

After the "`:map #1`" portion of the first command, you see the character sequence "`:!more ~/.vi_help^M`". If you're familiar with vi, you may know that the "`:!`" sequence allows you to run any Unix command while you're in the vi editor. For instance, while you're in command mode in vi, you can type "`:!ls -al`" (followed by the `<Enter>` key) to get a long listing of all files in your current directory. This is great, because you don't have to exit vi and then re-enter just to run the "`ls -al`" command, saving you a lot of keystrokes.

That said, you can see how this extends to what we're doing with the `F1` key. We're telling vi that every time the user hits the `F1` key, run the external Unix command "`more ~/.vi_help`". This means "use the Unix 'more' command to display the contents of the file '`.vi_help`' located in our `HOME` directory". The file "`.vi_help`" is any file you create - our example file is shown in Figure 3.

`====================`
`| |`
`| vi Help Screen |`
`| |`
`====================`

`Customized Function Keys`
`------------------------`

`F1 - Help Screen (this screen message)`
`F2 - Save Changes`

`Command-Mode Commands`
`=====================`

`Commands To Insert Text`
`-----------------------`

`a - Append after the current cursor position`
`A - Append after the end of the current line`
`i - Insert at current cursor position`
`I - Insert at beginning of line`
`o - Open a new line below the current line (lower-case letter o)`
`O - Open a new line above the current line (upper-case letter O)`

`Commands to Delete Text`
`-----------------------`

`x - Delete the character at the current cursor position`
`dd - Delete the current line`
`ndd - Delete the next 'n' lines, including the current line`
`d$ - Delete from the current position to the end of the line`

`Movement Commands`
`-----------------`

`0 - Move to the beginning of the current line (number zero)`
`$ - Move to the end of the current line`
`b - Move backwards one word in the current file`
`w - Move forward to the next word`
`G - Move to the end of the current file`
`nG - Move to line 'n'`

`Cutting and Pasting Commands`
`----------------------------`

`yy - Yank the current line (i.e., copy it to buffer)`
`nyy - Yank the next 'n' lines, including the current line`
`pp - Paste the content of the buffer`

Figure 3: | You can create a `.vi_help` file to act as a help screen within the vi editor.

Now, every time the user hits the `F1` key, they will actually use the `more` command to view the customized file `.vi_help` located in their `HOME` directory. But what's the `^M` at the end of the line? Do we just type the character `^` followed by the letter `M`?

The answer is no. The `^M` you see in Figure 3 is actually generated by typing a `<CTRL-v>` (holding down the 'Ctrl' key and the 'v' key at the same time) followed by a `<CTRL-m>`.

This key sequence embeds special characters into our file to tell vi we want to automatically generate an `<Enter>` key signal at this point in the file. If you're familiar with your ASCII codes, you know that hitting the `<Enter>` key is the same as typing a `<CTRL-m>`. Try typing a `<CTRL-m>` at the Unix command line if you like - it's the same as the `<Enter>` key. When you use the `<CTRL-v><CTRL-m>` key sequence, you actually generate only one character in your `.exrc` file, not two separate characters.

If we don't tell vi to put an `<Enter>` key keystroke at this point, vi will display the "`:!more ~/.vi_help`" command on the last line of your vi editor screen when you hit the `F1` function key, but it won't execute the command until you manually hit the `<Enter>` key, which isn't what we want. Think of the `<CTRL-v><CTRL-m>` key sequence as automatically hitting the `<Enter>` key for you.

The `F2` function key mapping will seem easy now. When the user hits the `F2` key, vi automatically issues the "`:w`" write command, and then generates an `<Enter>` key keystroke, saving your current file to disk.

Other useful macros are shown in Figure 4. `F3` is set to display line numbers on screen, `F4` is set to take the line numbers off screen, and `F5` configures automatic indentation of lines. All of these functions are very useful when writing programs.

`set showmode` `set nomesg` `:map #1 :!more ~/.vi_help^M` `:map #2 :w^M` `:map #3 :set number^M` `:map #4 :set nonumber^M` `:map #5 :set autoindent^M`

Figure 4: | This `.exrc` file demonstrates useful macros for the `F1` through `F5` function keys.

Conclusion

You have now seen how to customize your own `.exrc` file to display your current working mode, keep other users messages off of your display, and create your own macros to make your life with the vi editor easier and more productive. You can now apply the techniques included in this article to customize vi to include your own working preferences.