chapters/19.markdown @ ea7cfb4681d9

typo? seems like variable scope is needed when referencing the variable
author Lauri Heiskanen <lauri.heiskanen@nimble.fi>
date Sat, 07 Jan 2012 15:21:23 +0200
parents e66e6a4e104d
children 69162b499ec1
Variables
=========

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 we've learned, but it will lay the
groundwork for the last part, which walks through creating a full-fledged Vim
plugin from scratch.

The first thing we need to talk about are variables.

Run the following commands:

    :::vim
    :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:

    :::vim
    :let foo = 42
    :echo foo

Vim will display "42", because we've reassigned `bar` to the integer "42".  From
this it may seem that 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:

    :::vim
    :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:

    :::vim
    :set nowrap
    :echo &wrap

Vim displays "0".  Now try these commands:

    :::vim
    :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's 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.  Run the following commands:

    :::vim
    :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:

    :::vim
    :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:

    :::vim
    :let &l:number = 1

Now switch to the other file and run this command:

    :::vim
    :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:

    :::vim
    :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:

    :::vim
    :echo @a

Vim will echo "hello!".

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

    :::vim
    :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:

    :::vim
    :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.

Exercises
---------

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.