Simple Vim Tips

Apologies to anyone coming here, from the Vim Tips pages, expecting to find lots of advanced tips; these pages are merely a collection of things that I find useful (or easily forgotten) for my own Vim usage.

Managing Options

To display the current setting of an option (e.g. expandtab), use:

:set expandtab?

and to see in which scripts it is changed, use:

:verbose set expandtab?

Syntax Highlighting and Modeline

As a security measure, Vim does not allow the modeline to achieve a great deal in terms of configuration. One of its limitations is that you can't turn syntax highlighting off for a particular file. However, there is a workaround; simply assign the syntax filetype to an empty value, for example:

# vim: tw=80 ts=4 syntax=

Let and Set

Both let and set can be used to set variables and options. However, there is a fundamental difference, which is not necessarily obvious: let can evaluate expressions whilst set treats values literally (and is specifically used for Vim options). So, for instance, if you want to use the patchmode option to include the original file's date, you'd need something like the following:

autocommand filetype vim let &l:patchmode='.'.strftime('%Y%m%d',getftime(@%))

This would rename script.vim to script.vim.20110526, assuming that the file's modification date was the 26th May 2011. However, if you used:

autocommand filetype vim setlocal

script.vim would be renamed to script.vim'.'.strftime('%Y%m%d').

The advantage of using set(local) is that you can configure multiple variables with the same command, whilst let allows only one. For example:

set ignorecase smartcase incsearch

would have to be rewritten thus:

let &ignorecase=1
let &smartcase=1
let &incsearch=1

Note that let &l:option=value is the equivalent of setlocal option=value. Also, for boolean values, let interprets zero as false and non-zero as true. Finally the @% argument to getftime() refers to the name of the current file (@ refers to a register, and % means the register containing the current file's name).

Vanishing Error Messages

When Vim loads a file, it sometimes runs various scripts and functions (:help autocommand). If it encounters errors, they are displayed only briefly; sometimes too briefly to read. To view the messages at your leisure, use :messages. This also works for success messages.

Redirecting :g output to a file

Let's say you want to create a new file containing all and only those lines on which a certain word appears. This can be done thus: :g/word/.w!>>filename. Thanks to Gary Johnson (vim_use mailing list).

Running a shell command on the buffer

If you want to run a command like uniq, sort, or grep, on the contents of the current buffer, without having to save the buffer, use :w !command. This sends the buffer's contents to the command via standard input. The command's output will appear in a new window. For more information, see :help :w_c and :help :range!.

If you want the results of the command to replace the contents of the current buffer, use :% !command (this is often handy with the uniq command).

Saving a file (buffer) to a new name

If you're editting a file, and then write it to a new file name (:w filename), be careful if you save it again later using just :w (without specifying the file name). One might expect the file to be saved with its new name, leaving the original intact. However, Vim will save the file using its original name.

Editting Vim's Command Line

If you're entering a command on the “:” command line, there are many handy shortcuts. CTRL-R followed by various symbols inserts the contents of various buffers; for instance, CTRL-R" inserts the unnamed buffer. CTRL-R followed by CTRL-A followed by another control character inserts various items of text from the cursor position (see :help c_CTRL-R).

You can also enter control characters (ASCII codes below 32) using CTRL-V. Just type CTRL-V followed by CTRL and the letter you want. For instance, if you want a CTRL-G (the BELL code), type CTRL-V followed by CTRL-G. Note that some control characters have special meaning.

There are two control characters that have special effects on the command line. (1) The TAB character (CTRL-I) has a variety of effects. If you hit the TAB key after the colon, all you'll get is an exclamation mark, unless you happen to hit it after :%s/ in which case, Vim is clever enough to insert a tab character for you to search on. Hitting CTRL-I has the same effect in both cases. If, however, you hit TAB after :w myF, Vim will try to complete the file name beginning with “myF”. (2) The Line feed character (CTRL-J), which marks the end of a line in *nix, and is part of the end of a line in DOS/Windows, cannot be entered on the command line; all you get is the NULL character (^@).

Copy and Paste in Windows

Vim maintains its own cut (yank) and paste registers, which are separate to Windows' single system register. To refer to Windows' system register, precede the y(ank) or p(aste) command with " followed by +. The " indicates that we wish to specify a particular register, and the + indicates the Windows register. So, to paste the Windows buffer into Vim, use "+p.

Split Diff

If you use the “Split Diff with...” feature (look under the File menu in Windows), Vim automatically folds blocks of lines that match. To reveal all the folded lines, just type zr.

Be consistent when opening files to do a diff. Always open the earliest or latest version first. Doesn't matter which one, as long as you are consistent. It's very confusing forgetting which buffer is the most recent, and being consistent helps your memory.

Simple Search

Use the :g (global) command, with “p” for print. To display all lines that contain some string, use :g/something/p.

Running Commands on Specific Lines

The :g (global) command is used to select lines on which to perform some operation. The operation can be an Ex command such as “p” for print, as suggested in the tip above (type :help :index for more information on Ex commands) . It can also be used to join lines like the Normal mode “J” command, but in this case, you can have it operate on specific lines throughout the entire file. For instance, :g/<[^>]\+/p will join lines where an HTML tag's attributes are spread over two or more lines (it's not clever enough to join more than the first two lines, but you can run the command repeatedly to achieve that effect).

Find lines that don't contain something

There are two ways to do a search for strings that do not match a pattern. One involves modifying the search command, the other involves modifying the search pattern.

To search for all lines that do not match a pattern of interest, modify the g command by appending an exclamation mark (“!”) to the g. For example: :g!/notthis/p

The other method is to search for lines that match a pattern that excludes the pattern of interest. The search pattern here is start–of–line, exclusive set (use the character(s) that you want to exclude), one or more of this set (you may want to use “*” for zero or more), then the end–of–line. You have to include both the start and end of lines, since if you exclude them, the pattern will match a line that does contain the pattern, since it will match the parts of such a line that don't contain the specified character(s). Example, to find all lines not containing the commercial at sign (“@”): :g/^[^@]\+$/p

Simple Search and Replace

Here's how to search for every occurence of “something” and replace it with “else”. Asking you each time to confirm the replace: :%s/something/else/gc

Typing a colon puts Vim into command mode. “%” means search every line in the file. “s” means perform a subsitute operation. The bit between the first and second “/” is the string to search for. The bit between the second and third “/” is the string to replace with. The “g” means perform this operation globally on each line (without this, Vim would only perform the replace on the first occurence on each line). Finally, the “c” means ask the user for confirmation before each replacement (to save time, you can press a in response to the question to have all the remaining replacements carried out without the confirmation.

Debug Vim Scripts

Suppose you are writing an indent script and want to display the value of some variable during the script's processing. You can do this with the following command, which has the advantage of waiting until you have time to read it. Thus, it acts as a breakpoint of sorts. Press enter to continue processing.

call input("myvar = ".myvar)

The command :script lists all the scripts that have been loaded, which is handy for confirming that the script you're testing has actually been loaded!

Note that syntax errors in an indent script seem to not generate an error message, although the file-to-be-viewed/editted that triggers the loading of the indent file does seem to take a long time to load. If anyone knows that they are generated and knows how to view them, please let me know.

Home About Me
Copyright © Neil Carter

Content last updated: 2011-08-08