Skip to content

Instantly share code, notes, and snippets.

@Raimondi
Last active February 14, 2026 03:19
Show Gist options
  • Select an option

  • Save Raimondi/4aba07c8697eb7f1609b620082357052 to your computer and use it in GitHub Desktop.

Select an option

Save Raimondi/4aba07c8697eb7f1609b620082357052 to your computer and use it in GitHub Desktop.
A pair of scripts to get a list and order of execution of Vim's autocommand events
Events used:
BufAdd
BufCreate
BufDelete
BufEnter
BufFilePost
BufFilePre
BufHidden
BufLeave
BufNew
BufNewFile
BufRead
BufReadPost
BufReadPre
BufUnload
BufWinEnter
BufWinLeave
BufWipeout
BufWrite
BufWritePost
BufWritePre
ExitPre
FileReadPost
FileReadPre
FileType
GUIEnter
GUIFailed
QuitPre
Syntax
TabClosed
TabClosedPre
TabEnter
TabLeave
TabNew
VimEnter
VimLeave
VimLeavePre
VimResume
VimSuspend
WinClosed
WinEnter
WinLeave
WinNew
WinNewPre
Events executed:
Syntax : afile: foo.c, abuf: 1, amatch: , v:event: {}
BufReadPre : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
BufReadPost : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
FileType : afile: foo.c, abuf: 1, amatch: c, v:event: {}
Syntax : afile: foo.c, abuf: 1, amatch: c, v:event: {}
BufWinEnter : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
BufEnter : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
VimEnter : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
BufNew : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufCreate : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufLeave : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
BufWinLeave : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
BufHidden : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
BufReadPre : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufReadPost : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
FileType : afile: bar.c, abuf: 2, amatch: c, v:event: {}
Syntax : afile: bar.c, abuf: 2, amatch: c, v:event: {}
BufEnter : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufWinEnter : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufNew : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
BufCreate : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
BufLeave : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufWinLeave : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufHidden : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufNewFile : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
FileType : afile: baz.c, abuf: 3, amatch: c, v:event: {}
Syntax : afile: baz.c, abuf: 3, amatch: c, v:event: {}
BufEnter : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
BufWinEnter : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
QuitPre : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
ExitPre : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
BufWinLeave : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
BufUnload : afile: foo.c, abuf: 1, amatch: /Users/israel/Source/playground/foo.c, v:event: {}
BufUnload : afile: bar.c, abuf: 2, amatch: /Users/israel/Source/playground/bar.c, v:event: {}
BufUnload : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
VimLeavePre : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
VimLeave : afile: baz.c, abuf: 3, amatch: /Users/israel/Source/playground/baz.c, v:event: {}
vim9script
def Get()
# Get all autocmd events and format them for use in the script
new
help autocommands
:1/\C\*{event}\*//\C^Name/+2;/\C\*autocmd-events-abc\*/-3y
quit
put!
:%s/\C^\t\(Reading\|Writing\|Buffers\|Options\|Startup and exit\|Terminal\|Various\)$/# \U\1:/
g/^\t/:-1join
:%s/^|\(\w\+\)|\t\+\(.*\)/events->add('\1') # \2/
g/^\s*$/delete _
enddef
Get()
vim9script
# Run this with --cmd 'so set_au_events.vim' to set things up as early as possible
var events: list<string> = []
var log: list<string> = []
const fpath = expand('<script>:p:h') .. '/autocmd_events.log'
delete(fpath)
def Log(event: string)
log->add($'{printf('%-20s', event)}: afile: {expand('<afile>')}, abuf: {expand('<abuf>')}, amatch: {expand('<amatch>')}, v:event: {v:event}')
enddef
def WriteLog()
log->writefile(fpath)
enddef
# List of events as of 9.1.2135
# Uncomment whatever you need
# Beware! The Cmd-events can be problematic if left uncommented because they change how Vim behaves
# READING:
events->add('BufNewFile') # starting to edit a file that doesn't exist
events->add('BufReadPre') # starting to edit a new buffer, before reading the file
events->add('BufRead') # starting to edit a new buffer, after reading the file
events->add('BufReadPost') # starting to edit a new buffer, after reading the file
#events->add('BufReadCmd') # before starting to edit a new buffer |Cmd-event|
events->add('FileReadPre') # before reading a file with a ":read" command
events->add('FileReadPost') # after reading a file with a ":read" command
#events->add('FileReadCmd') # before reading a file with a ":read" command |Cmd-event|
events->add('FilterReadPre') # before reading a file from a filter command
events->add('FilterReadPost') # after reading a file from a filter command
events->add('StdinReadPre') # before reading from stdin into the buffer
events->add('StdinReadPost') # After reading from the stdin into the buffer
# WRITING:
events->add('BufWrite') # starting to write the whole buffer to a file
events->add('BufWritePre') # starting to write the whole buffer to a file
events->add('BufWritePost') # after writing the whole buffer to a file
#events->add('BufWriteCmd') # before writing the whole buffer to a file |Cmd-event|
events->add('FileWritePre') # starting to write part of a buffer to a file
events->add('FileWritePost') # after writing part of a buffer to a file
#events->add('FileWriteCmd') # before writing part of a buffer to a file |Cmd-event|
events->add('FileAppendPre') # starting to append to a file
events->add('FileAppendPost') # after appending to a file
#events->add('FileAppendCmd') # before appending to a file |Cmd-event|
events->add('FilterWritePre') # starting to write a file for a filter command or diff
events->add('FilterWritePost') # after writing a file for a filter command or diff
# BUFFERS:
events->add('BufAdd') # just after adding a buffer to the buffer list
events->add('BufCreate') # just after adding a buffer to the buffer list
events->add('BufDelete') # before deleting a buffer from the buffer list
events->add('BufWipeout') # before completely deleting a buffer
events->add('BufFilePre') # before changing the name of the current buffer
events->add('BufFilePost') # after changing the name of the current buffer
events->add('BufEnter') # after entering a buffer
events->add('BufLeave') # before leaving to another buffer
events->add('BufWinEnter') # after a buffer is displayed in a window
events->add('BufWinLeave') # before a buffer is removed from a window
events->add('BufUnload') # before unloading a buffer
events->add('BufHidden') # just before a buffer becomes hidden
events->add('BufNew') # just after creating a new buffer
events->add('SwapExists') # detected an existing swap file
# OPTIONS:
events->add('FileType') # when the 'filetype' option has been set
events->add('Syntax') # when the 'syntax' option has been set
events->add('EncodingChanged') # after the 'encoding' option has been changed
events->add('TermChanged') # after the value of 'term' has changed
events->add('OptionSet') # after setting any option
# STARTUP AND EXIT:
events->add('VimEnter') # after doing all the startup stuff
events->add('GUIEnter') # after starting the GUI successfully
events->add('GUIFailed') # after starting the GUI failed
events->add('TermResponse') # after the terminal response to |t_RV| is received
events->add('TermResponseAll') # after the terminal response to |t_RV| and others is received
events->add('QuitPre') # when using `:quit`, before deciding whether to exit
events->add('ExitPre') # when using a command that may make Vim exit
events->add('VimLeavePre') # before exiting Vim, before writing the viminfo file
events->add('VimLeave') # before exiting Vim, after writing the viminfo file
events->add('VimSuspend') # when suspending Vim
events->add('VimResume') # when Vim is resumed after being suspended
# TERMINAL:
events->add('TerminalOpen') # after a terminal buffer was created
events->add('TerminalWinOpen') # after a terminal buffer was created in a new window
# VARIOUS:
events->add('FileChangedShell') # Vim notices that a file changed since editing started
events->add('FileChangedShellPost') # After handling a file changed since editing started
events->add('FileChangedRO') # before making the first change to a read-only file
events->add('DiffUpdated') # after diffs have been updated
events->add('DirChangedPre') # before the working directory will change
events->add('DirChanged') # after the working directory has changed
events->add('ShellCmdPost') # after executing a shell command
events->add('ShellFilterPost') # after filtering with a shell command
events->add('CmdUndefined') # a user command is used but it isn't defined
events->add('FuncUndefined') # a user function is used but it isn't defined
events->add('SpellFileMissing') # a spell file is used but it can't be found
events->add('SourcePre') # before sourcing a Vim script
events->add('SourcePost') # after sourcing a Vim script
#events->add('SourceCmd') # before sourcing a Vim script |Cmd-event|
events->add('VimResized') # after the Vim window size changed
events->add('FocusGained') # Vim got input focus
events->add('FocusLost') # Vim lost input focus
events->add('CursorHold') # the user doesn't press a key for a while
events->add('CursorHoldI') # the user doesn't press a key for a while in Insert mode
events->add('CursorMoved') # the cursor was moved in Normal mode
events->add('CursorMovedC') # the cursor was moved in the |Command-line|
events->add('CursorMovedI') # the cursor was moved in Insert mode
events->add('WinNewPre') # before creating a new window
events->add('WinNew') # after creating a new window
events->add('TabNew') # after creating a new tab page
events->add('WinClosed') # after closing a window
events->add('TabClosed') # after closing a tab page
events->add('TabClosedPre') # before closing a tab page
events->add('WinEnter') # after entering another window
events->add('WinLeave') # before leaving a window
events->add('TabEnter') # after entering another tab page
events->add('TabLeave') # before leaving a tab page
events->add('CmdwinEnter') # after entering the command-line window
events->add('CmdwinLeave') # before leaving the command-line window
events->add('CmdlineChanged') # after a change was made to the command-line text
events->add('CmdlineEnter') # after the cursor moves to the command line
events->add('CmdlineLeave') # before the cursor leaves the command line
events->add('CmdlineLeavePre') # before preparing to leave the command line
events->add('InsertEnter') # starting Insert mode
events->add('InsertChange') # when typing <Insert> while in Insert or Replace mode
events->add('InsertLeave') # when leaving Insert mode
events->add('InsertLeavePre') # just before leaving Insert mode
events->add('InsertCharPre') # when a character was typed in Insert mode, before inserting it
events->add('ModeChanged') # after changing the mode
events->add('TextChanged') # after a change was made to the text in Normal mode
events->add('TextChangedI') # after a change was made to the text in Insert mode when popup menu is not visible
events->add('TextChangedP') # after a change was made to the text in Insert mode when popup menu visible
events->add('TextChangedT') # after a change was made to the text in Terminal mode
events->add('TextYankPost') # after text has been yanked or deleted
events->add('SafeState') # nothing pending, going to wait for the user to type a character
events->add('SafeStateAgain') # repeated SafeState
events->add('ColorSchemePre') # before loading a color scheme
events->add('ColorScheme') # after loading a color scheme
events->add('RemoteReply') # a reply from a server Vim was received
events->add('QuickFixCmdPre') # before a quickfix command is run
events->add('QuickFixCmdPost') # after a quickfix command is run
events->add('SessionLoadPost') # after loading a session file
events->add('SessionWritePost') # after writing the session file using the |:mksession| command
events->add('MenuPopup') # just before showing the popup menu
events->add('CompleteChanged') # after Insert mode completion menu changed
events->add('CompleteDonePre') # after Insert mode completion is done, before clearing info
events->add('CompleteDone') # after Insert mode completion is done, after clearing info
events->add('KeyInputPre') # just before a key is processed
events->add('User') # to be used in combination with ":doautocmd"
events->add('SigUSR1') # after the SIGUSR1 signal has been detected
events->add('WinScrolled') # after scrolling or resizing a window
log->add('Events used:')
for event in events->sort()
log->add(event)
autocmd_add([{
replace: true,
group: 'AutoCmdTest',
event: event,
pattern: '*',
cmd: $'call Log("{event}")'
}])
endfor
log->add('')
log->add('Events executed:')
autocmd_add([{
replace: true,
group: 'AutoCmdTestLeave',
event: 'VimLeave',
pattern: '*',
cmd: 'call WriteLog()'
}])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment