Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/lua/std/auto.lua

Raw
---@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