Now we're going to look at a topic almost as important as mappings: autocommands.
Autocommands are a way to tell Vim to run certain commands whenever certain events happen. Let's dive right into an example.
Open a new file with :edit foo
and close it right away with :quit
. Look on
your hard drive and you'll notice that the file is not there. This is because
Vim doesn't actually create the file until you save it for the first time.
Let's change it so that Vim creates files as soon as you edit them. Run the following command:
:autocmd BufNewFile * :write
This is a lot to take in, but try it out and see that it works. Run :edit foo
again, close it with :quit
, and look at your hard drive. This time the file
will be there (and empty, of course).
You'll have to close Vim to remove the autocommand. We'll talk about how to avoid this in a later chapter.
Let's take a closer look at the autocommand we just created:
:autocmd BufNewFile * :write
^ ^ ^
| | |
| | The command to run.
| |
| A "pattern" to filter the event.
|
The "event" to watch for.
The first piece of the command is the type of event we want to watch for. Vim offers many events to watch. Some of them include:
filetype
setting.This is just a tiny sample of the available events. There are many more you can use to do lots of interesting things.
The next part of the command is a "pattern" that lets you be more specific about when you want the command to fire. Start up a new Vim instance and run the following command:
:autocmd BufNewFile *.txt :write
This is almost the same as the last command, but this time it will only apply to
files whose names end in .txt
.
Try it out by running :edit bar
, then :quit
, then :edit bar.txt
, then
:quit
. You'll see that Vim writes the bar.txt
automatically, but doesn't
write bar
because it doesn't match the pattern.
The final part of the command is the command we want to run when the event
fires. This is pretty self-explanatory, except for one catch: you can't use
special characters like <cr>
in the command. We'll talk about how to get
around this limitation later in the book, but for now you'll just have to live
with it.
Let's define another autocommand, this time using a different event. Run the following command:
:autocmd BufWritePre *.html :normal gg=G
We're getting a bit ahead of ourselves here because we're going to talk about
normal
later in the book, but for now you'll need to bear with me because it's
tough to come up with useful examples at this point.
Create a new file called foo.html
. Edit it with Vim and enter the following
text exactly, including the whitespace:
<html>
<body>
<p>Hello!</p>
</body>
</html>
Now save this file with :w
. What happened? Vim seems to have reindented the
file for us before saving it!
For now I want you to trust me that running :normal gg=G
will tell Vim to
reindent the current file. Don't worry about how that works just yet.
What we do want to pay attention to is the autocommand. The event type is
BufWritePre
, which means the event will be checked just before you write any
file.
We used a pattern of *.html
to ensure that this command will only fire when
we're working on files that end in .html
. This lets us target our
autocommands at specific files, which is a very powerful idea that we'll
continue to explore later on.
You can create a single autocommand bound to multiple events by separating the events with a comma. Run this command:
:autocmd BufWritePre,BufRead *.html :normal gg=G
This is almost like our last command, except it will also reindent the code whenever we read an HTML file as well as when we write it. This could be useful if you have coworkers that don't indent their HTML nicely.
A common idiom in Vim scripting is to pair the BufRead
and BufNewFile
events
together to run a command whenever you open a certain kind of file, regardless
of whether it happens to exist already or not. Run the following command:
:autocmd BufNewFile,BufRead *.html setlocal nowrap
This will turn line wrapping off whenever you're working on an HTML file.
One of the most useful events is the FileType
event. This event is fired
whenever Vim sets a buffer's filetype
.
Let's set up a few useful mappings for a variety of file types. Run the following commands:
:autocmd FileType javascript nnoremap <buffer> <localleader>c I//<esc>
:autocmd FileType python nnoremap <buffer> <localleader>c I#<esc>
Open a Javascript file (a file that ends in .js
), pick a line and type
<localleader>c
. This will comment out the line.
Now open a Python file (a file that ends in .py
), pick a line and type
<localleader>c
. This will comment out the line, but it will use Python's
comment character!
Using autocommands alongside the buffer-local mappings we learned about in the last chapter we can create mappings that are specific to the type of file that we're editing.
This reduces the load on our minds when we're coding. Instead of having to think about moving to the beginning of the line and adding a comment character we can simply think "comment this line".
Skim :help autocmd-events
to see a list of all the events you can bind
autocommands to. You don't need to memorize each one right now. Just try to
get a feel for the kinds of things you can do.
Create a few FileType
autocommands that use setlocal
to set options for your
favorite filetypes just the way you like them. Some options you might like to
change on a per-filetype basis are wrap
, list
, spell
, and number
.
Create a few more "comment this line" autocommands for filetypes you work with often.
Add all of these autocommands to your ~/.vimrc
file. Use your shortcut
mappings for editing and sourcing it quickly, of course!