August 18, 2004

SysAdmin to SysAdmin: Getting more out of Vim

Author: Brian Jones

If you're a Linux administrator, no matter what size your environment, it's quite likely that you use Vim. You probably use it as a config file editor, or for light programming tasks. If you're already familiar with the basics, have a look at some slick tips that'll have you using Vim for more than just ho-hum, everyday admin tasks. 

I use Vim for everything. I started out using it for simple config file
edits, bash or Perl scripts, and trivial notes. I used to use Zend Studio
for PHP programming, Quanta Plus, Bluefish, or Screem for HTML, OpenOffice.org for
documentation, and tools like gedit for drafting email and longer,
personal notes (like my personal "tips and hacks" log file). However,
over the past couple of years, I've learned to configure Vim to use it
for all of these tasks. To me, it makes more sense to try to use one
editor for all of my editing tasks if possible (without writing
code, of course).

Vim configuration

Vim allows for several configuration file options. If you have a
.vimrc file in your home directory, it uses that. It can
also take a user-specified configuration file at the command line using
the -u flag. This is useful if Vim chokes on some new
config option you're trying out, because you can use, for example,
vim -u NONE to bypass your config file altogether. Finally,
in the absence of either of these options, Vim uses a default,
system-wide configuration file, generally /etc/vimrc.

Another handy way to configure Vim is to do it interactively and save
your settings at the end of the session. For example, on my Fedora Core
2 laptop, a new user account (which uses the global Vim configuration by
default) has the formatoptions option set to
tcql. To see what yours is set to, type :set
formatoptions?
. All of the letters the command returns represent a different enabled
format option. The t means to use line wrapping. If you wanted to
use only the t option, you would type (in normal mode) :set
formatoptions=t
.

Typing :set textwidth? shows me
that none is set, meaning an actual line break doesn't
get entered unless you press Enter. This can be a bit
deceiving, because Vim appears to wrap lines at the window border of your
terminal. However, typing :set list shows the
non-printable characters, including the line boundaries, which appear as
dollar-sign characters. If you type a 200-character line and a carriage return in a 72-character wide window, the lines will seem to wrap, but :set list will
show you that there's only a single end-of-line. To prove it another
way, putting the cursor on the 200th character and hitting the "0" key
in normal mode will bring you to what Vim sees as the beginning of the
line, which will be character 1, whether that looks to you like
it's the same line or not. To get the configuration right for
human-readable text files, I generally use :set textwidth=72.

NOTE: Notice that typing :set followed by any
option and a question mark shows you what the option is set to. To
see all of the options and their current values, type :set
all
, without a question mark. Also, if you don't want to use a
textwidth, but don't want Vim to break lines unless you tell it to, use
the option :set nowrap.

Once you've set your options and have things the way you like them, you
can type :mkvimrc, and Vim will save all of the
options currently in effect to a .vimrc file in your home directory.

Acting differently depending on file type

In all likelihood, you don't edit only one type of file. You
might have Perl, bash, Python, HTML, PHP, SQL, and C program files in
addition to your normal array of configuration files. If you turn on
filetype recognition in Vim, you can set up different options for each
of these types of files. Here's a short section of my
.vimrc file to use as an example:


filetype on
autocmd FileType html,mail set formatoptions=tq textwidth=72
autocms FileType perl set smartindent nowrap

As you can see, I've told Vim to turn on filetype detection.
Once that's turned on, I set options common to HTML and mail files using
a single autocommand. However, as your customization for each filetype
grows, you may choose to source a separate file for different filetypes,
like this:

autocmd FileType html source $HOME/.vimrc.html

This can make debugging easier and your main .vimrc file a
bit cleaner to look at. It also ensures that misconfigurations in your
HTML configuration don't make the editor unusable for text files, and
vice versa.

Mapping shortcut keys

This is where a lot of the real fun starts. Most of the customizations I use
are keyboard mappings configured to make repetitive tasks as easy as
hitting a single key. Keys can be mapped to internal Vim commands,
external shell commands, or even Vim functions you write yourself!

The examples I'll use to illustrate the mapping features all come from
my own use of Vim. I use Vim to write my Sysadmin to Sysadmin articles
every week. I write them in plain HTML, but there are some rules that we
writers, along with the editors and formatting people, have agreed upon
to make life easier for all three parties. One rule is that file names
and commands that are typed in the middle of a sentence be enclosed with
<code> tags. I use this feature a lot, and so I've created a key
mapping that puts my tags in, and then places my cursor in between them:

imap <F12> <code> </code> <Esc>2F>a

What this says, from left to right, is that this mapping will be
effective only in "insert" mode (hence "imap"; visual mode mappings use
"vmap" ... you get the idea). Then I choose my target key affected by the
mapping -- F12 in this case. What follows that are the literal keystrokes
that F12 will replace. Since we're starting in insert mode, the two tags
will be typed in, and then we'll enter Escape to enter
command mode. At that point, entering 2F>a tells the
editor to search backward for the second occurrence of ">" (2F>),
and append (a). This also puts us back in insert mode. In fact, when
you press F12 while you're in insert mode, you never know you left insert mode,
which is nice.

Using shell commands from within Vim can often prove quite useful, even
if it's a brute-force way to do something you don't know how to do
otherwise. My example here does a word count. I check my word count
often while I'm writing these articles, because at some point I know I
have to start wrapping things up before I get too long-winded. I can't
imagine there isn't a way to do this in Vim, but I haven't found it, so
I do it this way:

map <F5> :!wc -w %; sleep 3 <Enter><Enter>

The above line configures things such that when you press F5 in normal
(command) mode, it executes wc -w on the current file,
then gives you three seconds to look at the output. It then presses the Enter key twice to get you back to your file. The important part to remember
here is that you need to prepend the :! to the shell
command! The colon says you're about to enter a command, and
the exclamation point says that the command will not be a Vim or Ex
command, but rather an external shell command.

In closing

The possibilities of key mapping are seemingly endless -- you could
probably spend the rest of your weekends for the rest of the year just
customizing Vim for all of the different tasks you do.

Scripting Vim,
working on multiple files, using multiple buffers, and split window
shortcuts are all left as exercises to the user. I highly recommend
doing a search for "my .vimrc file" on Google, since many people post
their own configuration details, which can be very handy. For those
who really want to get a thorough grounding in all that Vim has to
offer, I strongly recommend Steve
Oualline's "Vi IMproved -- Vim"
. This is a fantastic book.

Finally, if you have a minute, please post your own
killer .vimrc one-liner or even a Vim function here as a comment to this
article. It'll give me and others something to bookmark for reference,
and it's always fun to share hints and hacks with other Vim users!

 

Click Here!