aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/_core
Commit message (Collapse)AuthorAge
* fix(ui2): use global value of 'fillchars' #42397Evgeni Chasnovski4 days
| | | | | | | | Problem: Custom ui2 window tracks 'fillchars' option to adjust to the change of `msgsep` flag. However, 'fillchars' is `:h global-local` window option. If it is set locally to the window, ui2 reacts to its `msgsep` value and keeps using it afterwards even in other windows. Solution: Use and react to only global value of 'fillchars'.
* feat(inspector): support ranges in vim.inspect_posLewis Russell4 days
| | | | | | | | | | | | | | | | Problem: Highlight inspection is limited to a single position, and its result types do not document the fields shared by different highlight sources. Solution: Accept end_row/end_col in vim.inspect_pos to inspect a range. Keep range ends exclusive and retain the existing single-position behavior. Support Ex line ranges in :Inspect, including Visual selections. Document named result types, expose shared highlight fields, and keep the existing extmark details and buffer field for compatibility. AI-assisted
* feat(multicursor): ]C [C use previous cursors if mc inactive #42267IOCRYPOSTO7 days
| | | | | | | | | | | | Problem: After clearing cursors, "]C" "[C" do nothing, although the previous cursor positions ("gQ") may still be useful as marks. Solution: If multicursor is not active, "]C" "[C" iterate the "nvim.multicursor.last" extmarks. They also work as an operator motion ("d]C"), since there is no cascade. AI-assisted
* feat(api): nvim_chan_set()Justin M. Keyes11 days
| | | | | | | | | | | | | | | | | | | Problem: Only the stdio channel can "own" a server (self-exit on close). After :restart the TUI reconnects over a socket, so the restarted server does not have "self-exit" behavior when the channel closes (e.g. by UI disconnect, host-terminal close, etc.), which leaves a dangling server. Solution: - Introduce `nvim_chan_set`. (`nvim_set_client_info` doesn't fit: exposing it to Lua would require a `channel` param, which is not backwards-compatible, plus it's awkward because it doesn't merge info.) - Broadcast per-channel properties in the "restart" UI event as an opaque dict (a potentially useful pattern for other UI-events in the future). - UIs are expected to restore the channel properties on restart. - `nvim_get_chan_info()` reports "detach". - Remove `nvim__chan_set_detach()`.
* fix(lua): vim._with({ buf, win }) assertion failure #42244Justin M. Keyes2026-10-05
| | | | | | | | | Problem: `vim._with({ buf = 0, win = 0 }, f)` fails an assert in ctx_switch(). vim._with() allows `buf` with `win` when `win` shows `buf`, but nlua_with() passes both, and ctx_switch() takes only one target. Solution: Ignore `buf` if `win` is given; the window implies its buffer.
* fix(search): correct patlen calculation for semicolon search (#42150)Qiming zhao2026-09-30
| | | | | | | | | | | | | | | | | Problem: When repeating search using a semicolon (e.g. `/pat1/;/pat2`), `pat` advances past both the semicolon and the delimiter ('/' or '?'), consuming 2 characters, but `patlen` was only decremented by 1. Consequently, `patlen` in the subsequent search is 1 byte too long and includes the trailing NUL byte, corrupting `msgbuf` and causing ui2's search_count handler to fail with 'attempt to concatenate a nil value'. Solution: Decrement `patlen` by 2 when skipping ';' and delimiter. Also ensure ui2 safely guards search_count messages when extracting the search stat. Fixes #41929 AI-assisted
* ci(lua): enable annotation and style checksLewis Russell2026-09-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: - annotation-usage-error and code-style-check are disabled. - vim.inspect relies on a dummy self-assignment for docgen, and its help omits parameter and option details. - LuaLS fallback types obscure iterator inference. - Docgen hardcodes public function names and appends separately sorted files, leaving shared helpers under the inspector heading. Solution: - Enable annotation-usage-error and code-style-check, and fix misplaced annotations. - Document vim.inspect's callable module directly, removing the dummy assignment. Describe its parameters, option defaults and process callback. - Remove LuaLS iterator fallbacks, correct iterator signatures and check values that the improved inference identifies as optional. - Parse callable modules, require bindings and parent module references. Derive public names and inherited function docs from these links, including missing help for vim.async.semaphore() and vim.version(). - Export vim.lsp.tagfunc directly with lazy loading and document its implementation instead of maintaining a wrapper. - Group files in section_order, replacing append_only and merge_files. Merge declarations before sorting each section, placing shared helpers in the main vim section and keeping vim.inspect in alphabetical order. - Add basic parser coverage for callable modules and module links. AI-assisted
* refactor(multicursor)!: drop nvim_mcursor #42156Justin M. Keyes2026-09-30
| | | | | | | | | | | | | | Problem: `nvim_mcursor` is not fully baked, and not strongly motivated, currently. The main programmatic interface for cursors is the "nvim.multicursor" extmarks namespace. Solution: Drop `nvim_mcursor`. Add an internal hook so that multicursor can react when extmarks are added to the "nvim.multicursor" namespace. TODO: If extmarks/namespaces are clumsy to work with, we should _fix that_ rather than adding wrappers.
* Merge pull request #42134 from lewis6991/emmyluaLewis Russell2026-09-30
|\ | | | | fix(lua): enable param-type-mismatch diagnostic
| * fix(lua): enable param-type-mismatch diagnosticLewis Russell2026-09-28
| | | | | | | | | | | | | | | | | | Problem: Argument type mismatches are excluded from EmmyLua checks. Solution: Correct runtime annotations and calls, document local checker workarounds, and enable the diagnostic. AI-assisted
| * fix(api): correct Lua command and completion typesLewis Russell2026-09-28
| | | | | | | | | | | | | | | | | | | | | | Problem: Command inputs and parsed modifiers have different optional fields, and completion window IDs are annotated as floating-point values. Solution: Separate modifier input and return types, correct integer IDs, and update the metadata generators and their output. AI-assisted
* | feat(multicursor): zq operator; cursor-local marks #42148Justin M. Keyes2026-09-29
|/ | | | | | | | | | | | | | | | | | Problem: - `[count]Q` and `{Visual}Q` are implemented as ad hoc utils, because `Q` is not an "operator". - `Q` always "toggles", it is not "idempotent". - Various *cursor-relative* marks (`'.`, `'[`) are not saved/restored per-cursor, so they don't work during cascade. - Insert cascade clobbers the primary's `'^` and changelist. Solution: - Introduce the `zq{motion}` operator, which places cursors at every reachable `{motion}`. - `{Visual}Q` is now an alias to `{Visual}zqj`. - Introduce `1Q` and `2Q` for idempotent cursor placement. - Drop `[count]Q`, it's redundant with `zqgn`. - Classify cursor-relative marks as `type=motion` instead of `type=jump`. Save/restore per-cursor during cascade.
* fix(lua): enable unnecessary-assert diagnosticLewis Russell2026-09-28
| | | | AI-assisted
* fix(lua): enable assignment type checking in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | Enable EmmyLua's assign-type-mismatch diagnostic after correcting the runtime annotations and assignments it flags. Correct option, tuple, and return types, and use separate locals when a value changes representation. Add guards and narrow casts where needed so the runtime passes the stricter check. Regenerate the affected docs. AI-assisted
* fix(lua): enable nil-safety diagnostics in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | | Enable EmmyLua's need-check-nil diagnostic and resolve nullable values through more precise types, explicit invariants, and guards for missing runtime state. Keep analyzer-specific workarounds local and update the affected API documentation. Exclude the bundled re.lua from analysis so its nil-check warnings do not fail CI. AI-assisted
* fix(gen): ignore return casts in generated documentationLewis Russell2026-09-25
| | | | | | | | Return-cast annotations refine types but do not add return values. Recognize them before @return and exclude them from rendered docs. Apply narrowing to vim.isnil() without changing its runtime behavior. AI-assisted
* feat(multicursor): gQ restores primary-cursor position #42071Justin M. Keyes2026-09-24
| | | | | | | | | | | | | | | | | | | | | Problem: Unlike "gv", "gQ" does not restore the primary-cursor position. This is inconvenient for workflows where you temporarily clear the cursors, navigate somewhere, then want to return to the multicursor session. Solution: Store the primary-cursor position at extmark-id 1 of the `'nvim.multicursor.last'` namespace. Note: users that *don't* want to restore the primary-cursor position can delete extmark-id 1 from the `'nvim.multicursor.last'` namespace just before `gQ`. (Intentionally undocumented because this interface is not final, and should not block Nvim 0.13 release.) vim.keymap.set('n', 'gQ', function() local ns = vim.api.nvim_create_namespace('nvim.multicursor.last') pcall(vim.api.nvim_buf_del_extmark, 0, ns, 1) return 'gQ' end, { expr = true })
* fix(multicursor): skip gQ during an active session #42068Justin M. Keyes2026-09-24
| | | | | | | Problem: gQ is nonsense during an active multicursor session. Solution: Make it a no-op.
* fix(multicursor): revert "]C"/"[C" cursor-plopping behavior #42034Justin M. Keyes2026-09-22
| | | | | | | | | | | | | Problem: Jumping to a cursor adds one at the old position, so navigation has a side-effect. "]CQ" no longer deletes a cursor, and returning with "[C" after wandering off adds a cursor wherever you were. This is useful in some cases, but as a default it is surprising. The default behavior should be simple and composable. Solution: Revert the "]C"/"[C" cursor-plopping behavior. Document a mapping for the "rotate" behavior.
* fix(multicursor): may exceed kitty cursors param limit #42029Justin M. Keyes2026-09-21
| | | | | | | | Problem: If there are >85 cursors on-screen, the terminal barfs the termcodes to the screen. Solution: Emit the coords in chunks. Only "0;4" clears, so the groups accumulate.
* fix(help): follow symlink files in :helptags #42008Shougo2026-09-20
|
* feat(multicursor): color extra Kitty cursors #41935phanium2026-09-18
| | | | | | | | | | | Problem: Extra cursors use shape 29 (follow primary), so they render identically to the primary instead of using hl-MCursor colors. Solution: Send MCursor fg/bg as sRGB via shapes 30/40 before placing cursors. Terminals without 30/40 support ignore the color sequences. AI-assisted
* fix(lua): add missing param annotations (#41911)Lewis Russell2026-09-15
|
* feat(multicursor): {Visual}[count]Q matches in Visual selection #41863Justin M. Keyes2026-09-11
| | | | | | | | | | | | | | Problem: `[count]Q` cannot be limited to a Visual selection. Solution: `{Visual}[count]Q` places cursors on matches within a Visual selection (linewise). TODO: This works linewise, even if the visual selection is charwise/block. If we really want to limit by charwise/block selection, then we should add that feature to `seachpos()` or similar. Every caller of `seachpos()` should not have to cobble together bespoke support thereof.
* fix(multicursor): {Visual}Q should not move primary cursor #41862Justin M. Keyes2026-09-11
| | | | | | | | | Problem: `{Visual}Q` moves the primary to the top of the selection, for no particular reason. And it's inconsistent with `[count]Q`. Solution: Keep the primary on the line where the selection ended, aligned to the shared screen column so it still coincides with that line's cursor.
* fix(ui2): dialog messages offset by the pager line count #41839Justin M. Keyes2026-09-11
| | | | | | | | | | | | | | | | Problem: expand_msg() derives its start row from the pager buffer even when the target is the cmd or dialog buffer, so the copied lines are appended instead of replacing, and the copied extmarks are placed at pager rows in a smaller buffer: "Invalid 'end_col': out of range", thrown inside a UI event handler. Solution: Offset only when appending to a visible pager, and read the line count after msg_clear(), whose autocmds may write to the pager. Copy marks with `strict = false`, since the rows and columns are recomputed for a different buffer and should clamp rather than raise. AI-assisted
* refactor(help): reuse help.lua to generate build tagsLewis Russell2026-09-10
| | | | | | | | | | Make gen_helptags.lua call help.lua instead of keeping its own tag parser. Builds and :helptags now use the same code. Allow the shared code to run without Neovim, and fail the build when tag generation reports an error. AI-assisted
* perf(help): generate helptags with LPegLewis Russell2026-09-10
| | | | | | | | | | | | | | | | Problem: Generating helptags builds and queries a full vimdoc syntax tree. This is much slower than the previous scanner and also happens before discovering that the tags file cannot be written. Solution: Extract tags with an LPeg grammar, reading each file once and skipping example blocks and ordinary text. Open the output first so unwritable directories can return immediately. This restores legacy handling of tags inside inline code spans. On an arm64 Mac, the 5.36 MB runtime corpus takes 24 ms instead of 604 ms, with identical generated tags. AI-assisted
* build: enable more EmmyLua checksLewis Russell2026-09-09
| | | | | | | | | | Enable checks for unused code, deprecated calls, return types, and annotations. Fix the warnings and replace the deprecated highlight function. Keep exceptions where old APIs are still needed or the checker gets it wrong. AI-assisted
* feat(watch): add on_error callbackLewis Russell2026-09-09
| | | | | | | | | | | | | | Problem: Watcher failures are reported inconsistently, and callers cannot detect when a watcher is no longer usable. Solution: Route startup and event failures and unexpected inotifywait exits through an optional on_error callback. Log to nvim-watch.log by default. Ignore disappearing child directories and exits caused by cancellation. Let LSP log failures and notify once per message, using INFO for missing roots and ERROR otherwise, without interrupting registration. AI-assisted
* build: enable more EmmyLua checksLewis Russell2026-09-08
| | | | | | | | | | | | | | | | - call-non-callable - missing-fields - redefined-label - redefined-local - undefined-field - unreachable-code Promote redefined-local and unreachable-code to warnings. Fix DOS line-ending handling for multiline semantic tokens, and support intersection types in the help parser. AI-assisted
* build: replace LuaLS with EmmyLuaLewis Russell2026-09-07
| | | | | | | | | | | | | | | Problem: LuaLS struggles with the generics used in Nvim's runtime, requiring broad diagnostic suppressions. Indexing is also slow. Solution: Use EmmyLua for type checks in the build and CI. It offers more sophisticated type checking, substantially better support for generics, and much better flow analysis. Correct the affected annotations. Use `@internal`, supported directly by EmmyLua, instead of `@nodoc` for shared internal declarations, and support it in the help parser. AI-assisted
* fix(help): resolve generic and nullable type referencesLewis Russell2026-09-07
| | | | | | | | | | Problem: K on generic and nullable type annotations can jump to the wrong help tag. Generated See references repeat the type names. Solution: Strip generic arguments and nullable suffixes when resolving help tags. Remove the redundant generated See references. AI-assisted
* fix(ui2): mouse movement dismisses expanded messages #41732Volodymyr Chernetskyi2026-09-06
| | | | | | | | | | | | | Problem: cmd_on_key() tests the key it was handed against the literal string '<MouseMove>', but at that point "typed" still holds raw key bytes. Thus the comparison never holds and the branch its own comment describes is dead. Moving the mouse over an expanded cmdline collapses it. Solution: Translate the key once, up front, so every comparison in the function sees the same form. AI-assisted
* feat(ui2): highlight the [+x] spill indicator with MoreMsg #41679Volodymyr Chernetskyi2026-09-04
| | | | | | | | | | | | | Problem: The "spill" indicator that ui2 appends when messages overflow the available height is drawn with whatever highlight the message tail happens to have, so it is indistinguishable from the message text. Solution: Give the [+x] chunks an explicit `MoreMsg` highlight, and only fall back to the message tail highlight for chunks that don't carry one of their own. AI-assisted
* feat(ui2): scroll the dialog window with the mouse wheel #41682Volodymyr Chernetskyi2026-09-04
| | | | | | | | | | | | Problem: The ui2 dialog implements paging for the arrow keys, Home/End and the page keys, but not for the mouse wheel. When `mouse` contains `"c"`, turning the wheel does nothing at all. Solution: Handle <ScrollWheelUp>/<ScrollWheelDown>, scrolling by the `mousescroll` `"ver"` amount. AI-assisted
* feat(multicursor): "]C"/"[C" leave a cursor at old position #41681Justin M. Keyes2026-09-04
| | | | | | | | | Problem: `]C` jumps the primary onto another cursor, which dedupes at the next edit. Every `]C` consumes a cursor. Solution: `]C` adds a cursor at the current position before jumping. This effectively "rotates" the primary cursor.
* feat(lua): add vim.asyncLewis Russell2026-09-03
| | | | | | | | | | | | | | | | | | | | Problem: Nvim has many Lua APIs that start callback-driven work: timers, jobs, libuv handles, and other event-loop tasks. Callers that need to sequence or cancel that work have to build their own coroutine wrappers, task bookkeeping, and cleanup rules. This makes async control flow hard to share, test, and document. Solution: Add `vim.async`, a structured-concurrency module vendored from async.nvim. It provides task handles, await/pawait helpers, sleep/timeout helpers, completion-order iteration, and semaphores on top of Nvim's event loop. The API follows the same broad model as Trio: async work has an owner, tasks are awaited explicitly, and cancellation is cooperative. Include generated vimdoc with an introductory overview and examples, a news entry, and functional tests for the new module. AI-assisted
* fix(statusline): default 'statusline' improvements #41597Sébastien Hoffmann2026-09-03
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: there should be exactly one cell of padding between sections, and exactly one cell of minimum padding between the left and the right. - Spaces between sections waste space when a section is empty. According to a comment in #33036, this was the reason to avoid `%k` and implement the keymap section with a vim expression, but other sections still have this problem. - The diagnostics section wastes space because it is not entirely empty when there are diagnostics in another buffer. - The terminal exit code section can touch the right side, e.g. the ruler, even though it belongs to the left side. Solution: - Use auto-hiding item groups (`%(` without width fields) to get rid of unneeded spaces when a section shows no information. This simplifies the 'showcmd' and 'keymap' sections in particular. - As a slight simplification, `term_exitcode` is moved into the flags section since it is formatted with square brackets like a flag. - Count the diagnostics for the current buffer specifically. - Ensure at least one cell of padding between the left and the right side by adding a space next to the separator `%=`. Problem: some sections are implemented with `%{%`, even though reevaluation of the expression result is not needed. This leads to otherwise needless %-escaping in `progress_status`. Solution: use `%{` instead. Problem: `%{` and `%{%` (without items) replace spaces with fillchars. This looks out-of-place inside the terminal exit code section, and in contrast to all other sections, the 'busy' section is surrounded by fillchars, which looks inconsistent, and with some terminal-font combinations, ◐ overlaps the fillchar, e.g. Alacritty & JetBrains Mono. Solution: use non-breaking spaces U+202F to avoid fillchar substitution. Problem: sections that appear/disappear frequently can make otherwise more stable sections jump around a lot. Solution: sort the sections on the right roughly by volatility: 'showcmd' in first place, 'keymap' next to the ruler.
* vim-patch:9.2.1031: 'wildmode' list:full does not show 'wildmenu'zeertzjq2026-09-02
| | | | | | | | | | | | | | | | | Problem: With 'wildmode' set to list:full the matches are listed but the wildmenu is not shown, although it is "full" that starts wildmenu mode (zeertzjq). Solution: List the matches and show the menu, as the two behaviors in the same phase ask for. The menu is left to the phases that ask for it, so that "list" on its own still only lists (Hirohito Higashi). fixes: vim/vim#21196 closes: vim/vim#21205 https://github.com/vim/vim/commit/fa1ddffcce24f22d61608c0086e55adadd1d2c11 Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
* feat(multicursor): MC HAMMER #41587Justin M. Keyes2026-09-01
| | | | | | | | | | | | | | | | | | | | | Other (squashed) commits: fix(tui): emit ui_send output atomically with the frame Problem: tui_ui_send() writes directly to the TTY, bypassing the output buffer. Sequences sent via nvim_ui_send() (e.g. kitty multiple-cursors, or visual-dot-repeat) always arrive in a separate TTY write from the frame they were computed for. This manifests as "tearing", or e.g. in the case of multicursor the terminal renders text with stale cursor overlays. Solution: - tui_ui_send(): while a frame is being assembled (pending invalid regions or buffered output), buffer instead of writing directly. - Out-of-frame sends (tty queries, clear-on-disable) still write immediately. - mcursor.lua: emit the terminal-cursor update at the end of the redraw cycle (`on_end`, when screen positions are final) instead of vim.schedule().
* fix(ui2): respect options set during startup after enabling ui2 #41591Evgeni Chasnovski2026-09-01
| | | | | | | Problem: options related to ui2 (like `fillchars` with `msgsep`) do not take effect if set during startup after enabling ui2. Solution: explicitly check just after startup if relevant options were changed during startup.
* 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(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(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(ui2): cmdwin is not special #41508Justin M. Keyes2026-08-26
| | | | |