9941 Commits

Author SHA1 Message Date
zeertzjq
f3feae0bbf fix(terminal): crash after deleting buffer lines (#37921)
Problem:  Terminal crashes after deleting buffer lines.
Solution: Don't insert lines above lines 0.
2026-02-17 13:00:13 +00:00
glepnir
bd12aef784 fix(highlight): refresh highlight attrs before message output #25737
Problem:
When MsgArea highlight is changed, the next message may flash
and disappear because msg_start() renders with stale highlight attributes.

msg_puts_len() uses HL_ATTR(HLF_MSG) to render message text, which
happens before update_screen() calls highlight_changed().
So the message is rendered with outdated attrs.

Solution:
Call highlight_changed() in msg_start().
2026-02-17 07:59:07 -05:00
Justin M. Keyes
73c4472d4a Merge #37913 prompt-bufffer, u_savecommon 2026-02-17 07:40:19 -05:00
zeertzjq
4f6b3e5c15 fix(terminal): spurious buffer update with empty buf (#37920)
Problem:  Opening a terminal on an empty buffer produces a spurious
          buffer update event.
Solution: Don't call deleted_lines_buf() if no lines have been deleted.
2026-02-17 20:30:34 +08:00
luukvbaal
e268760e46 feat(ui2): show active paging keys in dialog float title #37919
Problem:  Paging keys being consumed without obvious indicator
          in the dialog window can be surprising.
Solution: Display a hint with paging keys in the dialog window title
          when paging is active. Recognize <Esc> as mapping to stop
          paging.
2026-02-17 07:28:56 -05:00
zeertzjq
17d126049a test: don't run test cases directly in describe() (#37915) 2026-02-17 11:34:12 +08:00
Sean Dewar
ce9dbd398b fix(undo): u_savecommon uses wrong buffer
Problem: u_savecommon with reload = true wrongly uses curbuf.

Solution: use buf. Fix comments.
2026-02-17 01:03:58 +00:00
Sean Dewar
16bf7652b7 fix(prompt): prompt_setprompt with unloaded buffer, ': with lnum 0
Problem: prompt_setprompt memory leak/other issues when fixing prompt line for
unloaded buffer, or when ': line number is zero.

Solution: don't fix prompt line for unloaded buffer. Clamp ': lnum above zero.
2026-02-17 00:31:26 +00:00
Justin M. Keyes
dbe07e292e refactor(tests): server_spec #37912 2026-02-16 19:19:58 -05:00
luukvbaal
16495e6863 fix(ui2): only set dialog on_key callback once #37905
Problem:  vim.on_key() called for each message while cmdline is open.
          Cursor is on a seemingly random column when pager is entered.
          Entering the pager while the cmdline is expanded can be more
          convenient than pressing "g<".
          Pager window is unnecessarily clamped to half the shell height.
          Setting 'laststatus' while pager is open does not adjust its
          dimensions.
Solution: Only call vim.on_key() once when dialog window is opened.
          Ensure cursor is at the start of the first message when
          entering the pager.
          Enter the pager window when "<CR>" is pressed while the
          cmdline is expanded.
          Don't clamp the pager window height.
          Set message windows dimensions when 'laststatus' changes.
2026-02-16 17:11:32 -05:00
Tristan Knight
13cf80deef fix(lsp): map all LSP methods to server capabilities (#37910) 2026-02-16 13:20:34 -08:00
Maria Solano
05bd4398c5 feat(lsp): support textDocument/documentLink (#37644) 2026-02-16 11:05:33 -08:00
luukvbaal
49c19a1fe3 fix(messages): message not flushed at end of command #37904
Problem:  Logic determining messages belonging to the last command to
          show with "g<" does not flush pending messages. This can
          result in clearing the temporary message history before a
          message still belonging to the previous command was emitted.
Solution: Flush pending messages when marking the end of messages
          belonging to previous command.
2026-02-16 11:51:43 -05:00
Maria Solano
6e1745e96e feat(lua): support vim.Range:has(vim.pos) #37879 2026-02-16 11:05:38 -05:00
Jibril
501a21f333 fix(coverity/637363): out-of-bounds write #37878
Problem:
stack->offset value is used as an array index.

Solution:
Instead of comparing the stack->offset value to the size in bytes of the array,
compare the actual length of the array.
2026-02-16 09:51:00 -05:00
Justin M. Keyes
f4e88cfe42 Merge #37875 prompt-buffer fixes 2026-02-16 09:37:36 -05:00
luukvbaal
a393347673 fix(extmark): adjust invalidate range by one for deleted lines #37897
Problem:  A multi-line extmark that ends exactly at a deleted range end
          is not invalidated.
          Revalidated sign mark is added with incorrect range.
Solution: Remove questionable invalidation range condition which was
          originally added to avoid deleting a mark that ends below a
          deleted line.

          Since splicing for a deleted line, and a replaced range that
          explicitly ends at column 0 beyond a deleted line is identical,
          we can't try to distinguish these two cases. I.e. :1delete 1
          and nvim_buf_set_text(0, 0, 0, 1, 0, {}) yield the same splice
          operation.

          This means that a multi-line sign_text mark should now span at
          least one column beyond its end_row, as seen in the adjusted
          test. This is still somewhat unexpected/inconvenient to me
          which is what prompted me to try to avoid it with the original
          condition.

          Add revalidated sign mark back to decor with correct range;
          third sign mark added to test exposed a crash.
2026-02-16 09:35:53 -05:00
luukvbaal
d131d67e67 fix(float): clamp floating window above cmdline #37899
Problem:  A float whose zindex is below the cmdline can be enlarged and
          end up behind the cmdline.
Solution: Clamp height of such windows to not extend beyond 'cmdheight'.
2026-02-16 09:33:32 -05:00
Rahul Yedida
249f305bbc feat(defaults): per-platform 'guifont' default #37175
Problem:
Font rendering and kerning are subpar in GUIs.

Solution:
Set default 'guifont' based on common CSS fonts per:
https://github.com/system-fonts/modern-font-stacks#monospace-code
2026-02-16 09:05:23 -05:00
zeertzjq
e6fae64454 fix(terminal): handle opening terminal on unloaded buffer (#37894)
Problem:  Strange behavior when opening terminal on unloaded buffer.
Solution: For nvim_open_term() ensure the buffer is loaded as it needs
          to be read into the terminal. For jobstart() just open the
          memfile as the file content isn't needed.

Not going to make nvim_open_term() pass stdin to the terminal when stdin
isn't read into a buffer yet, as other APIs don't read stdin on unloaded
buffer either. There are also other problems with loading buffer before
reading stdin, so it's better to address those in another PR.
2026-02-16 21:47:45 +08:00
zeertzjq
4450a45466 vim-patch:9.1.1954: Setting a byte in a blob, accepts values outside 0-255
Problem:  Setting a byte in a blob, accepts values outside 0-255
Solution: When setting a byte in a blob, check for valid values
          (Yegappan Lakshmanan)

closes: vim/vim#18870

f4a299700e

Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2026-02-16 21:17:02 +08:00
zeertzjq
cbec4603a0 vim-patch:partial:9.1.1668: items() does not work for Blobs
Problem:  items() does not work for Blobs
Solution: Extend items() to support Blob
          (Yegappan Lakshmanan).

closes: vim/vim#18080

da34f84847

Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2026-02-16 21:17:02 +08:00
zeertzjq
992543c361 vim-patch:8.2.3841: Vim9: outdated TODO items, disabled tests that work (#37900)
Problem:    Vim9: outdated TODO items, disabled tests that work.
Solution:   Remove TODO items, run tests that work now.  Check that a dict
            item isn't locked.

71b7685092

Co-authored-by: Bram Moolenaar <Bram@vim.org>
2026-02-16 12:32:18 +00:00
zeertzjq
cf68c82598 test(old): restore test coverage for invalid 'statusline' flag 2026-02-16 08:24:19 +08:00
zeertzjq
77d396caf4 vim-patch:9.2.0009: tests: test_cindent are not ordered
Problem:  tests: the tests test_cindent_* functions were numbered
          inconsistently, causing them to be executed in wrong order.
Solution: Rename the test_cindent functions with zero-padded numbers.

9308c85a7e

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-02-16 08:23:19 +08:00
zeertzjq
b59eba3ada vim-patch:9.2.0007: cindent: recognizing labels within commented lines
Problem:  Comment lines which start like a label are recognized as a
          label and indented based on that.
Solution: Check if the position is in a comment after recognizing a label
          in cin_islabel (Anttoni Erkkilä)

closes: vim/vim#19397

9af18686c7

Co-authored-by: Anttoni Erkkilä <anttoni.erkkila@protonmail.com>
2026-02-16 08:23:18 +08:00
Sean Dewar
51dc752e6c fix(prompt): wrong changed lnum in init_prompt
Problem: if init_prompt replaces the prompt line at the ': mark, it calls
inserted_bytes with the wrong lnum.

Solution: use the correct lnum. Call appended_lines_mark instead when appending
the prompt at the end.
2026-02-15 23:42:10 +00:00
Sean Dewar
3a10405214 fix(prompt): prompt_setprompt does not adjust extmarks, no on_bytes
Problem: prompt_setprompt does not adjust extmarks or trigger on_bytes
buffer-updates when fixing the prompt line.

Solution: adjust them, trigger on_bytes.

Notably, hides extmarks when replacing the entire line (and clearing user
input). Otherwise, when just replacing the prompt text, hides extmarks there,
but moves those after (in the user input area) to the correct spot.
2026-02-15 23:42:10 +00:00
Sean Dewar
7641177c5f fix(prompt): wrong cursor col after prompt_setprompt, no on_lines
Problem: prompt_setprompt calls coladvance with a byte column, but it expects a
screen column. on_lines buffer-updates aren't fired when fixing the prompt line.

Solution: don't use coladvance. Call changed_lines, which also simplifies the
redraw logic. (and calls changed_cline_bef_curs if needed; added test checks
this)

Unlike https://github.com/neovim/neovim/pull/37743/changes#r2775398744, this
means &modified is set by prompt_setprompt if it fixes the prompt line.
Not setting &modified is inconsistent anyway -- even init_prompt sets it if it
fixes the prompt line.
2026-02-15 23:41:32 +00:00
zeertzjq
7d8653575f vim-patch:9.2.0004: Changing hidden prompt buffer cancels :startinsert/:stopinsert (#37881)
Problem:  Changing hidden prompt buffer cancels :startinsert/:stopinsert
          (after 9.0.1439).
Solution: Don't change mode for a prompt buffer in an autocommand
          window (zeertzjq).

closes: vim/vim#19410

8b81a6b6e1
2026-02-15 22:51:03 +00:00
Riley Bruins
4719b94443 feat(statusline): option to specify stacking highlight groups #37153
**Problem:** No easy way to stack highlight groups #35806.

**Solution:** Add a way to specify a new statusline chunk with a
highlight group that inherits from previous highlight attributes.

Also applies to tabline, etc.
2026-02-15 12:16:51 -05:00
Tim Pope
a1895f024a fix(lsp): support workspace/configuation with no section #27510
The [spec for `workspace/configuration`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_configuration)
marks the `section` property of each item in `items` optional.
Therefore, I believe it violates the spec to skip over items without
a section, because then the length of the results won't match the length
of a valid `items` input. The spec does not elaborate on _what_ to
return in this case, but I don't think it would be controversial to say
that returning the full configuration, as done for an empty string, is
the most natural interpretation.

That empty string case, by the way, was initially [added in
response](5da124fc82)
to a real world implementation requesting it. I don't have a similar
real world implementation to point to for the omitted `section`, but
I would note that `getConfiguration()` from `vscode-languageserver-node`
[defaults to a request with no section](d859bb14d1/server/src/common/configuration.ts (L24-L26))
when called with no arguments. I surmise that this is intended as a way
to retrieve the full configuration.
2026-02-15 11:37:24 -05:00
Wayne Young
3eb8a2784e test(lsp): wait up to 1 second to read messages 2026-02-15 10:31:10 +00:00
zeertzjq
b614c15392 refactor(terminal): don't put cursor at bottom-left in Normal mode (#37873)
When the terminal process is suspended, putting cursor at bottom-left
hints that pressing a key will change the suspended state. However, when
returning to Normal mode, the user is more likely to interact with the
actual terminal output (e.g. copying it), so it's better to put cursor
at the old position which should be closer to the output.

Also, using is_focused() to check for mode is confusing. Just check
`State & MODE_TERMINAL` instead.
2026-02-15 17:25:22 +08:00
Sean Dewar
2a5d687cc9 fix(prompt): prompt_setprompt sets cursor col unnecessarily
Problem: prompt_setprompt adjusts the cursor's column number even when it's not
on the prompt's line.

Solution: only adjust when on the prompt's line.
2026-02-15 06:04:12 +00:00
Sean Dewar
b3096b5860 fix(prompt): ml_get error with invalid ': lnum
Problem: internal error E315 in init_prompt if ': has an invalid line number.

Solution: clamp the line number.
2026-02-15 01:41:12 +00:00
Sean Dewar
4afbc25432 fix(prompt): heap-buffer-overflows with invalid ': col
Problem: heap-buffer-overflow in init_prompt and prompt_setprompt if ': mark has
an invalid column number.

Solution: consider an out-of-bounds column number as a missing prompt.

Remove the check for NULL for old_line, as ml_get_buf can't return NULL.
2026-02-15 01:41:12 +00:00
Sean Dewar
1349233cd1 fix(prompt): heap-buffer-overflow in prompt_setprompt
Problem: prompt_setprompt may check the wrong buffer, which can lead to a
heap-buffer-overflow.

Solution: don't use curbuf.

Also replace all kCallbackNone initializers with CALLBACK_INIT.
2026-02-15 01:40:31 +00:00
zeertzjq
f8d59cfab9 fix(highlight): setting 'winhl' doesn't work with global ns (#37868)
Problem:  Setting 'winhighlight' doesn't after setting global namespace
          using nvim_win_set_hl_ns().
Solution: Check if using another namespace when setting 'winhighlight'
          instead of disabling 'winhighlight' in nvim_win_set_hl_ns().
2026-02-15 08:03:44 +08:00
Shadman
8ab511bba5 feat(prompt): plugins can update prompt during user input #37743
Problem:
Currently, if prompt gets changed during user-input with
prompt_setprompt() it only gets reflected in next prompt. And that
behavior is not also consistent. If user re-enters insert mode then the
user input gets discarded and a new prompt gets created with the new
prompt.

Solution:
Handle prompt_setprompt eagerly. Update the prompt display, preserve user input.
2026-02-14 12:18:08 -05:00
Tristan Knight
b99cdd08de refactor(lsp): centralize provider capability resolution #37221
- Refactor LSP client to use unified provider-based capability lookup for
  diagnostics and other features.
- Introduce `_provider_value_get` to abstract capability retrieval,
  supporting both static and dynamic registrations.
- Update diagnostic handling and protocol mappings to leverage
  provider-centric logic.
2026-02-14 10:50:48 -05:00
Evgeni Chasnovski
539b8027a3 fix(pack): explicitly close confirmation window #37861
Problem: Executing `nvim_buf_delete()` does not guarantee that the
  window which shows the buffer is going to close after `:write` or
  `:quit`. In particular, if there is no listed buffer present.

Solution: Explicitly close the window that was created for confirmation
  buffer. Use `pcall` to catch cases when the window was already closed
  or when it is the last window.
2026-02-14 08:26:36 -05:00
Dmytro Pletenskyi
01666aae64 feat(diagnostic): fromqflist({merge_lines}) #37416
Problem:
`vim.diagnostic.fromqflist` ignores lines that are `item.valid == 0` (see
`getqflist`). Many qflists have messages that span multiple lines, which look
like this:

    collection/src/Modelling/CdOd/Central.hs|496 col 80| error: [GHC-83865]
    ||     • Couldn't match expected type: InstanceWithForm
    ||                                       (FilePath
    ||                                        -> SelectValidCdInstWithForm
    ...

calling `vim.diagnostic.fromqflist(vim.fn.getqflist)` gets a diagnostic message
like this:

    error: [GHC-83865]

only the first line is kept, but often, the remaing lines are useful as well.

Solution:
Introduce `merge_lines` option, which "squashes" lines from invalid qflist items
into the error message of the previous valid item, so that we get this
diagnostic message instead:

    error: [GHC-83865]
         • Couldn't match expected type: InstanceWithForm
                                           (FilePath
                                            -> SelectValidCdInstWithForm
2026-02-14 06:07:01 -05:00
Justin M. Keyes
0864939cc5 fix(restart): append -c <cmd> at end, drop -- [files…] #37846
Problem:
- `:restart <cmd>` prepends `-c <cmd>` before the original `-c` args (if
  any). So the original `-c` args may "override" it, which is
  surprising.
- Confusing logic: `v:argv` is partially prepared in `ex_docmd.c`, and
  then later `ui.c` skips other parts of it.

Current behavior is nonsense, for example this sequence:

    :restart echo "Hello"
    :restart +qall echo "Hello" | echo "World"

results in this v:argv:

    [
      'nvim'
      '-c'
      'echo "Hello" | echo "World"'
      '--embed'
      '-c'
      'echo "Hello"'
      ...
    ]

Whereas after this commit, v:argv is:

    [
      'nvim'
      '--embed'
      ...
      '-c'
      'echo "Hello" | echo "World"'
    ]

Solution:
- Append `-c <cmd>` at the _end_ of `v:argv`, not the start.
- Use a dummy placeholder `+:::` to mark where the "restart command"
  appears in `v:argv`.
- Do all `v:argv` preparation in `ex_docmd.c`. This simplifies `ui.c`.
- Drop `-- [files…]` from `v:argv` since it is probably more annoying
  than useful. (Users can use sessions to restore files on restart.)
2026-02-14 05:34:30 -05:00
Yochem van Rosmalen
b5ce7e74dc refactor(help): move local-additions to Lua #37831
Problem:
- ~200 line function of hard-to-maintain C code.
- Local Addition section looks messy because of the varying description
  formats.

Solution:
- Move code to Lua.
- Have a best-effort approach where short descriptions are right
  aligned, giving a cleaner look. Long descriptions are untouched.
2026-02-14 05:30:18 -05:00
zeertzjq
1a1a60bd05 fix(terminal): resuming doesn't work with command in fish (#37857)
Problem:  Resuming terminal process doesn't work with command in fish.
Solution: Send SIGCONT to the entire process group.

Use killpg() like what bash and zsh do on `fg`:
https://cgit.git.savannah.gnu.org/cgit/bash.git/tree/jobs.c?id=637f5c8696a6adc9b4519f1cd74aa78492266b7f#n3928
77045ef899/tree/Src/jobs.c (l2674)
77045ef899/tree/Src/signals.c (l538)

Install fish on CI to test this.
2026-02-14 10:49:39 +08:00
zeertzjq
9cbc430cfb fix(terminal): missing refresh with partial mappings (#37839)
Problem:  Terminal buffers are not refreshed when processing keys that
          trigger partial mappings.
Solution: Process due terminal refreshes before redrawing.
2026-02-14 08:00:27 +08:00
Riccardo Mazzarini
6657cc3671 fix(ui): repaint separator connectors after all window updates #37852
Problem:
When a window is redrawn, `draw_vsep_win`/`draw_hsep_win` paint plain
separator characters (`│`/`─`) along the window's entire edges,
including cells that are connector corners belonging to other windows.
Then `draw_sep_connectors_win` only fixes the corners of that same
window, not connectors in the middle of its edges that belong to
adjacent windows.

If the window that "owns" the connector corner isn't part of the redraw,
the connector is never repainted.

Solution:
Move connector drawing out of the per-window `win_update` and into a
separate pass in `update_screen` that runs after all windows have been
updated.
2026-02-13 18:39:05 -05:00
zeertzjq
6bc0b8ae87 feat(terminal): detect suspended PTY process (#37845)
Problem:  Terminal doesn't detect if the PTY process is suspended or
          offer a convenient way for the user to resume the process.
Solution: Detect suspended PTY process on SIGCHLD and show virtual text
          "[Process suspended]" at the bottom-left. Resume the process
          when the user presses a key.
2026-02-13 13:49:08 +00:00
zeertzjq
9c5ade9212 fix: wait() checks condition twice on each interval (#37837)
Problem:  wait() checks condition twice on each interval.
Solution: Don't schedule the due callback. Also fix memory leak when
          Nvim exits while waiting.

No test that the condition isn't checked twice, as testing for that can
be flaky when there are libuv events from other sources.
2026-02-13 21:02:40 +08:00