chapters/14.markdown @ a16e1fecfe07 default tip
Be clear
| author | Steve Losh <steve@stevelosh.com> |
|---|---|
| date | Mon, 27 Mar 2017 13:10:55 +0000 |
| parents | 4fa876d7523c |
| children | (none) |
Autocommand Groups ================== A few chapters ago we learned about autocommands. Run the following command: :::vim :autocmd BufWrite * :echom "Writing buffer!" Now write the current buffer with `:write` and run `:messages` to view the message log. You should see the `Writing buffer!` message in the list. Now write the current buffer again and run `:messages` to view the message log. You should see the `Writing buffer!` message in the list twice. Now run the exact same autocommand again: :::vim :autocmd BufWrite * :echom "Writing buffer!" Write the current buffer one more time and run `:messages`. You will see the `Writing buffer!` message in the list *four* times. What happened? When you create an autocommand like this Vim has no way of knowing if you want it to replace an existing one. In our case, Vim created two *separate* autocommands that each happen to do the same thing. The Problem ----------- Now that you know it's possible to create duplicate autocommands, you may be thinking: "So what? Just don't do that!" The problem is that sourcing your `~/.vimrc` file rereads the entire file, including any autocommands you've defined! This means that every time you source your `~/.vimrc` you'll be duplicating autocommands, which will make Vim run slower because it executes the same commands over and over. To simulate this, try running the following command: :::vim :autocmd BufWrite * :sleep 200m Now write the current buffer. You may or may not notice a slight sluggishness in Vim's writing time. Now run the command three more times: :::vim :autocmd BufWrite * :sleep 200m :autocmd BufWrite * :sleep 200m :autocmd BufWrite * :sleep 200m Write the file again. This time the slowness will be more apparent. Obviously you won't have any autocommands that do nothing but sleep, but the `~/.vimrc` of a seasoned Vim user can easily reach 1,000 lines, many of which will be autocommands. Combine that with autocommands defined in any installed plugins and it can definitely affect performance. Grouping Autocommands --------------------- Vim has a solution to the problem. The first step is to group related autocommands into named groups. Open a fresh instance of Vim to clear out the autocommands from before, then run the following commands: :::vim :augroup testgroup : autocmd BufWrite * :echom "Foo" : autocmd BufWrite * :echom "Bar" :augroup END The indentation in the middle two lines is insignificant. You don't have to type it if you don't want to. Write a buffer and check `:messages`. You should see both `Foo` and `Bar`. Now run the following commands: :::vim :augroup testgroup : autocmd BufWrite * :echom "Baz" :augroup END Try to guess what will happen when you write the buffer again. Once you have a guess in mind, write the buffer and check `:messages` to see if you were correct. Clearing Groups --------------- What happened when you wrote the file? Was it what you expected? If you thought Vim would replace the group, you can see that you guessed wrong. Don't worry, most people think the same thing at first (I know I did). When you use `augroup` multiple times Vim will *combine* the groups each time. If you want to *clear* a group you can use `autocmd!` inside the group. Run the following commands: :::vim :augroup testgroup : autocmd! : autocmd BufWrite * :echom "Cats" :augroup END Now try writing your file and checking `:messages`. This time Vim only echoed `Cats` when you wrote the file. Using Autocommands in Your Vimrc -------------------------------- Now that we know how to group autocommands and clear those groups, we can use this to add autocommands to `~/.vimrc` that don't add a duplicate every time we source it. Add the following to your `~/.vimrc` file: :::vim augroup filetype_html autocmd! autocmd FileType html nnoremap <buffer> <localleader>f Vatzf augroup END We enter the `filetype_html` group, immediately clear it, define an autocommand, and leave the group. If we source `~/.vimrc` again the clearing will prevent Vim from adding duplicate autocommands. Exercises --------- Go through your `~/.vimrc` file and wrap *every* autocommand you have in groups like this. You can put multiple autocommands in the same group if it makes sense to you. Try to figure out what the mapping in the last example does. Read `:help autocmd-groups`.