100 Commits
Author SHA1 Message Date
glepnir bf4b0ea764 fix(float): changing zindex does not restack drawn float #42571
Problem:
nvim_win_set_config() with only a new zindex does not change which
float is drawn on top.

Solution:
Recompose the grid area after its layer is reordered.
2026-10-30 09:21:56 -04:00
glepnir 7b9ac8b4db fix(lsp): plaintext info inherits markdown rendering #42492
Problem:
The info popup is reused between items. Once a markdown item turns on
treesitter and conceal, they stay on, so plaintext docs shown after it
get rendered as markdown.

Solution:
Turn them off for non-markdown items.
2026-10-20 16:35:54 -04:00
glepnir 17f43325b1 vim-patch:9.2.1203: command completion uses stale state (#42489)
Problem:  Completion for -complete=breakpoint/filetypecmd uses stale
          state from a previous :breakdel/:profdel/:filetype completion.
Solution: Reset the state in set_cmd_context() and getcompletion().

closes: vim/vim#21419

https://github.com/vim/vim/commit/f81f03d457b3a296ce37629411cce3765837a793
2026-10-20 10:12:04 +08:00
glepnir f74c5b6488 fix(buffer): avoid use-after-free in buf_ensure_loaded() #42446
Problem: open_buffer() can run autocommands that wipe the buffer
while loading, leaving a dangling buf_T.

Solution:
Check that the buffer is still valid and loaded after open_buffer().
2026-10-19 14:13:30 -04:00
glepnir be5167e21c vim-patch:9.2.1197: :autocmd completion fails after ++args (#42384)
Problem:  Cannot complete the command after ++once or ++nested for
          :autocmd.
Solution: Skip over these flags in set_context_in_autocmd() (glepnir).

closes: vim/vim#21429

https://github.com/vim/vim/commit/cf57ec0db8a9bc9926c7ede86a8586f057545723
2026-10-16 09:20:14 +08:00
glepnir f84f8a4155 fix(api): crash on invalid :tab address #42328
Problem:
nvim_parse_cmd("'btab", {}) and typing ":'btab" crash, parse_cmdline()
continues with a NULL eap->cmd after an invalid :tab address.

Solution:
Fail if parse_command_modifiers() set an error.
2026-10-13 04:59:36 -04:00
glepnir e244a2adca feat(lsp): support client_id in vim.lsp.completion.get() #42189
Problem:
vim.lsp.completion.get() always asks every client that has completion
enabled in the buffer, so a mapping cannot ask just some of them.

Solution:
Add a "client_id" option that limits the request to the given client,
or clients if it is a list.
2026-10-03 15:29:48 -04:00
glepnir d51a6e2d55 fix(lua): types for getloclist() signatures #42131
Problem: vim.fn.getloclist() is untyped, unlike getqflist().

Solution: Split it into typed list and {what} forms, like getqflist().
2026-09-28 07:26:34 -04:00
glepnir 71f3a2ad63 perf(lsp): read options once per completion response #42106
Problem:
Converting completion items reads 'completeopt' through vim.opt,
'ignorecase' and 'smartcase' for every item.

Solution:
Read them once per response.
2026-09-27 07:19:04 -04:00
glepnir bc0cdbe02d build(clang-tidy): disable checks renamed from cert-xx #42049
Problem:
clang-tidy reports an issue with `atoi()` in insexpand.c

Solution:
clang-tidy 22 renamed cert-err34-c to
bugprone-unchecked-string-to-number-conversion, cert-env33-c to
bugprone-command-processor, and cert-err33-c to bugprone-unused-return-value.
2026-09-23 10:08:53 -04:00
glepnir 6c97dd7e9b refactor(api): reuse parse_cmdline in nvim_cmd #38508
Problem:
nvim_cmd() duplicates Ex parsing: it sets the address type and default
range itself and builds the whole command line in build_cmdline_str().

Solution:
Build only the range, command name and arguments, and let
parse_cmdline() fill in exarg_T.
2026-09-22 05:24:42 -04:00
glepnir 432797eb61 docs(lua): v:event field annotations #41963 2026-09-18 05:16:59 -04:00
glepnir 2a344d8c84 fix(lsp): snippet is not expanded when resolve races the user #41774
Problem:
on_complete_done() defers clear_word() and the snippet expansion until
completionItem/resolve answers, and drops both when 'changedtick' moved
meanwhile. Typing right after accepting leaves the plain word in the
buffer.

Solution:
Expand before requesting, and anchor the resolved edits with an extmark
instead of gating them on 'changedtick'.
2026-09-11 07:49:57 -04:00
glepnir 08dd3adffb feat(api): add ev.win to autocmd callback args #39826
Problem: Autocmd callbacks currently have to rely on curwin, which may
already have changed by the time they run. This is especially noticeable
for WinNew, WinClosed, WinResized and WinScrolled.

Solution: Track the window in the autocmd context and expose it as ev.win.
Pass it explicitly for the window events that need it.
2026-09-09 15:42:20 -04:00
glepnir 0a844adc13 fix(lsp): newlines in the completion word from insertText #41801
Problem:
A textEdit is cut to its first line but an insertText is not, so its
newlines reach the |complete-items| word.

Solution:
Cut it the same way.
2026-09-09 08:04:23 -04:00
glepnir b3bd442c5c fix(lsp): completion dynamicRegistration breaks capability readers #41771
Problem:
A server that supports dynamic registration must not also declare
completionProvider at initialize, so server_capabilities.completionProvider
is nil for anything reading it directly.

Solution:
Do not advertise it by default. A client that follows a registration can
declare it itself.
2026-09-08 05:48:38 -04:00
glepnir 937f835a3e feat(lsp): support dynamic registration of completionProvider #41748
Problem:
dynamicRegistration is declared false, and completionProvider is read
from server_capabilities only.

Solution:
Declare it, and prefer registerOptions per field.
2026-09-07 09:53:35 -04:00
glepnir cccf359851 build: disable some clang-tidy readability checks #41556
Problem:
New clang-tidy checks readability-trailing-comma and
readability-redundant-parentheses fire across the codebase.

Solution:
Disable readability-trailing-comma and readability-redundant-parentheses
checks in the clang-tidy configuration.
2026-09-02 04:54:00 -04:00
glepnir f0146bcbe7 vim-patch:9.2.1009: duplicate dict code in ins_compl_dict_alloc() (#41497)
Problem:  ins_compl_dict_alloc() builds the same dict as
          fill_complete_info_dict().
Solution: Call fill_complete_info_dict() instead (glepnir).

closes: vim/vim#21140

https://github.com/vim/vim/commit/303a153694d93e93620023835c64e4dc2122e3b2
2026-08-26 08:37:44 +00:00
glepnir f97bcbdf77 vim-patch:9.2.1007: fuzzy completion list wrongly sorted after complete() (#41498)
Problem:  With 'completeopt' "fuzzy", a re-sort after complete() leaves the
          last match unsorted at the end of the list.
Solution: Find the original text by its flag instead of assuming
          compl_shows_dir points at it.

closes: vim/vim#21103

https://github.com/vim/vim/commit/7e747229993bf784768fbb22b4bdd3a13dbb3d13
2026-08-26 04:32:09 +00:00
glepnir 2a382ffb61 fix(lsp): completion overwrites text before the word boundary #41463
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.
2026-08-24 06:14:49 -04:00
glepnir 92d5531f96 vim-patch:9.2.1001: complete_info() does not report the item highlight 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
2026-08-24 14:35:25 +08:00
glepnir 2c5f37f6af fix(lsp): empty filterText/sortText/insertText not treated as unset #41421
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.
2026-08-22 07:40:17 -04:00
glepnir 6d8401f8d5 fix(ui): missing vertical separator for a winbar only window (#41151)
Problem: A winbar-only window with zero text height still occupies one row,
         but win_update() returns early on w_view_height == 0 and skips the
         vertical separator.

Solution: Also draw the vertical separator in the early return path.
2026-08-05 06:42:39 +08:00
glepnir 387bd0fbe7 refactor(window): use window handle in frame layout log (#41153)
Problem: The frame layout debug log uses the obsolete window ID field.

Solution: Use the window handle field when printing window information.
2026-08-04 11:39:59 +00:00
glepnir 182b02afb0 fix(insexpand): use String cleanup for compl_leader (#41044)
Problem:
compl_leader is a String, but it is cleared with XFREE_CLEAR().

Solution:
Replace XFREE_CLEAR() with API_CLEAR_STRING().
2026-07-29 10:51:44 +00:00
glepnir 3fa5904cf2 fix(lsp): multibyte fragment treated as commit char #41019
Problem:
commit_chars_str() reads a 0x80-0xBF byte as a 2-byte lead, so
"\xA9x" makes "x" a commit character. nvim_get_hl() returns
a dict, so `#` on it is 0 whether or not the group exists

Solution:
use vim.str_utf_end() and drop entries that are not one whole
character. use next check dict length.
2026-07-28 08:39:03 -04:00
glepnir 916a6e9546 fix(eval): complete_info() equal, preselect, commit_chars #41022
Problem:  complete_info() does not report "equal", "preselect" or "commit_chars".

Solution: Report them for the items that set them.
2026-07-28 07:24:58 -04:00
glepnir 0b3b12da8d fix(completion): "preselect" ignores "noinsert", menu order #41007
Problem:  A preselected item is inserted even with "noinsert", and the
          first added preselected item wins over the first one shown
          in the menu.
Solution: Use K_DOWN when "noinsert" is set; pick the first preselected
          item that made it into the menu.
2026-07-27 08:49:12 -04:00
glepnir f95bd73935 feat(float): 'previewpopup' option #26799
Problem:
The preview-window (:pedit, etc.) always uses a split, but it would be
useful as a floatwin (or "popup").

Solution:
Support Vim's 'previewpopup' option.
2026-07-23 17:27:14 -04:00
glepnir d06bac614c refactor(window): extract w_kind for window role #40830
Problem:
w_float_is_info conflates a window's role with its floating layout,
which are orthogonal properties.

Solution:
Replace w_float_is_info with a w_kind enum for the window's role.
2026-07-20 07:21:53 -04:00
glepnir 9fae7234f6 feat(completion): support completionList.applyKind #40769
Problem: values from completionList.itemDefaults always replace the
item's own commitCharacters and data. Since 3.18 a server can ask for
them to be merged instead.

Solution: Handle CompletionList.applyKind and advertise applyKindSupport.
Drop itemDefaults once folded into the items: get_items() runs twice on
the same result and a Merge isn't idempotent.

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#completionItemApplyKinds
2026-07-17 21:07:01 -04:00
glepnir 5ce9e74f13 feat(completion): commitCharacters #38417
Problem: LSP completion commitCharacters are not handled. Typing a
commit character (e.g. `.`, `(`, `;`) while a completion item is
selected does not accept the item first.

Solution: Store commit characters as a flat string in complete-items.
Check it before completion stops, accept the match and let
the character be inserted normally.
2026-07-15 19:08:37 -04:00
glepnir 58b6310adc fix(startup): respect enter for windows created in startup scripts #37287
Problem: When a split window is created from the init script using nvim_open_win()
with enter=false, the current window focus is not preserved. The cursor
incorrectly moves into the newly created split during startup.

Solution: Save curwin before the iteration loop in create_windows(), and
restore it after the loop. also update edit_buffers() to use curwin instead
of firstwin.
2026-07-12 12:30:40 -04:00
glepnir 59dbca9b0c fix(api): nvim_cmd() "args" type too narrow #40670
Problem: nvim_cmd() accepts number/boolean in args and converts them
to strings, but the keyset declares ArrayOf(String).

Solution: use ArrayOf(Union(Integer, String, Boolean)) and wrap union
types in parens when generating array annotations.
2026-07-10 20:34:08 -04:00
glepnir 7312df77bb fix(api): nvim_buf_set_text resets changelist to 0 #39965
Problem: changed_lines got a hardcoded 0, so the changelist entry
and '. mark always recorded column 0 instead of where the edit
actually happened.

Solution: pass start_col instead. changelist now tracks the real
column.
2026-06-29 14:38:07 -04:00
glepnir 4d18693c49 vim-patch:9.2.0741: complete_check() does not return TRUE for mapped input (#40467)
Problem:  Mapped typed keys didn't interrupt completion in
          complete_check() (Yikai Zhao)
Solution: Also interrupt when in_compl_func and not replaying a register.
          (glepnir)

closes: vim/vim#5547
closes: vim/vim#20643

https://github.com/vim/vim/commit/37d85f5f1ad336fdc63e949c3b2db8ae7be618e4
2026-06-29 07:08:24 +08:00
glepnir 823517ad1d fix(highlight): keep guisp underline color in float with 'winblend' #40283
Problem:
A colored (guisp) underline showing through a 'winblend' float
lost its special color and followed the foreground instead.

Solution:
In the blend-through case, blend the underline's special color
only when the cell below sets sp explicitly; otherwise clear it.
2026-06-16 07:39:32 -04:00
glepnir 02b7415324 fix(lsp): requery empty isIncomplete completion lists #40100
Problem:
an empty `{ isIncomplete = true, items = {} }` ends completion
instead of requerying.

Solution:
keep isIncomplete on empty lists and retrigger on keypress while incomplete.
Reset on <C-e> so it doesn't immediately re-query.
2026-06-15 18:29:27 -04:00
glepnirandRyan Patterson 724e1421f8 fix(api): keep highlight font through set/get and redraws #40200
Problem: a font set via nvim_set_hl is lost or corrupted with font-only groups,
attribute combining, and update=true, and is dropped on any attr-table rebuild.
nvim__inspect_cell also frees the font name while a returned dict still borrows it.

Solution: register font-only groups, carry font through hl_combine_attr, inherit
it on update, and persist sg_font so a rebuild can restore it. Keep interned font
names across a rebuild instead of clearing them. Add the missing font field to
get_hl_info.

Co-authored-by: Ryan Patterson <cgamesplay@cgamesplay.com>
2026-06-15 17:51:42 -04:00
glepnirandThomas M Kehrenberg 2e8c60cb38 vim-patch:9.2.0624: C-N/C-P cannot be mapped in complete() completion (#40232)
Problem:  Keys valid in CTRL-X mode are never mapped while insert
          completion is active, so <C-N> and <C-P> cannot be remapped
          for completion started by complete().
Solution: Do not disable mappings in CTRL_X_EVAL mode.  In this mode a
          mapping cannot interfere with selecting the completion
          method, which is what the no-mapping rule exists for.

related: vim/vim#6440
related: vim/vim#16880
closes:  vim/vim#20489

https://github.com/vim/vim/commit/076585e6addb5688f123ef3e174fcfee993b7602

Co-authored-by: Thomas M Kehrenberg <tmke8@posteo.net>
2026-06-14 05:15:07 +00:00
glepnir ff0352fd4f vim-patch:9.2.0639: gq with 'formatprg' fails on an empty buffer (#40226)
Problem:  gq (and other filters) on an empty buffer fail with
          "E20: Mark not set": when the filter produces no output,
          do_filter() still subtracts the line count from '[ and '],
          pushing '] to line 0.
Solution: when the filter produces no output, put '[ and '] on a valid
          line instead of subtracting past line 1 (glepnir).

related: neovim/neovim#30593
closes:  vim/vim#19061

https://github.com/vim/vim/commit/aefbca2977653a96f11061da80d6b72587497fb7
2026-06-14 08:45:16 +08:00
glepnir 3f37b230af vim-patch:9.2.0601: matchfuzzypos() returns garbage positions for long candidates (#40140)
Problem:  A needle that only matches past char 1024 gives an INT_MIN + 1
          score with unset positions, e.g.
          matchfuzzypos([repeat('a',1024)..'z'], 'az').
Solution: Drop the candidate when match_positions() returns SCORE_MIN.

closes: vim/vim#20435

https://github.com/vim/vim/commit/52003f7fc11e8fffa4cc8b0969282224a8b9a52e
2026-06-08 05:27:20 +00:00
glepnir 11b9e6f193 fix(option): allow empty/blank edges in 'winborder' #40112
Problem:
The comma form of 'winborder' is split with copy_option_part(),
whose skip_to_option_part() eats spaces after a comma, and empty
fields are rejected.

Solution:
Split the comma form literally on ',', keeping empty fields and
single-space fields.
2026-06-05 06:37:07 -04:00
glepnir 5e3b655ad4 vim-patch:9.2.0591: 'scrolljump' ignored when scrolling up (#40106)
Problem:  srolljump=-100 only scrolls half a page going up, but works
          fine going down. update_topline() always falls back to
          scroll_cursor_halfway() when the cursor is far above topline.
Solution: Only center when sj is smaller than half the window. Otherwise
          call scroll_cursor_top like the downward path does (glepnir).

fixes:  vim/vim#1527
closes: vim/vim#20366

https://github.com/vim/vim/commit/a4a60c0fdb8aeec21dcd14871c465fe0f2e6fbc3
2026-06-04 06:21:59 +02:00
glepnir a5d4b4e0fc vim-patch:9.2.0585: line number wrong after undoing a deletion in quickfix buffer (#40081)
Problem:  Deleting a quickfix line and undoing it leaves the entry
          pointing one line below where it should.
Solution: Don't shift already cleared entries in qf_mark_adjust.

closes: vim/vim#20379

https://github.com/vim/vim/commit/64982d6010c3610e7f44190f4eb128d6f0f2b91a
2026-06-02 07:30:12 +02:00
glepnir 6b6efb37eb vim-patch:9.2.0583: completion: indent not ignored for fuzzy line completion (#40080)
Problem:  Indent is not stripped in whole-line completion (CTRL-X
          CTRL-L).
Solution: Skip the matched line's indent for whole-line matches in
          search_for_fuzzy_match (glepnir).

closes: vim/vim#20405

https://github.com/vim/vim/commit/9fa5f64135c1b018ca5bfc86d851ac8185f6472b
2026-06-02 07:28:23 +02:00
glepnir 70cfeabe23 fix(float): title/footer shows printable control chars #40047
Problem:
Literal tab (or other control char) in a float title/footer is
not made printable, so it renders incorrectly instead of as "^I".

Solution:
Normalize title/footer text for display like 'statusline'
tab to "^I", parameterize parse_virt_text() with untab
and recompute the width.
2026-05-30 10:02:16 -04:00
glepnirandSean Dewar 7662001c48 fix(float): simplify :bufdelete focus retry #39928
Problem:
Followup to #39858. close_windows returned a holder window just so
do_buffer_ext could retry there, but the non-float branch was dead code
and close_windows was called twice.

Solution:
Check one_window directly in do_buffer_ext, drop the holder, make
close_windows void again.

Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
2026-05-21 10:38:04 -04:00
glepnir 26df751add fix(float): :bufdelete in floatwin may change focus #39858
Problem:
(Followup to 54f22a8f01c0feb27a531b52aedf5cdbd5e51b24.)
Deleting another buffer from a floatwin could move focus into the holder
window and fire BufEnter for the buffer being deleted.

Solution:
Use switch_win_noblock() instead of buf_jump_open_win() before
recursing into do_buffer_ext().
2026-05-21 05:06:50 -04:00
glepnir 450ba41436 fix(api): adjust Visual position after nvim_buf_set_text #30690
Problem:
Visual selection could end up in the wrong place after
nvim_buf_set_text or nvim_buf_set_lines. In some delete cases,
Visual.lnum was already clamped before the line shift happened, so the
adjustment got skipped.

Solution:
Split fix_cursor_cols into reusable fix_pos_col logic and reuse it
for Visual updates. Also adjust Visual.lnum before changed_lines so
the shift uses the original position before final clamping.
2026-05-18 13:08:26 -04:00
glepnir 3ffe29d679 fix(lsp): preserve trigger chars on completion #39850
Problem:
After 767fbd8, typing trigger chars would open completion but the
chars were removed.

Solution:
Use filterText fallback so selected item respects typed trigger chars.
2026-05-18 05:25:41 -04:00
glepnir 767fbd88ff fix(lsp): fallback to filterText for non-matching PlainText items #39695
Problem:
PlainText completion items used `textEdit.newText` or `insertText` as
the completion word even when they did not match the typed prefix. This
could break popup completion behavior like 'completeopt+=longest'.

Solution:
Fall back to `filterText` when `newText` or `insertText` does not match
the typed prefix.
2026-05-17 11:58:49 -04:00
glepnir 54f22a8f01 fix(excmd): :bufdelete may fail from floating window #39800
Problem: with a float focused and the target buf only shown in the
last non-float window, do_buffer_ext goes down the buf != curbuf
path. close_windows can't touch the last non-float, b_nwindows stays
> 0, close_buffer is skipped, returns OK silently.

Solution: if a non-float still holds buf after close_windows, jump
into it and recurse. Then buf == curbuf and the existing replacement
path takes over.
2026-05-16 12:25:18 -04:00
glepnir 2dc0efccb0 fix(snippet): cancel session on <Esc> in Select mode #39238
Problem: <Esc> in a Select-mode tabstop leaves the session and highlight active.
CursorMoved isn’t triggered since the cursor doesn’t move.

Solution: use ModeChanged (s:n) instead. Defer with vim.schedule() to avoid transient
s:n from jump().
2026-05-10 09:19:12 -04:00
glepnir 1fd82615b1 refactor(excmd): remove duplicate get_cmd_argt (#39643)
Problem:
`excmd_get_argt` and `get_cmd_argt` do the same thing.

Solution:
Drop `get_cmd_argt` and update its callers to use `excmd_get_argt`.
2026-05-07 08:55:30 +00:00
glepnir 1787965d77 feat(api): nvim_get_commands returns desc #39623
Problem:
Can't get a command's description from nvim_get_commands when
cmd is string.

Solution:
Returns "desc" field in nvim_get_commands.
`definition` is now empty when cmd is function type.
2026-05-06 06:36:39 -04:00
glepnir 941f2f9522 vim-patch:9.2.0418: wildcards in expanded env vars reinterpreted by glob (#39517)
Problem:  With $d='[dir]', `:e $d/file.txt` opens the wrong file,
          `:e $d/<Tab>` fails to complete, and `glob('$d/*')` returns
          nothing. Wildcard characters inside expanded environment
          variables get picked up by globbing again.
Solution: Turn the 4th parameter of expand_env_esc() from a bool into a
          string of characters to escape in each expanded value. Callers
          that pass the result to wildcard expansion should include
          PATH_ESC_WILDCARDS in addition to " \t" (glepnir).

closes: vim/vim#20053

https://github.com/vim/vim/commit/20e98ff1cc3ffc13d42579d2bf9b9567f98595a2
2026-05-02 10:51:44 +08:00
glepnir c79d5f5028 vim-patch:9.2.0417: completion: no support for "noinsert" with 'wildmode' (#39516)
Problem:  completion: no support for "noinsert" with 'wildmode' and
          commandline completion
Solution: Add "noinsert" value to the 'wildmode' option, mirroring
          'completeopt' "noinsert" behaviour (glepnir).

fixes:  vim/vim#16551
closes: vim/vim#20080

https://github.com/vim/vim/commit/af494af5ff188d976073cbc049249614edffa4bf
2026-04-30 11:13:47 +00:00
glepnir b9431b340f fix(lsp): show meaningful error on invalid completion response #39445
Problem: vim.NIL is truthy in Lua, so `#(result.items or result)`
crashes on `#vim.NIL` when servers return null.

Solution: skip spec-allowed result=null silently, raise an error
on items=null with the server name.

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
2026-04-28 10:18:37 -04:00
glepnir 4431713285 feat(events)!: support Optionset modified, drop BufModifiedSet #35610
Problem:
BufModifiedSet autocmd only triggered for current buffer during
redraw, causing delayed events when :wa writes non-current buffers.

Solution:
- Use the aucmd_defer approach to implement `Optionset modified`.
- Drop BufModifiedSet.
2026-04-27 06:30:11 -04:00
glepnir a57fab2f2d test: curbuf initialized in describe-block #39365
Problem: curbuf was initialized at describe-block load time
before any Nvim session existed.

Solution: Replace with 0 directly at call sites.
2026-04-24 09:30:33 -04:00
glepnir 496374e951 fix(shada): bdelete'd buffers not stored in oldfiles #39070
Problem:
b98eefd added `!b_p_bl` to `ignore_buf()`, which also
skips bdelete'd buffers since bdelete unsets `b_p_bl`.

Solution:
Check `b_p_initialized` together with `b_p_bl` so that
bdelete'd buffers (which have b_p_initialized=false) are not
filtered out. Keep `b_p_bl` check only in `shada_get_buflist()`.
2026-04-22 13:05:41 -04:00
glepnir 44770bb924 fix(cmd): ++p, ++edit should match "word" boundary #39146
Problem: `:write ++patate foo` doesn't error out, instead it turns on
mkdir_p and uses "atate foo" as the filename. Same with ++edit.
The parser just does strncmp without checking what comes after.

Solution: require the next char after the option name to not be a
letter
2026-04-22 04:43:07 -04:00
glepnir 01861c2f95 fix(api): expose fg_indexed/bg_indexed in nvim_get_hl #39210
Problem: fg_indexed/bg_indexed were dropped from nvim_get_hl output due
to a wrong short_keys guard. HL_FG_INDEXED also wasn't cleared in
hl_blend_attrs, and HLATTRS_DICT_SIZE was too small.

Solution: Remove the short_keys guard, clear HL_FG_INDEXED in
hl_blend_attrs, bump HLATTRS_DICT_SIZE to 24, and clarify docs that
these flags mean rgb is an approximation of the cterm palette index.
2026-04-20 05:12:52 -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
glepnir 92317013b4 refactor: move e_invalwindow to errors.h (#39067)
Problem: e_invalwindow was a static local, inconsistent with other error strings.

Solution: Convert it to EXTERN/INIT style and move it to errors.h.
2026-04-15 11:59:07 +08: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
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
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
glepnir 49086862fc fix(api): nvim_get_hl drops groups defined with link_global #38492
Problem: hlgroup2dict passes &ns_id to ns_get_hl twice. The first call
(link=true) sets *ns_hl = 0 when link_global is set, so the second call
and the sg_cleared guard both see ns_id == 0 and bail out. The group is
silently dropped from the result.

Solution: use a temporary copy of ns_id for each ns_get_hl call so the
original value is preserved.
2026-04-12 08:38:35 -04:00
glepnir af9a72d8c1 fix(lsp): check stale context in hover/signature callback #38724
Problem: hover/signature callback lacked consistency checks, so slow LSP servers
could open a float after the cursor had already moved away.

Solution: guard the callback with buf validity, buf version, and cursor
position checks before opening the float. Also fix table capacity calculation.
2026-04-11 10:32:56 -04:00
glepnir 01567ad4f6 fix(highlight): preserve inherited colors when update=true breaks links #38750
Problem: Breaking a link with update=true loses colors inherited from
the linked group.

Solution: Copy color indices from the linked group so inherited colors
remain visible in :hi output.
2026-04-11 10:14:27 -04:00
glepnir 6473d007e7 fix(lsp): apply_text_edits causes unwanted BufDelete events #38778
Problem:
Since 2f6d1d3c88, `apply_text_edits`
unconditionally sets `buflisted=true`, causing spurious BufDelete events
if plugins restore the original 'buflisted' state on unlisted buffers:
https://github.com/neovim/neovim/blob/65ef6cec1cb766334c59d3255595dfe523b11020/src/nvim/option.c#L2159-L2169

Solution:
- Don't set 'buflisted' in `apply_text_edits`. Set it more narrowly, in
  `apply_workspace_edit` where the semantics requires affected buffers
  to be visible to the user.
- Also skip setting 'buflisted' if it would not be changed, to avoid
  redundant `OptionSet` events.
2026-04-08 17:10:52 -04:00
glepnir 8603fc9180 fix(pum): crash with 'pumborder' and wide item (#38852)
Problem: pum_col goes negative when item width + border exceeds screen.

Solution: account for border_width in pum_compute_horizontal_placement()
instead of adjusting pum_col after the fact
2026-04-08 09:16:41 +08:00
glepnir af707dd242 fix(diagnostic): virtual_lines should anchor at end_lnum, not lnum #38701
Problem: Multi-line diagnostics always render virtual lines below lnum.

Solution: Use end_lnum when placing the virt_lines extmark.
2026-04-06 13:22:39 -04:00
glepnir 9383a096eb fix(api): nvim_set_hl boolean false corrupts underline styles (#38504)
Problem: setting one underline style to false clears bits belonging
to another style. `{underdouble = true, underdashed = false}` results
in undercurl because CHECK_FLAG_WITH_KEY does `m &= ~flag` which
doesn't work for multi-bit encoded values sharing HL_UNDERLINE_MASK.

Solution: use a local variable to derive the correct clear mask from
the flag. Clear the whole HL_UNDERLINE_MASK field instead of individual
bits, and only clear on false when the current style actually matches.
2026-03-28 15:26:46 +08:00
glepnir 4d04d0123d feat(api): nvim_set_hl{update:boolean} #37546
Problem: nvim_set_hl always replaces all attributes.

Solution: Add update field. When true, merge with existing
attributes instead of replacing. Unspecified attributes are preserved.
If highlight group doesn't exist, falls back to reset mode.
2026-03-25 06:01:50 -04:00
glepnir f2d0b06ecb fix(lsp): completion word includes leading space from label #38435
Problem: clangd prepends a space/bullet indicator to label. With
labelDetailsSupport enabled, the signature moves to labelDetails,
making label shorter. This flips the length comparison in
get_completion_word, causing it to use item.label directly and
insert the indicator into the buffer.

Solution: only prefer filterText over label when label starts with non-keyword
character in get_completion_word fallback branch.
2026-03-23 11:02:30 -04:00
glepnir 4ed597389c fix(lsp): snippet preview blocked completionItem/resolve request #38428
Problem: Generating snippet preview in get_doc() populated the
documentation field before resolve, so the resolve request was
never sent.

Solution: Move snippet preview logic into on_completechanged and
the resolve callback so it no longer blocks the resolve request.
2026-03-23 07:57:36 -04:00
glepnir cc518cf9ba feat(lsp): support CompletionItem.labelDetails #38403
Problem: CompletionItem.labelDetails is ignored, losing
function signatures and module info in the completion menu.

Solution: Append labelDetails.detail to abbr and use
labelDetails.description for menu with fallback to item.detail.

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionItemLabelDetails
2026-03-21 19:07:26 -04:00
glepnir 24714c0d43 refactor(test): clean up pumborder round test cases #38368
Problem: pumborder round tests contained redundant.

Solution: Remove unnecessary test code.
2026-03-20 04:46:57 -04:00
glepnir 531442ddd8 fix(ui): apply 'pumborder' to mouse menu, fix overflow #36193
Problem:
Mouse popup menus (right-click context menus) do not respect the
'pumborder' option and could overflow screen boundaries when borders
were enabled near the edge.

Solution:
- Remove the mouse menu exclusion from border rendering.
- Add boundary check to shift menu left when border would exceed screen
  width, ensuring complete visibility of menu content and borders.
2026-03-19 13:11:35 -04:00
glepnir 8f9278d7c2 fix(menu): right-click menu fails with E335 when using V after i_ctrl-o #37349
Problem:
Right-click menu fails with E335 when using V in Insert mode (after
i_ctrl-o). The mode detection checks restart_edit before VIsual_active,
incorrectly selecting Insert mode binding even when Visual mode is
active.

Solution:
Check Visual mode before Insert mode, to match get_menu_mode() priority
order.
2026-03-18 18:52:06 -04:00
glepnir 0da9827673 fix(lsp): respect documentation markup kind in completion preview #38338
Problem:
Completion preview always assumes plain text, ignoring LSP documentation "kind".

Solution:
Pass markup kind from completion item to info window, or fallback to PlainText.
2026-03-17 10:24:30 -04:00
glepnir 88a72efb46 fix(diagnostic): open_float() handles config.float function #31577
Problem:
The `float` field of vim.diagnostic.config can be a function,
but diagnostic.open_float() does not handle it correctly.

Solution:
Add handling for it in open_float().
2026-03-16 09:50:13 -04:00
glepnirandSean Dewar e2a0748cb2 feat(api): nvim_win_set_config can move floatwin to another tabpage
Problem: nvim_win_set_config can't move floating windows to different tab pages.

Solution: allow it.

Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
2026-03-14 18:45:29 +00:00
glepnir 5653b25e9b fix(lsp): handle non-string documentation in completion items #38291
Problem: `get_doc` throws error with "attempt to get length of a userdata
value" when `item.documentation` is truthy but not a string (e.g. vim.NIL
from a JSON null).

Solution: Check `type(item.documentation)` before taking its length.
2026-03-14 05:20:34 -04:00
glepnir 7b8deacc3f fix(ui): preview float doesn't respond to mouse scroll #38270
Problem: The floating preview window (e.g. completion info)
has mouse=false, so scroll wheel events pass right through it.

Solution: Set mouse=true on the preview float so users can
scroll its content with the mouse wheel.
2026-03-13 06:17:10 -04:00
glepnir 3f10bb87ef fix(completion): wrong CompleteDone reason for auto-inserted sole match #38280
Problem: #38169 used compl_used_match to determine the CompleteDone
reason, but this fires too broadly, it also changes the reason to
"accept" when the popup was shown and the user dismissed it with <Esc>
or <Space>, breaking snippet completion with autocomplete.

Solution: Instead of checking compl_used_match in, check whether the pum
was never shown (compl_match_array == NULL) in ins_compl_stop().
When a match was inserted but the pum never displayed,
set the completed word so CompleteDone fires with reason "accept".
This keeps the "discard" reason intact when the user dismisses a visible
pum without confirming.
2026-03-13 06:13:58 -04:00
glepnir f3ec657ebc fix(api): nvim_parse_cmd on range-only, modifier-only commands #36665
Problem: nvim_parse_cmd rejects valid commands like `:1` (range-only)
or `aboveleft` (modifier-only).

Solution: allow empty command when range or modifiers exist, and handle
execution using existing range command logic.
2026-03-13 06:06:39 -04:00
glepnir d87972f920 fix(pum): keep info window aligned with pum when above #38251
Problem:
When `pum_above` is set, the info window uses `anchor=SW`. Updating the
info window height during `CompleteChanged` causes its top edge to shift,
so it no longer aligns with the top of the pum.

Solution:
Use `NW` as the anchor even when `pum_above` is true so the info window
remains aligned with `pum_row`.
2026-03-12 05:48:14 -04:00
glepnir d7903982ae refactor(highlight): extract set_gui_color() from do_highlight()
Problem: GUIFG, GUIBG, GUISP handling in do_highlight() is basically
the same code copy-pasted three times.

Solution: Pull the shared logic into a small set_gui_color() helper.
2026-03-12 14:25:14 +08:00
glepnir d5a8c9d766 fix(highlight): correct change detection in do_highlight for gui colors
Problem: The GUIFG/GUIBG/GUISP handlers compare sg_rgb_{fg,bg,sp}
(RgbValue) against old_idx (color table index) instead of comparing
sg_rgb_{fg,bg,sp}_idx against old_idx, making did_change unreliable.

Solution: Use the _idx field for the index comparison and add the
missing sg_rgb_sp_idx assignment.
2026-03-12 14:25:14 +08:00
glepnir f168d215cf fix(lsp): ensure augroup before querying autocmds #38254 2026-03-11 13:57:19 -04:00
glepnir 63594ffa04 feat(lsp): do completionItem/resolve if completeopt=popup #32820
Problem:
No completionItem/resolve handler.

Solution:
If completeopt=popup is set, invoke completionItem/resolve when
a completion item is selected. Show resolved documentation in popup next
to the completion menu.
2026-03-11 05:48:31 -04:00
glepnir e23c083d13 fix(highlight): avoid null deref, misc issues #38164
Problem: update_window_hl dereferenced the pmap_get result without a
NULL check. Also `tmp` had the wrong type and attr_id==0 was rejected
twice.

Solution: check the pointer before dereferencing, change `tmp` to
bool, and update the attr_id check to `< 0`.
2026-03-10 18:17:02 -04:00
glepnir 145548a24a feat(lsp): show snippet preview if completeopt=popup #32553
Problem:
LSP completion does not show snippet preview.

Solution:
Show snippet preview if 'completeopt' includes popup.
2026-03-10 14:34:58 -04:00
glepnir 69419f8b3e fix(completion): CompleteDone reason="discard" when candidate text remains #38169
Problem: CompleteDone fires with reason="discard" even when the candidate
text was inserted and left in the buffer, because reason was determined
solely by the terminating keycode (Ctrl-Y).

Solution: Check compl_used_match to detect whether inserted
text remains in the buffer, and set reason="accept" accordingly.
2026-03-09 07:58:13 -04:00