---@class std.auto.AutocmdDef ---@field events string|string[] Event name(s), e.g. `'BufWritePost'` or `{ 'BufEnter', 'BufWritePost' }` ---@field command? string|function Vim command string or Lua callback. Mutually exclusive with `callback` as a string. ---@field callback? function Lua callback. Prefer `command` for functions. ---@field description? string Human-readable description shown in `:autocmd` ---@field buffer? integer Buffer number for buffer-local autocmds. When set, augroup is not attached. ---@field once? boolean Autocmd fires once then auto-removes ---@field pattern? string|string[] File pattern(s), e.g. `'*.lua'` or `{ '*.lua', '*.fnl' }` --- Creates an autocommand group and returns a registration function. --- --- Each call creates or resets an augroup via `nvim_create_augroup(…, { clear = true })`. --- Re-calling with the same `group_name` replaces all previous autocmds in that group. --- Buffer-local autocmds (when `buffer` is set) are not attached to the augroup; --- Neovim auto-cleans them when the buffer is deleted. --- --- ```lua --- local auto = require 'std.auto' --- --- -- single autocmd --- auto 'highlight_yank' { --- events = 'TextYankPost', --- pattern = '*', --- command = function() vim.hl.on_yank { timeout = 169 } end, --- } --- --- -- multiple autocmds sharing one group --- auto 'statusline' { --- { --- events = 'LspAttach', --- command = function() vim.cmd.redrawstatus() end, --- }, --- { --- events = { 'BufEnter', 'WinEnter' }, --- command = function() vim.cmd.redrawstatus() end, --- }, --- } --- --- -- buffer-local (no augroup attached) --- auto 'restore_cursor' { --- events = 'BufWinEnter', --- buffer = bufnr, --- once = true, --- command = function() --- vim.api.nvim_win_set_cursor(0, { line, col }) --- end, --- } --- --- -- toggle: re-calling clears previous autocmds --- local existing = vim.api.nvim_get_autocmds({ group = 'd2_validate' }) --- if #existing > 0 then --- pcall(vim.api.nvim_del_augroup_by_name, 'd2_validate') --- else --- auto 'd2_validate' { --- events = 'BufWritePost', --- pattern = '*.d2', --- command = validate, --- } --- end --- ``` --- ---@param group_name string Augroup name. Re-calling with the same name clears all ---previous autocmds in the group. ---@return fun(definitions: std.auto.AutocmdDef|std.auto.AutocmdDef[]) register Registers one or more autocmds into the group. ---@see vim.api.nvim_create_augroup ---@see vim.api.nvim_create_autocmd return function(group_name) local group = vim.api.nvim_create_augroup(group_name, { clear = true, }) --- adds new autocommands to the outer group --- @param list_of_autocommands table a single autocommand definition, or a list of those. return function(list_of_autocommands) if list_of_autocommands.events then list_of_autocommands = { list_of_autocommands, } end for _, autocommand in ipairs(list_of_autocommands) do vim.validate('autocommand.events', autocommand.events, { 'string', 'table' }) vim.validate('autocommand.command', autocommand.command, { 'string', 'function' }, true) vim.validate('autocommand.callback', autocommand.callback, 'function', true) vim.validate('autocommand.description', autocommand.description, 'string', true) vim.validate('autocommand.buffer', autocommand.buffer, 'number', true) vim.validate('autocommand.once', autocommand.once, 'boolean', true) vim.validate('autocommand.pattern', autocommand.pattern, { 'string', 'table' }, true) -- command and callback are mutually exclusive. -- one of them has to be nil local command = nil local callback = nil if type(autocommand.command) == 'function' then callback = autocommand.command else command = autocommand.command end vim.api.nvim_create_autocmd(autocommand.events, { desc = autocommand.description, group = autocommand.buffer and nil or group, buf = autocommand.buffer, pattern = autocommand.pattern, once = autocommand.once, command = command, callback = callback, }) end end end