Vim 301: Getting Adept at Vim

1182

If you’ve read and worked with the previous two tutorials on Vim, you’re probably getting reasonably comfortable with the editor. At this point, you should be able to get around very nicely. This time around, I’d like to look at some more advanced features and demonstrate briefly how to set up a Vim configuration file, and to get to the shell and use external commands from within Vim.

As you peel back layers of the Vim onion, you’ll continue to find new functionality. Some of it may be suitable for your workflow, some not so much. Keep what’s useful and discard the rest.

Folding in Vim

In the last installment, we covered using viewports and tabs to make it easier to navigate long documents and multiple documents. There’s one more feature that we should look at for working with really long documents, and that’s folding.

Let’s say you have a document that’s 1,000 lines long. You want to be able to view the first and last 20 lines at the same time. You could do it with viewports, but there’s a quick way to do it using folding.

Folding commands are prefaced with z. Let’s say you want to “fold” 70 lines. You’d run zf70j, which would “fold” all of those lines into a single line that effectively hides those lines until you “open” the fold. To do that, move the cursor onto the fold and run zo. To break down the command: zf tells Vim you’re about to do a fold. 70 tells Vim how many lines to perform the action on, and j is the direction command that tells Vim to fold downward. You could also use k to fold “upward” instead.

You might notice some odd characters inserted in the file. These are markers that tell Vim where the folds end and begin. The folds will continue to exist until they’re deleted. To do that, run zd on the line where the fold is, or zE to delete all folds in a file.

Yes, you can have multiple folds in a document, and even nested folds — that is, folds within another fold. I recommend you take a longish text file and play around with the fold commands to see what you can do. It can come in amazingly handy when working with long files.

  • zfnj creates a fold from the cursor down n lines.
  • zo opens a fold on the cursor.
  • zj moves the cursor to the next fold.
  • zk moves the cursor to the previous fold.
  • zd deletes the fold at the cursor.
  • zE deletes all folds in the document.
  • zM closes all open folds.
  • zR opens all folds.

Setting Up Your Vim Config

Once you start using Vim regularly, you’ll want to edit your Vim configuration file, the .vimrc under your home directory, to keep your favorite settings across sessions and to set up your favorite mappings, abbreviations, etc. Note that most Linux distros ship with a default vimrc located at /etc/vimrc. This is the system-wide configuration, but it can be overridden by your personal .vimrc.

Let’s look at a very simple Vim configuration file:

" .vimrc - startup file for Vim

syntax on
set viminfo='1000,f1,"500,:100,/100
set mouse=a
autocmd FileType html,xml,xsl source ~/.vim/scripts/closetag.vim

The Vim configuration file is basically a collection of Vim commands that are read on startup. The first line of the sample vimrc is a comment. Comments are preceded by quotes (“).

The syntax on command tells Vim to enable syntax highlighting. Vim can perform syntax highlighting for any type of file that has a syntax definition. Syntax files are usually shipped as part of the Vim or Vim enhanced packages and can be found under the /usr/share/vim directory. For instance, on openSUSE 11.2 they’re under /usr/share/vim/vim72/syntax — this will probably vary depending on your distro’s packaging guidelines.

The next command tells Vim how much history and so forth to store in the viminfo file. This makes session info persistent between sessions. So if you exit Vim you’ll still have some history from the previous session. See :help viminfo for more about this.

The set mouse=a command tells Vim to enable the mouse everywhere, even when running in an Xterm. This means that you can, among other things, use the mouse to position the cursor or drag viewports to resize them. I rarely use this myself, but it may prove handy for folks who don’t want to have to remember that Ctrl-w 10< is the way to make the existing vertical viewport 10 columns smaller.

The final command tells Vim to execute a command when it opens any source file that’s XML, XSL, or HTML. In this case, it calls the closetag.vim script, which makes it easy to “close” XML/HTML tags so you don’t have to type closing tags. We’ll get into scripts in the next tutorial.

To edit your .vimrc, just open the file in Vim and make the appropriate edits. You can either restart Vim to see the changes, or use the :source command to re-read the config file like so:

:source ~/.vimrc

Vim has far, far too many options to try to cover all or even most of them in one tutorial. The main thing to understand here is that Vim is almost infinitely customizable, and that if you can think of something that Vim should do (relative to editing text, at least) it’s probably possible.

In and Out of Vim

No man is an island, and no text editor is an operating system, even though Emacs does try pretty hard. Sometimes you need to work on text using external commands or get to a shell without exiting the Vim session.

If you need to get to a shell from inside Vim, without quitting your session, hit Ctrl-z. This is standard shell behavior on Linux systems, assuming you’re using Bash, which is to say it works with other commands running under Bash as well. To return to your session, hit fg at the shell prompt.

Another way to get to the shell is to just enter command mode and use :sh — which will drop you to a new shell and allow you to run your jobs and then return to Vim by using exit.

You can also filter text in Vim through a command, and then bring it back into Vim, without needing to leave Vim at all. A simple example: Let’s say you have a list of names in the buffer that you would like to sort in alphabetical order like this:

Jules
Vincent
Butch
Mia
Marsellus

Use Vim’s selection feature (Ctrl-v) to highlight the list, and then enter this command:

:! sort

That will sort the names in alphabetical order.

You can use this with all kinds of command line utilities. You could call fmt from within Vim to set the width of a file, or call tidy from within Vim to clean up crufty HTML.

Note that you don’t need to use the selection command if you know the range of lines you want to operate on or if you want to operate on the entire file. To filter specific lines, specify the range and then the command:

:x,y ! command

In this case, x would be the starting line, y would be the last line to check, and of course you’d replace command with the command you’d like to use. So, to filter lines 34 through 38 using sort, you’d run:

:34,38 ! sort

To do this globally (the entire buffer), use %, which tells Vim to do the entire buffer:

:% ! sort

The spaces aren’t actually necessary. You can bunch everything up as well, but it’s more readable the other way.

The Dot and Other Useful Tips

This may not be “advanced,” per se but I hadn’t mentioned it prior to now, and thought that it was worth calling out. Want a quick and easy way to redo your last operation? Hit the period (.) in command mode. For instance, enter edit mode and write a few lines of text, then hit Escape. Now hit . and Vim will re-insert the same text. Delete five words using 5dw in command mode. Then hit . and it will do the same thing again. This can be very useful when working with structured text and making repetitive edits.

Need to know how many words are in your document, or a document selection? No sweat. To get the word count for the entire document, use the command g-Ctrl-g (that’s g and then Ctrl-g) to get a report for the number of words in the document, as well as the number of lines and bytes, and position of the cursor. You’ll see a report like this in the status bar at the bottom of Vim:

Col 8 of 8; Line 38 of 38; Word 577 of 577; Byte 3226 of 3227

To get a report on a selection of text, use the commands from the Vim 101 guide to select the portion of text, and then use g-Ctrl-g to sum up the selection.

As an example, to figure out how many words are in a line when the cursor is at the end of the line, you’d use the commands v 0 g-Ctrl-g. The v puts you into select mode. The 0 moves the selection to the beginning of the line and highlights the entire line. And then g-Ctrl-g tells Vim to report the stats for the selected text.

That’s all for this installment. Next time we’ll look at the Vim GUI, Vim plugins and scripts, and other advanced features.