Learn Vimscript the Hard Way


Up to this point we've covered single commands. For the next third of the book we're going to look at Vimscript as a programming language. This won't be as instantly gratifying as the rest of what you've learned, but it will lay the groundwork for the last part of the book, which walks through creating a full-fledged Vim plugin from scratch.

Let's get started. The first thing we need to talk about are variables. Run the following commands:

:let foo = "bar"
:echo foo

Vim will display bar. foo is now a variable, and we've assigned it a string: "bar". Now run these commands:

:let foo = 42
:echo foo

Vim will display 42, because we've reassigned foo to the integer 42.

From these short examples it may seem like Vimscript is dynamically typed. That's not the case, but we'll talk more about that later.

Options as Variables

You can read and set options as variables by using a special syntax. Run the following commands:

:set textwidth=80
:echo &textwidth

Vim will display 80. Using an ampersand in front of a name tells Vim that you're referring to the option, not a variable that happens to have the same name.

Let's see how Vim works with boolean options. Run the following commands:

:set nowrap
:echo &wrap

Vim displays 0. Now try these commands:

:set wrap
:echo &wrap

This time Vim displays 1. This is a very strong hint that Vim treats the integer 0 as "false" and the integer 1 as "true". It would be reasonable to assume that Vim treats any non-zero integer as "truthy", and this is indeed the case.

We can also set options as variables using the let command. Run the following commands:

:let &textwidth = 100
:set textwidth?

Vim will display textwidth=100.

Why would we want to do this when we could just use set? Run the following commands:

:let &textwidth = &textwidth + 10
:set textwidth?

This time Vim displays textwidth=110. When you set an option using set you can only set it to a single literal value. When you use let and set it as a variable you can use the full power of Vimscript to determine the value.

Local Options

If you want to set the local value of an option as a variable, instead of the global value, you need to prefix the variable name.

Open two files in separate splits. Run the following command:

:let &l:number = 1

Now switch to the other file and run this command:

:let &l:number = 0

Notice that the first window has line numbers and the second does not.

Registers as Variables

You can also read and set registers as variables. Run the following command:

:let @a = "hello!"

Now put your cursor somewhere in your text and type "ap. This command tells Vim to "paste the contents of register a here". We just set the contents of that register, so Vim pastes hello! into your text.

Registers can also be read. Run the following command:

:echo @a

Vim will echo hello!.

Select a word in your file and yank it with y, then run this command:

:echo @"

Vim will echo the word you just yanked. The " register is the "unnamed" register, which is where text you yank without specifying a destination will go.

Perform a search in your file with /someword, then run the following command:

:echo @/

Vim will echo the search pattern you just used. This lets you programmatically read and modify the current search pattern, which can be very useful at times.


Go through your ~/.vimrc file and change some of the set and setlocal commands to their let forms. Remember that boolean options still need to be set to something.

Try setting a boolean option like wrap to something other than zero or one. What happens when you set it to a different number? What happens if you set it to a string?

Go back through your ~/.vimrc file and undo the changes. You should never use let if set will suffice -- it's harder to read.

Read :help registers and look over the list of registers you can read and write.