aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
Commit message (Collapse)AuthorAge
...
* fix(lsp): separate adjacent nested folding ranges #41428wrvsrx2026-08-31
| | | | | | | | | Problem: Folding range markers are overwritten while ranges are evaluated. A range ending on a row can hide another range starting there, and multiple nested ranges ending together emit only the innermost ending level. Solution: Track starts and the number of ends per row before emitting markers. Prefer starts on shared boundary rows and use the outermost level when nested ranges end together. AI-assisted
* fix(cmdwin): handle UTF-8 characters containing 0x80 #41566Aryan Pandey2026-08-31
| | | | | | | | Problem: Confirming cmdwin with a UTF-8 character containing 0x80 does not complete the command. Solution: Escape K_SPECIAL bytes while feeding the cmdwin input after confirmation.
* fix(ui2): cursor flicker in cmdline with matchit #41245not_compiled2026-08-30
| | | | | | | | | | | Problem: The cmdline_hide callback causes an unnecessary cursor move to the cmdline, before the normal redraw updates the cursor back to the current window. This appears as "flicker" when using plugins such as matchit (legacy ":" mappings instead of "<cmd>" mappings). Solution: Skip the immediate redraw for cmdline_hide events. The normal redraw still updates the cursor after the cmdline window is hidden.
* fix(snippet): cancel session on ESC in insert-mode #41555Nathan Zeng2026-08-30
| | | | | | | | Problem: If a snippet does not have a placeholder, we use insert mode instead of select mode. From here <Esc> leaves the session and highlight active. Solution: Cancel the session on <Esc>.
* fix(ui2): don't draw MsgSeparator if cmdheight=0 #41531not_compiled2026-08-29
| | | | | | | | | Problem: When 'cmdheight' is 0, the MsgSeparator can obscure the statusline when a message is displayed, making its contents disappear until the next redraw. Solution: Skip the separator when 'cmdheight=0' available.
* fix(lsp): blank line before Content-Length breaks header parsing #41524Yanze Li2026-08-29
| | | | | | | | | | | | | | Problem: A blank line before the Content-Length header makes header parsing fail with "Content-Length not found in header". An LF in the 'name' state falls through to the 'invalid' state, which only return to 'name' at the *next* LF. That LF terminates the next line, so the line with Content-Length is swallowed. The same issue happens when a junk line is a partial match of the header name (e.g. "Cont\nContent-Length: ..."). Solution: When seeing an LF in the 'name' state, reset the cursor and stay in 'name' rather than entering 'invalid'.
* vim-patch:9.2.1018: filetype: radvd config files are not recognized (#41534)zeertzjq2026-08-29
| | | | | | | | | | | | | | Problem: filetype: radvd config files are not recognized Solution: Detect radvd.conf as radvd filetype, include syntax and filetype plugins, add syntax tests, update the menus (mdspan). Reference: https://linux.die.net/man/5/radvd.conf closes: vim/vim#21159 https://github.com/vim/vim/commit/d4c8c66bed0615058073985627a15e9c1c01af06 Co-authored-by: mdspan <mdspan.github@gmail.com>
* fix(cmdwin): allow a user to switch to other buffers #41199Rob Pilling2026-08-28
|
* fix(lua): blast radius of broken `_G.debug` #41507Justin M. Keyes2026-08-27
| | | | | | | | | | | | | | | | | | | | | | | | Problem: `nlua_pcall()` references `_G.debug.traceback`. If user code deletes it or breaks it some other way, various Lua features are broken. _G.debug = nil vim.schedule(function() end) vim.wait(100) E5113: Lua chunk: attempt to index a nil value stack traceback: [C]: in function 'loop_poll' [string "vim/_core/editor"]:176: in function 'wait' crash.lua:3: in main chunk PANIC: unprotected error in call to Lua API (attempt to index a nil value) Solution: Check `_G.debug.traceback` before using it as errfunc. If it's broken, omit the traceback and say so in the error message. Note: We could cache `_G.debug` in LUA_REGISTRYINDEX on startup, but that would prevent plugins from providing custom functionality there (and we happen to do so in `tui_spec.lua` for example).
* fix(health): powershell "echo" fails without an arg #41477Rafli Surya Wijaya2026-08-26
|
* fix(ui2): cmdwin is not special #41508Justin M. Keyes2026-08-26
| | | | | | | | | | | | | | | | | | | | Problem: Unreliable ui2 test: FAILED …/ui/messages2_spec.lua @ 277: messages2 multiline messages and pager …/ui/messages2_spec.lua:277: Row 1 did not match. Expected: ... |*{1::}echo "foo" | echo "bar\nbaz\n"->repeat(&lines) | |*{1::}messages | |*{1::}^ | ... Actual: ... |*{9:vim.schedule callback: ...ork/neovim/neovim/runt [+7]}| Solution: ui2 is doing contortions to handle the old cmdwin behavior; stop doing that, it's no longer necessary since b2bf7bcfb151.
* vim-patch:9.2.1004: a completion function cannot tell why it was called (#41500)zeertzjq2026-08-26
| | | | | | | | | | | | | | | Problem: A function used through 'omnifunc' or 'complete' is called the same way whether 'autocomplete' started the completion or a key asked for one, so it cannot answer differently. Solution: Report which of the two it is in complete_info() as "auto". It is returned only when asked for in {what}, so what complete_info() says by itself does not change (Hirohito Higashi). closes: vim/vim#21143 https://github.com/vim/vim/commit/1f56c351dedad288f79c89b6b6f64be762ec3b9b Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
* vim-patch:9.2.1002: filetype: bazelrc files are not recognized (#41496)zeertzjq2026-08-26
| | | | | | | | | | | | Problem: filetype: bazelrc files are not recognized Solution: Detect *.bazelrc and tools/bazel.rc files as bazelrc filetype, include syntax und filetype plugins, update the menus (Barrett Ruth). closes: vim/vim#21146 https://github.com/vim/vim/commit/1afe7ad1bb72f36a80f8e625b91d0e7506ce8985 Co-authored-by: Barrett Ruth <br@barrettruth.com>
* revert: "fix(lsp): do not expand $VAR in tagfunc filenames" #41489Justin M. Keyes2026-08-25
| | | revert c5cb0350a6dc578e6ca73eefdd58159e1e039cbf
* fix(help): :helptags on CRLF helpfilesJustin M. Keyes2026-08-25
| | | | | | | | | | | | | | | | | | | Problem: The vimdoc parser does not treat "\r" as whitespace, so in a CRLF helpfile the codeblock rule fails and "*" pairs inside examples become tags. On Windows this generates duplicate "." and "/" tags: D:/a/neovim/neovim/build/bin/nvim.exe -u NONE -i NONE -e --headless -c "helptags ++t doc" -c "exe 'cquit' !empty(v:errmsg)"" Error in command line: E154: Duplicate tag "." in gui.txt and repeat.txt E154: Duplicate tag "/" in pattern.txt and usr_08.txt E154: Duplicate tag "/" in usr_08.txt and pattern.txt Note: The old C parser was unaffected because it read helpfiles in text mode (`os_fopen(…, "r")`). Solution: Strip "\r" before parsing.
* fix(help): :helptags regressionsJustin M. Keyes2026-08-25
| | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Parent commit regressed some behavior of the old C helptags-gen impl: - helpfiles in sub-directories are named by basename, so :help fails - "help-tags" always names "tags", never "tags-nl" - E150 E151 E152 E153 are never reported - existing tags file is not overwritten if no tags were found - a duplicate tag aborts the run, skipping the remaining directories - `*.TXT` and `*.FRX` (uppercase) are not recognized as helpfiles - tree-sitter-vimdoc accepts tags that the C parser rejected: `*a|b*` (breaks |links|) and unterminated `*tag` - PUC Lua "<" compares with (localized) `strcoll()`, so the tags file is not sorted by byte value (E432) - requiring `vim.treesitter` at load time breaks :help itself, not just :helptags, where the module is unavailable - `vim.pack` runs :helptags for plugins that have no "doc/" directory, so every install/update emits E150 Solution: - Fail the build if generating helptags reports any `v:errmsg`. - Restore old behavior: tags generated for runtime/doc are now identical to those from the C implementation. Errors are non-fatal messages instead of exceptions, so all directories are still processed. - Load treesitter lazily, report a plain error if parser is missing.
* feat(help): generate :helptags using TreesitterYochem van Rosmalen2026-08-25
| | | | | | | | | | | | | | | | | | | | Problem: Tags are manually parsed in C which is not flexible and prone to errors. Extending the help system to allow for other formats (e.g. Markdown) would require a large rewrite in the C core, while with Treesitter it only needs a query update. Solution: Use the power of treesitter to extract the tags from helpfiles. - build: set `$VIMRUNTIME` when generating helptags, like `cmake/Util.cmake` already does for other generators. - fix(help): only accept tags delimited by whitespace. The old C parser only accepted a `*tag*` preceded by start-of-line or whitespace and followed by whitespace or end-of-line. The vimdoc parser also captures tags followed by other text, e.g. `*$XDG_STATE_HOME*/.../logs` in starting.txt, which caused an E154 duplicate tag error for docs that were previously fine.
* feat(ui2): lift ui2 options into 'messagesopt' (part 1) #41474Justin M. Keyes2026-08-25
| | | | | | | | | | | | | | | | | | | Problem: In order for ui2 to graduate to the main "messages ui" its configuration needs to graduate into actual options. Solution: Migrate some of its config to 'messagesopt': - "maxheight" (note: currently this is an integer treated as a "percentage"; if we want to support a row count we could allow values with units, like `"42%"`) - "pager" - "timeout" Also improves error messages: messagesopt=hit-enter,history:500,bogus E474: Unknown item 'bogus' messagesopt=hit-enter,history:500,progress:x E474: 'progress' must be one of: , c messagesopt=hit-enter,history:abc E474: 'history' requires a number
* fix(ui2): pager_char does not match keycode aliases #41468Justin M. Keyes2026-08-24
| | | | | | | | Problem: `pager_char` compares the `keytrans()` result exactly. E.g. `pager_char = "<cr>"` does not work, it expects `<CR>` (uppercase). Solution: Normalize `pager_char` in enable().
* fix(lsp): advance inline completion range over matching input #41434Étienne Robert2026-08-24
| | | | | | | | | | | | | | | Problem: `Completor:accept()` applies the item against the range the server answered with. Characters typed after the request but before accepting lie inside neither that range nor the replacement, so they are left behind by the insertion: typing `a` after `foob` and accepting `foobar` within the 200 ms debounce yields `foobara`. Solution: Grow the item's range over the characters typed since the request, so that `accept()` replaces them. Only while the candidate still matches, decided by the longest common prefix `show()` already computes, so input that contradicts it is left alone. Snippet items are unaffected, since `accept()` ignores the range for them.
* fix(ui2): ui2 misinterprets getchar() input as pager_char (CR) #41465Justin M. Keyes2026-08-24
| | | | | | | | | | Problem: `vim.on_key()` callbacks are invoked for keys that `getchar()` consumes, which never reach the main loop, and there is no way to tell such a key apart. With ui2 the `on_key` handler activated after interactive cmdline, handles it as `pager_char` (thus enters the ui2 pager). Solution: Skip `vim.on_key()` callbacks during `getchar()`/`getcharstr()`.
* fix(lsp): clamp inline completion range to the line on accept #41435Étienne Robert2026-08-24
| | | | | | | | | | | | | | | | | | Problem: `Completor:accept()` hands the item's range straight to `nvim_buf_set_text()`. That range is resolved when the response arrives, so text deleted before accepting (backspacing within the 200 ms debounce) leaves the range end past what is left of the line, and the accept aborts with `Invalid 'end_col': out of range`. 18d6436 fixed the same staleness in `Completor:show()`, which drops an item once its range *start* falls outside the buffer. That guard does not cover the range end, and `accept()` was never given one, so this is a hole left by that fix rather than a regression of it. Solution: Clamp the end of the range to the end of the line before writing. The start needs no clamp: `show()` dropped the item one event loop tick earlier if it had gone out of range.
* fix(lsp): completion overwrites text before the word boundary #41463glepnir2026-08-24
| | | | | | | | | Problem: One item with an edit range before the word boundary changes the start column for all items. For tsserver `str.`, completing `str.char` can become `strcharAt` and break filtering. Solution: Prepend the missing text and filter on it.
* vim-patch:9.2.1001: complete_info() does not report the item highlight ↵glepnir2026-08-24
| | | | | | | | | | | | groups (#41461) Problem: complete_info() omits "abbr_hlgroup" and "kind_hlgroup". Solution: Keep the highlight group ID with the match instead of the resolved attribute and add both entries to the returned items (glepnir). closes: vim/vim#21105 https://github.com/vim/vim/commit/1c32cede0afdc9351d5887e2f25977d4fb964d9f
* vim-patch:63d08d4: runtime(doc): update :h write-plugin and readdir() examplezeertzjq2026-08-24
| | | | | | | | | | | | | | | | | | | | 1) The complete example plugin at :h write-plugin the end of the documentation didn't reflect the snippets provided during the tutorial. In most of the Add() function, interpolated strings are used, but the final result used concatenated strings. 2) The example provided in readdir() to get a list of files ending in ".txt" didn't properly escape the dot in the regular expression: readdir(dirname, {n -> n =~ '.txt$'}) This would match any file ending with "txt" that is at least 4 characters long, instead it should be: readdir(dirname, {n -> n =~ '\.txt$'}) closes: vim/vim#21123 https://github.com/vim/vim/commit/63d08d43862ed195da78cfb1bebe2c0ed02f80b7 Co-authored-by: Josep Puigdemont <josep.puigdemont@gmail.com>
* fix(ui2): dismiss msgs after mapped motions #41450not_compiled2026-08-23
| | | | | | | | | | Problem: Mapped keys can produce on_key callbacks with an empty `typed` value. so mapped motions such as `j -> gj` are not recognized as typed input and do not dismiss messages Solution: Track whether an empty `typed` callback follows typed input, allowing mapped motions to dismiss messages like directly typed motions.
* docs: misc #41452Justin M. Keyes2026-08-23
| | | | | Co-authored-by: darkdi <rantovov5@gmail.com> Co-authored-by: Qiaoxi Guo <28090444+breadtitor@users.noreply.github.com> Co-authored-by: zaveshaa <zaveshaa@gmail.com>
* fix(lsp): do not expand $VAR in tagfunc filenames #41398Shubh2026-08-23
| | | | | | | | Problem: CTRL-] via lsp tagfunc passes URI paths through :tag, which expands \$VAR, so files like people_.\$personId.tsx fail with E429. Solution: fnameescape() the filename in tag items so \$ is treated as literal.
* feat(pos): mutable vim.Pos, vim.Range fields #41318Olivia Kinnear2026-08-23
| | | Allow plugins to set the human-readable fields.
* feat(cmdatom): mappings capture continuationJustin M. Keyes2026-08-22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: A mapping that ends mid-operation (`nnoremap ,D d`) emits a content-free "mapping" atom plus a `pending` field, and the "continuation" motion arrives as a sibling atom. Consumers must stitch the two together (which has broken cases, e.g. Insert-opening mappings (",i") lose their session entirely). - ",i": the session atom is dropped bc the mapping RHS is consumed before the session starts (typebuf_maplen()==0), so atom_is_user_input()=false. - ":normal"-in-opfunc: the opfunc internal "v..y" session (a) became kVatomTyped just because the deferred composite was open, masking the real operator capture via atom_captures, and (b) its nested frames re-derived the outer redo. - "Motion" based on `moved=true`, has false negatives. - `CmdAtom.remap` is unnecessary, and clutters the docs/usage. Solution: - Introduce `frame_id` to identify CmdFrames. - Classify `type=motion` better, via `NV_MOTION` flag on the `nv_cmds` table. - Drop `CmdAtom.pending`, `CmdAtom.remap`. - Defer atom_composite_end() at the clock edge while an operator is pending, Visual is active, or `restart_edit` is set: the composite keeps collecting, so the continuation is captured in the mapping atom. - ",i": Now an open composite counts as user input. - ":normal"-in-opfunc: Now handled correctly. - `remap` is now decided by `composite.payload || 0 subatoms`. atom_payload_mark() records the read the resolution never captures. - `toplevel` is now decided by `CmdFrame.parent == NULL`. before/after: INPUT BEFORE AFTER --------------------------------------------------------------------- ,D w {mapping lhs=,D pending=operator} {operator lhs=,Dw keys=dw} + {operator keys=dw} ysiw" {mapping lhs=ys pending=operator} {operator lhs=ysiw" keys=g@iw"} + {operator lhs=g@iw"} ,v d {mapping pending=visual} {visual lhs=,vd keys=viwd} + {visual lhs=viwd} ,i XY<Esc> {normal keys=i lhs=,iXY<Esc>} {insert keys=1iXY<Esc> text=XY}
* fix(url): escape cmd.exe special chars in vim.ui.open() URL #41394Shubh2026-08-22
| | | | | | | | Problem: On Windows, vim.ui.open() passes URLs to `cmd.exe /c start`. cmd.exe treats `&` as a command separator, so query strings are truncated. Solution: Caret-escape `&|<>^%!` in URIs when the open handler is cmd.exe.
* fix(ui2): offset extmarks copied to pager by srow #41425Sean Dewar2026-08-22
| | | | | | | | Problem: wrong end_row when copying extmarks to the pager buffer when expanding a message. Results in incorrect highlights or errors such as "invalid `end_col` out of range". Solution: don't forget to offset end_row by srow, as is already done for the copied lines and extmark rows.
* fix(lsp): empty filterText/sortText/insertText not treated as unset #41421glepnir2026-08-22
| | | | | | | | | Problem: Empty string is falsy, so the spec's label fallback applies, but there only checks for nil. An empty filterText drops the item, an empty sortText sorts it first, and an empty insertText leaves the word empty. Solution: Treat empty string as unset.
* feat(cmdatom)!: eliminate the need for vim-repeat #41414Justin M. Keyes2026-08-21
| | | | | | | | | | | | | | | | | | | | | | | | | Problem: - `lhs` is not fully realized. E.g. for a "payload" mapping `lhs` omits the `getchar()` payload during a mapping (vim-surround `ds'` reports `lhs="ds"`). This means plugins like vim-repeat are still needed... - The "delta" fields of a CmdAtom are calculated too late. - `<abuf>` and `changed` check whatever (wrong) buffer a command (":bnext") might land in. - CTRL-W_w between two windows on the same buffer reports type="motion". Solution: - `CmdOrigin` samples (buf/win/cursor/changedtick) at each "scope" entry (CmdFrame, composite, Visual session, insert session). - `dd<C-w>l` reports `changed=true` for the buffer it edited, regardless of where the cursor ends up. - New fields: - `pos`: cursor position at command start. - `moved`: indicates whether the cursor moved (in same buffer). - `undoseq`: undo state at settlement. - lhs now includes the payload: "ds)" reports lhs="ds)" instead of "ds". - Easy for users to "replay" any atom. - Rename: type "command" => "normal", "ex" => "excmd"; `arg` => `cmdarg` - Drop `cascade` field (no reason to expose it)
* vim-patch:76f1eed: runtime(doc): clarify how setbufvar() handles window ↵zeertzjq2026-08-21
| | | | | | | | | | options (#41408) related: vim/vim#21089 closes: vim/vim#21104 https://github.com/vim/vim/commit/76f1eed3a5f8fe12a7b01725a99c582a95e69000 Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
* vim-patch:bce3eb1: runtime(doc): clarify the 'findfunc' option (#41389)zeertzjq2026-08-20
| | | | | | | | | | Remove the note about "this function is called only once per :find command invocation". fixes: vim/vim#21062 https://github.com/vim/vim/commit/bce3eb1fae71671b39756a77c9b1db203311ba0c Co-authored-by: Christian Brabandt <cb@256bit.org>
* feat(extmark): virt_lines can highlight until EOL #41289Goldpigg2026-08-18
|
* feat(lsp): fallback to textDocument/formatting from vim.lsp.formatexpr #40079Marcus Caisey2026-08-18
| | | | | | | | | | | | | | | | Problem: With the addition of the `:help al` text object, you can now easily format the whole buffer with `gqal`. However, `vim.lsp.formatexpr` only uses `textDocument/rangeFormatting` which some language servers (like gopls) don't support. Solution: - Fall back to `textDocument/formatting` if the whole buffer is being formatted and the server doesn't support `textDocument/rangeFormatting`. - In theory, these two methods should return the same response if the whole buffer is being formatted, but I preserved the existing behaviour of prioritising `textDocument/rangeFormatting` in case that does not hold (i.e. LS bug). - Also: `vim.lsp.formatexpr` had no tests at all, so actually add tests for it.
* docs: misc, cwd, vimscript.txt #41356Justin M. Keyes2026-08-17
| | | Extract vimscript.txt from repeat.txt
* feat(ui2): drop default enter-pager-via-CR mapping #40993Rob Pilling2026-08-17
|
* feat(vim.fs): slug() supports URI #41241Willaaaaaaa2026-08-16
| | | | | | | | | | Problem: `vim.fs.slug()` does not handle URIs like `term://foo//123:bash`, so callers (e.g. terminal persistence) must strip the scheme before calling `slug()`. Solution: Detect `scheme://` from the raw input before `normalize()` and replace it with a `=uri-<scheme>-` prefix.
* fix(lua): don't limit indexed vim.cmd positional argument count (#41317)zeertzjq2026-08-16
|
* feat(input)!: CmdAtom event #41297Justin M. Keyes2026-08-14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: There is no unified notion of a "user action". Vim processes input by one-char-at-a-time, and mostly throws away any hints it might gather about the user's action, with one exception: it stores the last _edit_ action (the "redo buffer", encoded as unstructured `["x][v][count]body` bytes). Plugins can only observe individual keys (vim.on_key) and high-level effects (TextChanged, CursorMoved). Solution: - Users can subscribe to `CmdAtom` events to handle any user action. - Event is deferred; handlers cannot cancel or interfere with user actions. - Capture `CmdSpec` from the normal/insert/visual subsystems. - typeahead/readahead stay unstructured (`buffheader_T`): they are key streams, not commands. - the redo/record buffers become `StringBuilder`: fewer allocations/copies. - Repurpose the input/redo engine to accept `CmdSpec` objects. "atom": one repeatable unit of user input, as a resolved (post-mapping) keysequence plus structured fields. Only user actions, not `:normal`, API calls, or non-"t" `feedkeys`. BREAKING: dot-repeat of an Insert session, replays the entire session including cursor-moves (:help ins-repeat). BREAKING: dot-repeat of a Visual operation, replays the selection instead of operating on a fixed-size region.
* vim-patch:9.2.0957: filetype: ArgoCD config file is not recognized (#41301)zeertzjq2026-08-14
| | | | | | | | | | | | | Problem: filetype: ArgoCD configuration file is not recognized Solution: Detect */argocd/config as yaml filetype (Fionn Fitzmaurice). Reference: https://argo-cd.readthedocs.io/en/latest/user-guide/commands/argocd_configure/#options-inherited-from-parent-commands closes: vim/vim#21031 https://github.com/vim/vim/commit/7807dd22793da0e826618c0ca9c6210bbc1ea3f5 Co-authored-by: Fionn Fitzmaurice <git@fionn.computer>
* fix(diagnostic): don't accumulate BufRead autocmds for unloaded buffers #40869Nathan B.2026-08-13
| | | | | | | | | | | | | | | Problem: vim.diagnostic.set() defers extmark position computation for an unloaded buffer via a once=true BufRead autocmd, registering a new one on every call without replacing the previous one. Each pending autocmd also retains that call's diagnostics. Solution: Instead of registering an autocmd per set() call, register a single static BufRead autocmd that computes positions from the diagnostic cache for any buffer with cached diagnostics when it is read. This removes the per-call registration entirely (nothing left to accumulate) and means diagnostics cleared while the buffer was unloaded no longer produce stale extmarks.
* Merge #41075 from echasnovski/pack-packspec-part1Justin M. Keyes2026-08-13
|\
| * feat(pack): add support for sourcing manifest scriptsEvgeni Chasnovski2026-07-31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: No way for plugins to define hooks that would be executed during plugin lifecycle. Like after install/update or before update/delete. Solution: Automatically source scripts defined in plugin manifest file (if any) after triggering corresponding `PackChanged{,Pre}` events. During sourcing make some termporary adjustments: - Current directory is set to plugin's root to simplify execution of CLI calls like `make build`. - Plugin's path is ensured to be inside 'runtimepath' to allow using `require('plugin-module')` inside manifest scripts. The reason to execute after triggering event is so that there is a possibility for users to execute code both before the script (exactly on event) and after the script (more-or-less via `vim.schedule` called on the event).
| * feat(pack): introduce plugin manifest supportEvgeni Chasnovski2026-07-31
| | | | |