Commit Graph

8104 Commits

Author SHA1 Message Date
Justin M. Keyes
c7d4892ce6 Merge #39194 from justinmk/luavimfn 2026-04-20 04:23:54 -04:00
Jaehwang Jung
79a7a4abe1 fix(smoothscroll): crash when resizing to textoff with showbreak
vim-patch:9.2.0362: division by zero with smoothscroll and small windows

Problem:  Resizing a smoothscrolled wrapped window to its textoff width
          with 'showbreak' can leave wrapped continuation lines with
          zero text width. win_lbr_chartabsize() still runs the partial max_head_vcol calculation in
          that state and divides by width2, crashing during redraw.
Solution: Skip that partial head calculation when the wrapped
          continuation width is zero, matching the other width2 guards
          in charset.c (Jaehwang Jung)

closes: vim/vim#20012

AI-assisted: Codex

0e31fb024c
2026-04-20 09:30:30 +08:00
luukvbaal
fe986e5dd0 feat(options): add 'winpinned' to pin a window #39157
Problem:
- Unable to "pin" a window to prevent closing without specifically
  being targeted.
- :fclose closes hidden windows (even before visible windows).

Solution:
- Add 'winpinned' window-local option. When set, window is skipped by
  :fclose and :only. Pin the ui2 cmdline window (which should always be
  visible), so that it is not closed by :only/fclose.
- Skip over hidden (and pinned) windows with :fclose.

Co-authored-by: glepnir <glephunter@gmail.com>
2026-04-19 20:36:55 -04:00
Justin M. Keyes
a38451be40 fix(excmd): nlua_call_excmd require() failure is a "lua_error"
Although `nlua_call_excmd` is semantically for implementing Ex-commands,
the `require()` should never fail, so that's a "Lua error".

But if the call itself fails (the later `semsg` call), that's an "Ex
cmd" error.
2026-04-20 02:31:09 +02:00
Jaehwang Jung
f2cc0a249d fix(drawline): hang while redrawing diff filler above fold #39219
Problem:
win_line() falls into infinite loop when a diff window has top filler
above its first visible buffer line, that first visible buffer line is a
closed fold, and the folded line uses normal non-empty foldtext.

Solution:
Allow flushing pending diff filler rows even when the underlying buffer
line is folded with foldtext.

AI-assisted: Codex

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
2026-04-19 12:29:31 -04:00
Ashley Hauck
4b54bca3df feat(events): trigger MarkSet autocmd in :delmarks #39156
Problem:
`api.nvim_buf_del_mark` already emits a `MarkSet` event with `col` and `line` set to 0. However, `:delmarks` currently emits no events.

Solution:
Change `:delmarks` to emit the same `col==line==0` event.
2026-04-19 07:42:08 -04:00
glepnir
b351afb1b1 fix(lsp): show CompletionItem.detail in info popup #38904
Problem: completionItem/resolve response's `detail` field is silently
dropped. Only `documentation` is shown in the popup.

Solution: Prepend `detail` as a fenced code block before `documentation`
in the info popup, skipping if documentation already contains it.
2026-04-18 15:43:20 -04:00
Justin M. Keyes
54398c5874 docs: misc #39045 2026-04-18 15:38:59 -04:00
Jaehwang Jung
97caa88972 fix(lsp): skip codelens refresh redraw for deleted buffer #39193
Problem:
After on_refresh() sends a textDocument/codeLens request, the buffer may
be deleted before the response arrives. The response callback then tries
to redraw that deleted buffer and raises Invalid buffer id error.

Solution:
Check buffer validity before redrawing.

AI-assisted: Codex
Co-authored-by: Yi Ming <ofseed@foxmail.com>
2026-04-18 15:38:09 -04:00
Evgeni Chasnovski
3a4cc5db0b fix(lua): make vim._with() work with buf=0 and win=0 context #39151
Problem: Using `buf=0`/`win=0` context in `vim._with` should be
  equivalent to using explicit buffer/window identifier respectively.

Solution: Explicitly adjust context in case of `buf=0` or `win=0`.
2026-04-18 12:04:28 -04:00
Justin M. Keyes
6701b45331 refactor(vimfn): full-Lua impl of vim.fn.environ() 2026-04-18 16:57:37 +02:00
zeertzjq
48d11681c2 test(tui_spec): don't run tty-test in a shell (#39186) 2026-04-18 19:53:19 +08:00
luukvbaal
68f7acaaae fix(marks): adjust marks when unloading "nofile" buffer #39118
Problem:  Marks are not adjusted unloading a buffer that doesn't exist
          on disk. E.g. extmarks are still valid (and will be beyond the
          end of the buffer if the buffer is reloaded), even though the
          text is lost.
Solution: Adjust marks for a cleared buffer when unloading a buffer that
          doesn't exist on disk.
2026-04-18 06:53:00 -04:00
Evgeni Chasnovski
6b9b4a1377 fix(vim.filetype): match() fails if g:ft_ignore_pat is not defined #39158
Problem: Calling `vim.filetype.match({ filename = '...', buf = ... })`
  during startup results in an error due to not yet defined
  `g:ft_ignore_pat`.

Solution: Add a guard to check `g:ft_ignore_pat` related properties only
  if the variable is defined. This also allows to simplify other tests
  which did not depend on `g:ft_ignore_pat` but required it explicitly
  set to work.
2026-04-18 06:50:28 -04:00
Evgeni Chasnovski
7219b816ea fix(lsp): limit number of created highlight groups (#39133)
* fix(api): allow silencing "Too many highlight groups" error

Problem: Using Lua's `vim.api.nvim_set_hl(0, 'New', {...})` can fail if
  there are too many existing highlight groups. However, this error can
  not be silenced with `pcall`.

Solution: Make it possible to silence in `nvim_set_hl` and
  `nvim_get_hl_id_by_name`.

* fix(lsp): limit number of groups created by `document_color()`

Problem: A file can contain many string colors that would be highlighted
  by an LSP server. If this number crosses 19999 (maximum number of
  allowed highlight groups), there are general issues with creating
  other highlight groups, which can break functionality outside of
  `vim.lsp.document_color`.

Solution: Limit number of highlight groups that are created by
  `vim.lsp.document_color` to 10000 (half of allowed maximum).
  This is not a 100% solution (since there can exist more than 10000
  other highlight groups), but explicitly checking number of groups is
  slow and 10000 should (hopefully) be enough for most use cases.
2026-04-17 17:16:11 -07:00
Justin M. Keyes
0d4d285bd2 perf(vim.fn): call Lua-implemented vim.fn.xx() directly #39166
Problem:
- Builtin "Vimscript" functions (f_xx) are mostly implemented in C.
  Partly that's because there is some boilerplate required to call out
  to Lua.
- Calls to `vim.fn.foo()` always marshall over the Lua <=> Vimscript
  ("typval") bridge, even if `fn.foo()` is implemented entirely in Lua:
  ```
  Lua => typval => Object => Lua => Object => typval => Lua.
  ```

Solution:
Functions declared in eval.lua with `func_lua` are implemented in
entirely in Lua (`_core/vimfn.lua`).

- `gen_eval.lua` wires `func_lua` entries to `lua_wrapper`, which handles
  the typval conversion for Vimscript callers (slow path).
- `nlua_call()` detects `func_lua` functions and calls the Lua
  implementation directly. This eliminates all conversion overhead for
  Lua callers (fast path).
- Validate at build-time that `func`, `func_float`, and `func_lua` are
  mutually exclusive.
- Migrate `hostname()` as a toy example, to show the idea.
2026-04-17 19:10:20 -04:00
zeertzjq
4eaf782bb6 fix(terminal): forward streamed bracketed paste properly (#39152) 2026-04-18 06:33:52 +08:00
Yi Ming
e84076c7c6 test(lsp): extract buf/util parts from lsp_spec.lua #39149
Problem:
`test/functional/plugin/lsp_spec.lua` had grown into a large catch-all file that mixed core LSP client lifecycle coverage, `vim.lsp.buf.*` behavior, and `vim.lsp.util.*` behavior in one place.

Solution:
Split the large tests into more focused test files without changing test coverage or intended behavior.

After this change, `lsp_spec.lua` is more focused on core LSP client/config/dynamic-registration behavior.
2026-04-17 15:27:50 -04:00
zeertzjq
724fccd46f fix(completion): update CursorColumn during completion (#39159)
Since Nvim uses a compositor, redrawing windows won't lead to flicker in
the popup menu, so the pum_visible() checks in move.c can be removed.
2026-04-17 21:20:51 +08:00
zeertzjq
fefad0721a test: include test path in summary (#39141)
Ref: https://github.com/neovim/neovim/pull/38486#discussion_r3088483987
2026-04-17 21:20:36 +08:00
luukvbaal
f0a8e6f337 fix(ui2): dialog paging is inconsistent #39128
Problem:  - Paging keys in the dialog window consume input when the user
            may not expect it. The dismissable title hint intended to
            mitigate that results in having to press Escape twice to
            abandon the prompt.
          - Mimicked "msgsep" float border is taking up unnecessary
            space when window takes up the entire screen.

Solution: - Use (conventional, albeit less convenient) keys intended
            for scrolling to page the dialog window:
            <(Mousewheel/Page)Up/Down>, <Home/End>.
          - Only set the float top border when separation is actually
            necessary, i.e. window does not reach the first row.
2026-04-16 16:32:08 -04:00
altermo
bb2284d75e fix(treesitter): TSNode:id() with NUL byte causes unreliable select() #39134
Problem:
`TSNode:id()` returns the underlying c pointer as a string, which may include
NUL bytes. In PUC Lua, `('%s'):format('\0a\0')` returns `''` and not `'\0a\0'`
(i.e. treats the string as a c-string (which terminates at the NUL byte)).

This resulted in two different nodes being able to have the same id.

Solution:
Use concatenation `..` instead of `string.format()`.
2026-04-16 13:52:20 -04:00
Evgeni Chasnovski
df6a0827fb test(pack): increase retry timeout for startup test #39125
Problem: Unreliable test on Windows which sometimes fails with too many
  failed retries.

Solution: Increase timeout in hopes that it will be enough to make it
  pass more frequently. This should not affect fast and already working
  platforms.
2026-04-16 10:11:34 -04:00
luukvbaal
5b0ad4a060 fix(float): don't unload 'hidden' float buffer with :close! (#39096)
Problem:  When closing floating windows to close a tabpage, if the current
          buffer will unload, buffers contained in those floating windows
          will too (unexpectedly).
Solution: Don't pass along "free_buf" argument; check 'bufhidden' for
          the buffer in the to be closed float.
2026-04-16 11:43:27 +02:00
Justin M. Keyes
6b1a918038 Merge #39078 render class dot members as module functions 2026-04-16 05:42:33 -04:00
Yi Ming
37aa66c1a2 feat(docs): render class dot members as module functions
AI-assisted: Codex
2026-04-16 16:50:36 +08:00
Barrett Ruth
3838a2579e fix(treesitter): restore highlighting on 32 bit systems #39091
Problem: Treesitter highlighting regressed on 32-bit builds because ranges that should cover the whole buffer were corrupted when passed into Lua.

Solution: Round-trip those range values through Lua and validate them so treesitter sees the same ranges on 32 and 64-bit builds.
2026-04-16 03:59:20 -04:00
Raizento
d2fff0590a fix(lsp): set 'winfixbuf' in open_floating_preview() window #39058
Problem:
The window opened by `vim.lsp.util.open_floating_preview()`
allows its buffer to be switched. Presumably that only happens
by accident and is disorienting.

Solution:
Set 'winfixbuf' in the open_floating_preview() window.
2026-04-15 17:14:35 -04:00
Justin M. Keyes
646ce85aa5 refactor: update usages of deprecated "buffer" param #39089 2026-04-15 18:45:26 +00:00
Justin M. Keyes
71ac4db335 refactor(api): rename "window" to "win" (positional parameters) #39083
continues d0af4cd909.

This commit renames positional parameters. This is only "cosmetic", but
is intended to make it extra clear which name is preferred, since people
often copy existing code despite the guidelines in `:help dev-naming`.
2026-04-15 13:31:17 -04:00
Yi Ming
1740d51ede feat(lsp): highlight foldtext via treesitter #38789
Problem:
To support `collapsedText`, which allows the LSP server to determine the
content of the foldtext, we provided `vim.lsp.foldtext()`. However, such
content does not have highlighting.

Solution
Treat the filetype of `collapsedText` as the filetype of the corresponding
buffer and use tree-sitter to highlight it.
2026-04-15 10:27:44 -04:00
Lewis Russell
1f53abf54b refactor(diagnostic): split diagnostic module
Extract the diagnostic implementation from
runtime/lua/vim/diagnostic.lua into focused internal modules covering
config, display, float rendering, jump/list helpers, namespace and
storage management, severity/shared utilities, and statusline support.

Move the builtin handlers into runtime/lua/vim/diagnostic/handlers/ and
keep runtime/lua/vim/diagnostic.lua as the public facade that lazily
dispatches to the split modules. This preserves the external
vim.diagnostic API while making the implementation easier to navigate
and reason about.

AI-assisted: Codex
2026-04-15 14:44:13 +01:00
Lewis Russell
9e80f63c30 Merge pull request #38486 from lewis6991/testharnes 2026-04-15 14:43:11 +01:00
Lewis Russell
55f9c2136e test: replace busted with local harness
Replace the busted-based Lua test runner with a repo-local harness.

The new harness runs spec files directly under `nvim -ll`, ships its own
reporter and lightweight `luassert` shim, and keeps the helper/preload
flow used by the functional and unit test suites.

Keep the file boundary model shallow and busted-like by restoring `_G`,
`package.loaded`, `package.preload`, `arg`, and the process environment
between files, without carrying extra reset APIs or custom assertion
machinery.

Update the build and test entrypoints to use the new runner, add
black-box coverage for the harness itself, and drop the bundled
busted/luacheck dependency path.

AI-assisted: Codex
2026-04-15 12:09:25 +01:00
zeertzjq
202e17deef vim-patch:9.2.0346: Wrong cursor position when entering command line window (#39072)
Problem:  Wrong cursor position when entering command line window
Solution: Add check_cursor() command to verify the cursor position
          (Hirohito Higashi).

When opening the command-line window with CTRL-F after typing a command
that fills the screen width, the cursor was placed past the end of the
line.  Add check_cursor() after setting State to MODE_NORMAL so the
cursor is adjusted to the last character.

Also fix the cmdwin prefix character (e.g. ':') being drawn on wrapped
continuation rows.  Draw an empty space instead so that the text
alignment is preserved.

closes: vim/vim#19964

c4fe1e958a

Cherry-pick Test_wildmenu_pum() changes from patch 9.1.1995.

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 18:22:05 +08:00
Lewis Russell
e289f9579c fix(lua): make vim.deep_equal cycle-safe
AI-assisted: Codex
2026-04-15 09:26:45 +01:00
Barrett Ruth
e827c3b648 fix(gf): handle local file: URI paths #38915
Problem:
`gf` and `<cfile>` treat `file:/absolute/path` as a literal path and
open `file:/...` instead of the local file.

Solution:
Strip the local `file:` prefix before path resolution in the hyperlink
path code.
2026-04-14 18:08:09 -04:00
luukvbaal
5d3cda472c feat(api): use zindex to determine dimmed cursor shape #39054
Problem:  The cursor shape is changed to indicate when it is behind an
          unfocused floating window (since a2b92a5e). This behavior
          cannot be controlled by a floating window that doesn't want
          to dim the cursor.

Solution: Assign a zindex-offset of 50 to the zindex of the current
          window. To not dim the cursor when creating a floating window
          on top of the current window one can assign the zindex
          accordingly.
2026-04-14 16:08:36 -04:00
Justin M. Keyes
faad7c73ac test: n.rmdir() save-and-restore CWD #39048 2026-04-14 15:37:06 +00:00
Evgeni Chasnovski
b8a24bfadf test(pack): use n.rmdir() to delete directories #39046
Problem: using `vim.fs.rm(dir_path, { force = true, recursive = true })`
  can result in an error on Windows if the process has a handle to it.

Solution: Use `n.rmdir()` helper in cases when its possible side effects
  (like changing working directory) does not matter.
2026-04-14 08:22:11 -04:00
luukvbaal
f0f9620b38 fix(cmdline): avoid Ex-mode NULL cmdline_block event #39043
Problem: Attempting to emit cmdline_block event with NULL cmdbuff after
<C-\><C-N> in Ex-mode.

Solution: Don't emit cmdline_block event when cmdbuff is NULL.
2026-04-14 08:12:24 -04:00
Justin M. Keyes
d77808ec59 docs: lsp, options, api #38980
docs: lsp, options

- revert bogus change to `_meta/builtin_types.lua` from 3a4a66017b

Close #38991

Co-authored-by: David Mejorado <david.mejorado@gmail.com>
2026-04-14 06:09:54 -04:00
glepnir
aa7cba995d fix(completion): preselect ignores completeopt flag #39030
Problem: compl_preselect_match is set even when completeopt doesn't
include preselect.

Solution: Check kOptCotFlagPreselect in ins_compl_add before setting
compl_preselect_match.
2026-04-14 02:30:16 -04:00
Justin M. Keyes
df8d98173c feat(api): rename buffer to buf in retval #38900
In 3a4a66017b, 4d3a67cd62
we renamed "buffer" to "buf" in dict parameters.

This commit also renames such keys in dict return-values.
2026-04-13 12:42:26 -04:00
jdrouhard
eb9cda5fcf test(ui/screen_basic_spec): scrolling behind floating window #38993
validate scrolling behavior in the presence of floating windows.
2026-04-13 07:54:07 -04:00
glepnir
53a29dce0e feat(completion): completeopt=preselect, LSP CompletionItem.preselect #36613
Problem: 
LSP CompletionItem.preselect is not supported.
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionClientCapabilities

Solution:
- Add "preselect" field to complete-items and "preselect" flag
  to 'completeopt'.
- Set preselectSupport=true in LSP client capabilities.
2026-04-13 05:59:07 -04:00
zeertzjq
b081cc3aeb test(terminal/channel_spec): wait some time for shell to start (#38995)
Problem:
The retry on Windows doesn't seem to actually work, as the test still
occasionally fails on Windows. Meanwhile the test can fail on Linux as
well:

FAILED   test/functional/terminal/channel_spec.lua @ 123: chansend sends lines to terminal channel in proper order
test/functional/terminal/channel_spec.lua:131: retry() attempts: 1
test/functional/terminal/channel_spec.lua:134: Failed to match any screen lines.
Expected (anywhere): "echo "hello".*echo "world""
Actual:
  |^ech$ o "hello"                                                                                      |
  |echo "world"                                                                                        |
  |hello                                                                                               |
  |$ world                                                                                             |
  |$                                                                                                   |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |                                                                                                    |
  |term://~/work/neovim/neovim/build/Xtest_xdg_terminal//32516:sh [-]                                  |
  |                                                                                                    |

Solution:
Use a wait before the chansend() instead.
2026-04-13 06:59:47 +08:00
Lars Debor
891bb0e6ce fix(lsp): show_document can't position cursor past EOL in insert-mode #38566
Problem: vim.lsp.util.show_document insert mode is unable
to set the cursor after the target character position if the target character
is at end of line.

Solution: Move cursor after the target character (in append position)
in this case.
2026-04-12 11:46:24 -04:00
glepnir
fcdb148437 fix(pum): info float width grows on reselect with 'linebreak' #38680
Problem: win_linetabsize() includes wrap overhead from 'linebreak'
based on current window width, but the result sizes the window,
causing a feedback loop.

Solution: Temporarily set w_view_width to Columns before measuring.
2026-04-12 11:42:27 -04:00
glepnir
1033739b60 feat(api): nvim_set_hl can set "font" #37668
Problem: Cannot set highlight group fonts via API, only via :highlight
command.

Solution: Add font parameter in nvim_set_hl().
2026-04-12 11:19:40 -04:00