76

I understand how auto commands work, and how to use them, but I'm somewhat unsure of what augroup is for. I read in :help augroup

                                                    *:aug* *:augroup*
:aug[roup] {name}               Define the autocmd group name for the
                                following ":autocmd" commands.  The name "end"
                                or "END" selects the default group.
                                To avoid confusion, the name should be
                                different from existing {event} names, as this
                                most likely will not do what you intended.

This doesn't really explain why they are useful, or why I would ever want to make an autocommand group name over just defining a bunch of autocommands next to each other.

For example, if autocommands foo and bar are related, why would I want to do

augroup spam
  au!
  au foo * foo
  au bar * bar
augroup END

when I could just do

"Autocommands for spam
au foo * foo
au bar * bar

Unless I'm misunderstanding what augroups are really for. So why are they useful?

guntbert
  • 1,245
  • 1
  • 13
  • 27
DJMcMayhem
  • 17,581
  • 5
  • 53
  • 85
  • For readers from 2022, see this well-written detailed answer(with examples): https://vi.stackexchange.com/a/39320/10189 – NeoZoom.lua Nov 23 '22 at 15:40

3 Answers3

74

The main reason to use augroups is to allow greater control over ranges of autocommands, e.g. to delete a bunch of autocommands in one go. A common pattern is to use the au! as the first part of a group. This removes all existing autocommands in the group, and allows one to start afresh. If you did not use a group, then au! would remove all/many autocommands that you did not want to remove.

Deleting autocommands is actually quite common, for instance in plugins, because this allows one to source a plugin/ftplugin multiple times. If you did not delete the autocommands, then each time you sourced the plugin/ftplugin you would add a new copy of the same autocommand. This is also true for your vimrc file. By using a group in your vimrc file, it becomes safe to reload it.

For more info, see :h 40.3.

Karl Yngve Lervåg
  • 9,494
  • 25
  • 35
  • So what's the effect/drawback of having duplicate autocommands? I'm learning augroup so sorry for this being maybe a bad question. – NeoZoom.lua Nov 22 '22 at 10:26
  • 1
    The effect is that the autocommand will fire multiple times. In some cases, this does not matter. In other cases, it will lead to undesireable results. An example: If you have an autocommand group for autocommands on motion triggers, then having multiple of these may result in lagging and reduced performance. – Karl Yngve Lervåg Nov 22 '22 at 21:34
39

Autocommand groups give you the opportunity to organize your autocommands, which is a quite useful feature in and of itself.

Say you are writing a plugin. Grouping your plugin's autocommands under your own namespace makes sense, if only because it lets you enable/disable your autocommands at will.

Your vimrc is not fundamentally different from a plugin/foo.vim so, all you get with autocommand groups is basically more control over your setup.

In practice…

If you don't assign them to a group, autocommands are "installed" in the global group by default. Installing related autocommands in their own group not only makes things clearer but it allows you to prevent the dreaded "pile-up" effect very easily and with a single !:

augroup spam             versus    autocmd! Foo * foo
    autocmd!                       autocmd! Bar * bar
    autocmd Foo * foo
    autocmd Bar * bar
augroup END

On the left, the whole group is uninstalled at once, before each autocommand of that group is properly installed. Neat.

On the right, Vim will wastefully run through the same "uninstall/install" routine for each autocommand. Dirty.

But you don't have to write that whole block every time if you don't want to. Autocommands can be assigned directly to a group so you can define a group somewhere:

augroup spam
    autocmd!
augroup END

and put your autocommands where you want, even in another script:

autocmd spam Foo * foo
autocmd spam Bar * bar

This would give you:

  • namespacing
  • pile-up prevention
  • order
  • flexibility

--- EDIT ---

Grouping autocommands is not the only way to prevent the pile-up problem. If you don't like the augroup ceremonial, you can simply append a ! to :autocmd:

autocmd! Foo * foo

to uninstall any already installed autocommand on the Foo event and the * pattern before adding a new one. It definitely works in the simplest cases but it doesn't scale up very well.

It is too easy to fall into the habit of using that ! systematically, thinking it's a silver bullet, and create hard to debug problems down the line. For example, the snippet below installs two autocommands in the user's vimrc:

" line 23 of ~/.vimrc
autocmd! Syntax * echom 'hi_1'

" line 414 autocmd! Syntax * echom 'hi_2' | echom 'hi_3'

But the second autocommand will uninstall the first one and only one will be executed in the end… an issue easily avoided with a group:

" line 10 of ~/.vimrc
augroup MyStuff
    autocmd!
augroup

" line 26 autocmd MyStuff Syntax * echom 'hi_1'

" line 417 autocmd MyStuff Syntax * echom 'hi_2' | echom 'hi_3'

romainl
  • 40,486
  • 5
  • 85
  • 117
  • If I just need pile-up prevention, is using autocmd! Foo * foo for each autocmd good enough ? If so, I do not need to care where the group, say spam, begins. – Good Pen Mar 26 '22 at 09:54
  • autocmd! Foo * foo is slightly messy but definitely good enough. 2. autocmd! Foo * foo is not added to the spam group so yeah, you don't need to care about spam as it is totally irrelevant.
  • – romainl Mar 26 '22 at 10:20