Search code examples
vimpluginsautocmd

Is there a clean way to augment a `BufWrite` autocmd in Vim?


I've recently installed the VimWiki plug-in, and am learning about Vim's plugin architecture in general (and better using directories like after/ftplugin instead of cramming everything into my .vimrc file).

I would like to call a function prior to writing wiki files, like so:

autocmd BufWrite *.wiki call CleanMarkdown()

However, vimwiki sets its own BufWrite autocommand, which updates any tables-of-contents in the wiki file. I could clobber this autocommand with my own function that calls both the CleanMarkdown() plus whatever vimwiki is doing today, but that would be brittle in the face of possible future changes in the vimwiki plugin.

Is there a standard way to add to the list of things to do for a BufWrite autocommand?


Solution

  • Multiplicity of autocmds

    There can be many :autocmds for any event; the command is cummulative. The corresponding :autocmd! removes certain sets of commands (depending on the arguments given to it).

    If you don't specify a [group], the autocmd will be defined in the global space, and there's a high risk of getting this cleared by some :autocmd!. Therefore, it is recommended to specify a [group] (especially in plugins). With this, you avoid that another (mis-behaving) plugin or customization clobbers your autocmd.

    Integrating with vimwiki plugin

    As the plugin already defines its own filetype, you don't need to duplicate the filetype detection logic, i.e. the *.wiki pattern. Instead, if you put your :autocmd definition in ~/.vim/after/ftplugin/vimwiki.vim, you can use the <buffer> special pattern to make this autocmd apply only to the current (VimWiki) buffer.

    augroup MyVimWikiCleanup
    autocmd BufWrite <buffer> call CleanMarkdown()
    augroup END
    

    Ordering

    The :autocmds are executed in the order in which they were defined. By using the after directory, yours will be executed after the plugin's.