123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- local buf_storage = require("nui.utils.buf_storage")
- local is_type = require("nui.utils").is_type
- local feature = require("nui.utils")._.feature
- local autocmd = {
- event = {
- -- after adding a buffer to the buffer list
- BufAdd = "BufAdd",
- -- deleting a buffer from the buffer list
- BufDelete = "BufDelete",
- -- after entering a buffer
- BufEnter = "BufEnter",
- -- after renaming a buffer
- BufFilePost = "BufFilePost",
- -- before renaming a buffer
- BufFilePre = "BufFilePre",
- -- just after buffer becomes hidden
- BufHidden = "BufHidden",
- -- before leaving a buffer
- BufLeave = "BufLeave",
- -- after the 'modified' state of a buffer changes
- BufModifiedSet = "BufModifiedSet",
- -- after creating any buffer
- BufNew = "BufNew",
- -- when creating a buffer for a new file
- BufNewFile = "BufNewFile",
- -- read buffer using command
- BufReadCmd = "BufReadCmd",
- -- after reading a buffer
- BufReadPost = "BufReadPost",
- -- before reading a buffer
- BufReadPre = "BufReadPre",
- -- just before unloading a buffer
- BufUnload = "BufUnload",
- -- after showing a buffer in a window
- BufWinEnter = "BufWinEnter",
- -- just after buffer removed from window
- BufWinLeave = "BufWinLeave",
- -- just before really deleting a buffer
- BufWipeout = "BufWipeout",
- -- write buffer using command
- BufWriteCmd = "BufWriteCmd",
- -- after writing a buffer
- BufWritePost = "BufWritePost",
- -- before writing a buffer
- BufWritePre = "BufWritePre",
- -- info was received about channel
- ChanInfo = "ChanInfo",
- -- channel was opened
- ChanOpen = "ChanOpen",
- -- command undefined
- CmdUndefined = "CmdUndefined",
- -- command line was modified
- CmdlineChanged = "CmdlineChanged",
- -- after entering cmdline mode
- CmdlineEnter = "CmdlineEnter",
- -- before leaving cmdline mode
- CmdlineLeave = "CmdlineLeave",
- -- after entering the cmdline window
- CmdWinEnter = "CmdwinEnter",
- -- before leaving the cmdline window
- CmdWinLeave = "CmdwinLeave",
- -- after loading a colorscheme
- ColorScheme = "ColorScheme",
- -- before loading a colorscheme
- ColorSchemePre = "ColorSchemePre",
- -- after popup menu changed
- CompleteChanged = "CompleteChanged",
- -- after finishing insert complete
- CompleteDone = "CompleteDone",
- -- idem, before clearing info
- CompleteDonePre = "CompleteDonePre",
- -- cursor in same position for a while
- CursorHold = "CursorHold",
- -- idem, in Insert mode
- CursorHoldI = "CursorHoldI",
- -- cursor was moved
- CursorMoved = "CursorMoved",
- -- cursor was moved in Insert mode
- CursorMovedI = "CursorMovedI",
- -- diffs have been updated
- DiffUpdated = "DiffUpdated",
- -- directory changed
- DirChanged = "DirChanged",
- -- after changing the 'encoding' option
- EncodingChanged = "EncodingChanged",
- -- before exiting
- ExitPre = "ExitPre",
- -- append to a file using command
- FileAppendCmd = "FileAppendCmd",
- -- after appending to a file
- FileAppendPost = "FileAppendPost",
- -- before appending to a file
- FileAppendPre = "FileAppendPre",
- -- before first change to read-only file
- FileChangedRO = "FileChangedRO",
- -- after shell command that changed file
- FileChangedShell = "FileChangedShell",
- -- after (not) reloading changed file
- FileChangedShellPost = "FileChangedShellPost",
- -- read from a file using command
- FileReadCmd = "FileReadCmd",
- -- after reading a file
- FileReadPost = "FileReadPost",
- -- before reading a file
- FileReadPre = "FileReadPre",
- -- new file type detected (user defined)
- FileType = "FileType",
- -- write to a file using command
- FileWriteCmd = "FileWriteCmd",
- -- after writing a file
- FileWritePost = "FileWritePost",
- -- before writing a file
- FileWritePre = "FileWritePre",
- -- after reading from a filter
- FilterReadPost = "FilterReadPost",
- -- before reading from a filter
- FilterReadPre = "FilterReadPre",
- -- after writing to a filter
- FilterWritePost = "FilterWritePost",
- -- before writing to a filter
- FilterWritePre = "FilterWritePre",
- -- got the focus
- FocusGained = "FocusGained",
- -- lost the focus to another app
- FocusLost = "FocusLost",
- -- if calling a function which doesn't exist
- FuncUndefined = "FuncUndefined",
- -- after starting the GUI
- GUIEnter = "GUIEnter",
- -- after starting the GUI failed
- GUIFailed = "GUIFailed",
- -- when changing Insert/Replace mode
- InsertChange = "InsertChange",
- -- before inserting a char
- InsertCharPre = "InsertCharPre",
- -- when entering Insert mode
- InsertEnter = "InsertEnter",
- -- just after leaving Insert mode
- InsertLeave = "InsertLeave",
- -- just before leaving Insert mode
- InsertLeavePre = "InsertLeavePre",
- -- just before popup menu is displayed
- MenuPopup = "MenuPopup",
- -- after changing the mode
- ModeChanged = "ModeChanged",
- -- after setting any option
- OptionSet = "OptionSet",
- -- after :make, :grep etc.
- QuickFixCmdPost = "QuickFixCmdPost",
- -- before :make, :grep etc.
- QuickFixCmdPre = "QuickFixCmdPre",
- -- before :quit
- QuitPre = "QuitPre",
- -- upon string reception from a remote vim
- RemoteReply = "RemoteReply",
- -- when the search wraps around the document
- SearchWrapped = "SearchWrapped",
- -- after loading a session file
- SessionLoadPost = "SessionLoadPost",
- -- after ":!cmd"
- ShellCmdPost = "ShellCmdPost",
- -- after ":1,2!cmd", ":w !cmd", ":r !cmd".
- ShellFilterPost = "ShellFilterPost",
- -- after nvim process received a signal
- Signal = "Signal",
- -- sourcing a Vim script using command
- SourceCmd = "SourceCmd",
- -- after sourcing a Vim script
- SourcePost = "SourcePost",
- -- before sourcing a Vim script
- SourcePre = "SourcePre",
- -- spell file missing
- SpellFileMissing = "SpellFileMissing",
- -- after reading from stdin
- StdinReadPost = "StdinReadPost",
- -- before reading from stdin
- StdinReadPre = "StdinReadPre",
- -- found existing swap file
- SwapExists = "SwapExists",
- -- syntax selected
- Syntax = "Syntax",
- -- a tab has closed
- TabClosed = "TabClosed",
- -- after entering a tab page
- TabEnter = "TabEnter",
- -- before leaving a tab page
- TabLeave = "TabLeave",
- -- when creating a new tab
- TabNew = "TabNew",
- -- after entering a new tab
- TabNewEntered = "TabNewEntered",
- -- after changing 'term'
- TermChanged = "TermChanged",
- -- after the process exits
- TermClose = "TermClose",
- -- after entering Terminal mode
- TermEnter = "TermEnter",
- -- after leaving Terminal mode
- TermLeave = "TermLeave",
- -- after opening a terminal buffer
- TermOpen = "TermOpen",
- -- after setting "v:termresponse"
- TermResponse = "TermResponse",
- -- text was modified
- TextChanged = "TextChanged",
- -- text was modified in Insert mode(no popup)
- TextChangedI = "TextChangedI",
- -- text was modified in Insert mode(popup)
- TextChangedP = "TextChangedP",
- -- after a yank or delete was done (y, d, c)
- TextYankPost = "TextYankPost",
- -- after UI attaches
- UIEnter = "UIEnter",
- -- after UI detaches
- UILeave = "UILeave",
- -- user defined autocommand
- User = "User",
- -- whenthe user presses the same key 42 times
- UserGettingBored = "UserGettingBored",
- -- after starting Vim
- VimEnter = "VimEnter",
- -- before exiting Vim
- VimLeave = "VimLeave",
- -- before exiting Vim and writing ShaDa file
- VimLeavePre = "VimLeavePre",
- -- after Vim window was resized
- VimResized = "VimResized",
- -- after Nvim is resumed
- VimResume = "VimResume",
- -- before Nvim is suspended
- VimSuspend = "VimSuspend",
- -- after closing a window
- WinClosed = "WinClosed",
- -- after entering a window
- WinEnter = "WinEnter",
- -- before leaving a window
- WinLeave = "WinLeave",
- -- when entering a new window
- WinNew = "WinNew",
- -- after scrolling a window
- WinScrolled = "WinScrolled",
- -- alias for `BufAdd`
- BufCreate = "BufAdd",
- -- alias for `BufReadPost`
- BufRead = "BufReadPost",
- -- alias for `BufWritePre`
- BufWrite = "BufWritePre",
- -- alias for `EncodingChanged`
- FileEncoding = "EncodingChanged",
- },
- buf = {
- storage = buf_storage.create("nui.utils.autocmd", { _next_handler_id = 1 }),
- },
- }
- ---@param callback fun(event: table): nil
- ---@param bufnr integer
- local function to_stored_handler(callback, bufnr)
- local handler_id = autocmd.buf.storage[bufnr]._next_handler_id
- autocmd.buf.storage[bufnr]._next_handler_id = handler_id + 1
- autocmd.buf.storage[bufnr][handler_id] = callback
- local command = string.format(":lua require('nui.utils.autocmd').execute_stored_handler(%s, %s)", bufnr, handler_id)
- return command
- end
- ---@param bufnr integer
- ---@param handler_id number
- function autocmd.execute_stored_handler(bufnr, handler_id)
- local handler = autocmd.buf.storage[bufnr][handler_id]
- if is_type("function", handler) then
- handler()
- end
- end
- ---@param name string
- ---@param opts { clear?: boolean }
- function autocmd.create_group(name, opts)
- if feature.lua_autocmd then
- return vim.api.nvim_create_augroup(name, opts)
- end
- vim.cmd(string.format(
- [[
- augroup %s
- %s
- augroup end
- ]],
- name,
- opts.clear and "autocmd!" or ""
- ))
- end
- ---@param name string
- function autocmd.delete_group(name)
- if feature.lua_autocmd then
- return vim.api.nvim_del_augroup_by_name(name)
- end
- vim.cmd(string.format(
- [[
- autocmd! %s
- augroup! %s
- ]],
- name,
- name
- ))
- end
- ---@param event string|string[]
- ---@param opts table
- ---@param bufnr? integer # to store callback if lua autocmd is not available
- function autocmd.create(event, opts, bufnr)
- if feature.lua_autocmd then
- return vim.api.nvim_create_autocmd(event, opts)
- end
- event = type(event) == "table" and table.concat(event, ",") or event --[[@as string]]
- local pattern = is_type("table", opts.pattern) and table.concat(opts.pattern, ",") or opts.pattern
- if opts.buffer then
- pattern = string.format("<buffer=%s>", opts.buffer)
- end
- if opts.callback then
- local buffer = opts.buffer or bufnr
- if not buffer then
- error("[nui.utils.autocmd] missing param: bufnr")
- end
- opts.command = to_stored_handler(opts.callback, buffer)
- end
- vim.cmd(
- string.format(
- "autocmd %s %s %s %s %s %s",
- opts.group or "",
- event,
- pattern,
- opts.once and "++once" or "",
- opts.nested and "++nested" or "",
- opts.command
- )
- )
- end
- ---@param opts table
- function autocmd.delete(opts)
- if feature.lua_autocmd then
- for _, item in ipairs(vim.api.nvim_get_autocmds(opts)) do
- if item.id then
- vim.api.nvim_del_autocmd(item.id)
- end
- end
- return
- end
- local event = is_type("table", opts.event) and table.concat(opts.event, ",") or opts.event
- local pattern = is_type("table", opts.pattern) and table.concat(opts.pattern, ",") or opts.pattern
- if opts.buffer then
- pattern = string.format("<buffer=%s>", opts.buffer)
- end
- vim.cmd(string.format("autocmd! %s %s %s", opts.group or "", event or "*", pattern or ""))
- end
- ---@param event string|string[]
- ---@param opts table
- function autocmd.exec(event, opts)
- local events = type(event) == "table" and event or { event } --[=[@as string[]]=]
- if feature.lua_autocmd then
- vim.api.nvim_exec_autocmds(events, {
- group = opts.group,
- pattern = opts.pattern,
- buffer = opts.buffer,
- modeline = opts.modeline,
- data = opts.data,
- })
- return
- end
- for _, event_name in ipairs(events) do
- local command = string.format(
- [[doautocmd %s %s %s %s]],
- opts.modeline == false and "<nomodeline>" or "",
- opts.group or "",
- event_name,
- opts.pattern or ""
- )
- if opts.buffer then
- vim.api.nvim_buf_call(opts.buffer, function()
- vim.cmd(command)
- end)
- else
- vim.cmd(command)
- end
- end
- end
- -- @deprecated
- ---@deprecated
- ---@param event string | string[]
- ---@param pattern string | string[]
- ---@param cmd string
- ---@param options nil | table<"'once'" | "'nested'", boolean>
- function autocmd.define(event, pattern, cmd, options)
- local opts = options or {}
- opts.pattern = pattern
- opts.command = cmd
- autocmd.create(event, opts)
- end
- -- @deprecated
- ---@deprecated
- ---@param group_name string
- ---@param auto_clear boolean
- ---@param definitions table<"'event'" | "'pattern'" | "'cmd'" | "'options'", any>
- function autocmd.define_grouped(group_name, auto_clear, definitions)
- if not is_type("boolean", auto_clear) then
- error("invalid param type: auto_clear, expected boolean")
- end
- autocmd.create_group(group_name, { clear = auto_clear })
- for _, definition in ipairs(definitions) do
- autocmd.define(definition.event, definition.pattern, definition.cmd, definition.options)
- end
- end
- -- @deprecated
- ---@deprecated
- ---@param group_name nil | string
- ---@param event nil | string | string[]
- ---@param pattern nil | string | string[]
- function autocmd.remove(group_name, event, pattern)
- autocmd.delete({
- event = event,
- group = group_name,
- pattern = pattern,
- })
- end
- ---@param bufnr number
- ---@param event string | string[]
- ---@param handler string | function
- ---@param options nil | table<"'once'" | "'nested'", boolean>
- function autocmd.buf.define(bufnr, event, handler, options)
- local opts = options or {}
- opts.buffer = bufnr
- if is_type("function", handler) then
- opts.callback = handler
- else
- opts.command = handler
- end
- autocmd.create(event, opts, bufnr)
- end
- ---@param bufnr number
- ---@param group_name nil | string
- ---@param event nil | string | string[]
- function autocmd.buf.remove(bufnr, group_name, event)
- autocmd.delete({
- buffer = bufnr,
- event = event,
- group = group_name,
- })
- end
- return autocmd
|