33

I've gone through the autocmd.txt help, but the information about this is scattered and not always present (eg. with BufRead).

Could someone who understands this well list the order of these events - with perhaps the conditions marked in parantheses, like

WinEnter   
BufEnter (if this window is for a different buffer than the current)

and so on, for easy reference?

Note (copied from my own comment below): I'm not talking about individual explanations of them, which are OK, but about how they interact with one another and in what order they happen. For eg., WinEnter says "Vim executes the BufEnter autocommands after the WinEnter autocommands", TabEnter says "After triggering the WinEnter and before triggering the BufEnter event", it's all scattered like this into many places. And sometimes it's not mentioned at all (for eg. BufRead doesn't mention whether it runs after BufEnter or before - maybe an expert can infer it from some other piece of info there, but I can't.
So, my intent here is to create a single, simple reference for the order of these events that can be looked up quickly by non-experts, in order to be more precise in our autocmd event specifications.

7
  • I think most of the explanations are OK, can you give a list of the ones you cannot understand ?
    – nobe4
    Commented Aug 24, 2015 at 9:17
  • @Nobe4 I'm not talking about individual explanations of them, which are indeed OK, but about how they interact with one another and in what order they happen. For eg., WinEnter says "Vim executes the BufEnter autocommands after the WinEnter autocommands", TabEnter says "After triggering the WinEnter and before triggering the BufEnter event", it's all scattered like this into many places. And sometimes it's not mentioned at all (for eg. BufRead doesn't mention whether it runs after BufEnter or before - maybe an expert can infer it from some other piece of info there, but I can't.
    – Sundar R
    Commented Aug 24, 2015 at 9:22
  • So, my intent here is to create a single, simple reference for the order of these events that can be looked up quickly by non-experts, in order to be more precise in our autocmd event specifications.
    – Sundar R
    Commented Aug 24, 2015 at 9:23
  • OK I didnt understand the question. You can try to log every event, and see the order of appearance (I can make an answer if you like)
    – nobe4
    Commented Aug 24, 2015 at 9:23
  • Your intent is actually to ask about somebody providing such a simple reference, not create one (yourself) ;)
    – VanLaser
    Commented Aug 24, 2015 at 9:36

3 Answers 3

21

I tried googling for this with different sets of keywords, and struck gold on one such attempt with this result: https://web.archive.org/web/20220121051339/https://developer.ibm.com/tutorials/l-vim-script-5/

Specifically, this part is relevant to the current question:

For example, if you start Vim, edit a file named demo.txt, swap into Insert mode, type in some text, save the file, and then exit, your Vim session receives a series of events like what is shown in Listing 1.

Listing 1. Event sequence in a simple Vim editing session

> vim

  1. BufWinEnter (create a default window)
  2. BufEnter (create a default buffer)
  3. VimEnter (start the Vim session):edit demo.txt
  4. BufNew (create a new buffer to contain demo.txt)
  5. BufAdd (add that new buffer to the session’s buffer list)
  6. BufLeave (exit the default buffer)
  7. BufWinLeave (exit the default window)
  8. BufUnload (remove the default buffer from the buffer list)
  9. BufDelete (deallocate the default buffer)
  10. BufReadCmd (read the contexts of demo.txt into the new buffer)
  11. BufEnter (activate the new buffer)
  12. BufWinEnter (activate the new buffer's window)i
  13. InsertEnter (swap into Insert mode)

It's still not entirely comprehensive (eg. no mention of BufRead aka BufReadPost, but I'm assuming it would come after BufReadCmd), but it's an excellent start.

One crucial missing piece of information though is how the FileType and Syntax autocmd events interact with this (assuming filetype and syntax are already on, and a new file is opened whose filetype and syntax are known to Vim).

4
  • 14
    This is only true when you're editing a single file. Contrary to the popular belief, the order of applying autocmds across multiple files is not well-defined. And even with a single file, the order has changed a few times with the version of Vim. The problems this can (and do) cause for plugins have been discussed to death on vim_dev, and the overall design is not going to change in the predictible future. As for getting a comprehensive understanding, well, there are 139 occurrences of apply_autocmds in the sources for Vim 7.4.827. Good luck with that. Commented Aug 24, 2015 at 10:18
  • @SatoKatsura This is the kind of expert opinion I was looking for, thanks! Is there some reference you can suggest to learn more about this (other than diving into Vim's sources)? Also, this might be entirely out of your area of interest, but do you have any idea if things are better defined in the 'Neovim'-land?
    – Sundar R
    Commented Aug 24, 2015 at 10:28
  • I'm afraid I don't know of any definitive reference. autocmds in Vim are a mess, I don't think it's actually possible to write a definitive reference, except for a few simple cases. I suppose everybody just settles for "usually works", and shrugs when it doesn't. As for neovim, I personally have mixed feelings about the project. I haven't looked at the code recently; I suppose you can get an answer on their issue tracker. Commented Aug 24, 2015 at 10:49
  • Also the term of "event" itself should subvert the idea of too fixed an order.
    – VanLaser
    Commented Aug 24, 2015 at 13:09
17

To complete the @sundar answer:

You can log the order of the events simply with a logging function:

augroup EventLoggin
  autocmd!
  autocmd BufNewFile * call s:Log('BufNewFile')
  autocmd BufReadPre * call s:Log('BufReadPre')
  ...
  autocmd User * call s:Log('User')
augroup END

function! s:Log(eventName) abort
  silent execute '!echo '.a:eventName.' >> log'
endfunction

See the full file here: https://github.com/lervag/dotvim/blob/3aa56d621423540bfa26b330182b3e97ed4ee5e8/personal/plugin/log-autocmds.vim (NB: As the previous gist has disappeared, I've replaced the URL to Karl's plugin --Luc)

You can then tail -f log and you get a real-time autocommand events activity.

3
  • 3
    I made a simple plugin for this, see here. Commented Aug 25, 2015 at 7:49
  • 6
    Note that @KarlYngveLervåg has moved its plugin to another path. Thank Karl! Commented Oct 27, 2016 at 15:57
  • Thanks for noticing and commenting, Luc! (Note: I can't update my comment to fix the dead link, sorry!) Commented Oct 28, 2016 at 8:35
11

This is the first result show up on google search about 'Vim event order'. So, i think it's worth providing the actual answer.

Using the command from @nobe4 answer, this is the result:

  1. Opening a new file, insert letter 'a', write and quit.
Syntax
User
BufNewFile
FileType
Syntax
BufWinEnter
BufEnter
VimEnter
CursorMoved
FocusGained
InsertEnter
CursorHoldI
InsertCharPre
CursorMovedI
TextChangedI
InsertLeave
CursorMoved
CmdlineEnter
CmdlineChanged
CmdlineChanged
CmdlineLeave
BufWrite
BufWritePre
BufWritePost
QuitPre
ExitPre
BufWinLeave
BufUnload
VimLeavePre
BufNew
BufNew
VimLeave
  1. Opening an existing file, append letter 'a', write and quit.
Syntax
User
BufReadPre
BufRead
BufReadPost
FileType
Syntax
BufWinEnter
BufEnter
VimEnter
CursorMoved
FocusGained
InsertEnter
CursorMovedI
InsertCharPre
CursorMovedI
TextChangedI
InsertLeave
CursorMoved
CmdlineEnter
CmdlineChanged
CmdlineChanged
CmdlineLeave
BufWrite
BufWritePre
BufWritePost
QuitPre
ExitPre
BufWinLeave
BufUnload
VimLeavePre
BufNew
BufNew
VimLeave
  1. Opening a new file, write and quit.
Syntax
User
BufNewFile
FileType
Syntax
BufWinEnter
BufEnter
VimEnter
CursorMoved
FocusGained
CmdlineEnter
CmdlineChanged
CmdlineChanged
CmdlineLeave
BufWrite
BufWritePre
BufWritePost
QuitPre
ExitPre
BufWinLeave
BufUnload
VimLeavePre
BufNew
BufNew
VimLeave
3
  • Welcome to Vi and Vim!
    – D. Ben Knoble
    Commented Jan 25, 2022 at 14:22
  • Some times au BufEnter * if &ft=='help' | call My_func() | endif or au BufEnter * if &buftype =='help' | call My_func() | endif is triggered even when I open My_any_FILE.zsh. I guessed the reason was that 'filetype' or 'buftype' does not update until BufEnter finishes, but from your conclusion, my guess seems wrong. So why those 2 autocmds are triggered even when I open My_any_FILE.zsh? Thx
    – Good Pen
    Commented Apr 3, 2022 at 1:40
  • What about launching Vim without arguments (i.e. vim in the current directory)? It's the only missing option, I'd be interested to know that as well.
    – mEm
    Commented Nov 28, 2023 at 10:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.