7690 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
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
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
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
glepnir
a7a7cdbcda fix(cmd): filter stdin file "-" from v:argv on :restart #37165
Problem:
restart hangs when nvim was started with stdin input, "-" marker stays
in v:argv, causing the restarted instance to block reading from stdin.

Solution:
filter out the "-" argument when rebuilding v:argv during restart.
Stdin content is ephemeral and shouldn't be re-read after restart.
2026-02-13 06:29:48 -05:00
glepnir
88dc44260f fix(api): preserve WinConfig style when converting float to split #37264
Problem: When a float window with style='minimal' is converted to a
split window and then changes buffer, the minimal style options get
overridden. This happens because merge_win_config() clears the style
field, so get_winopts() doesn't know to re-apply minimal style after
restoring options from the buffer's wininfo.

Solution: Save and restore the style field when clearing the config
during float-to-split conversion.
2026-02-12 20:23:30 -05:00
zeertzjq
cc7022c544 fix(terminal): scrollback may still be wrong on height increase (#37835)
Problem:  Terminal scrollback may be wrong when increasing height after
          outputting lines with full scrollback.
Solution: Ensure enough number of scrollback lines have been deleted.
2026-02-13 01:06:23 +00:00
Kevin Goodsell
fa24df3264 fix(bufwrite.c): handle invalid byte sequences #37363
Problem:

bw_rest was used as an extra buffer to save incomplete byte sequences
between calls to buf_write_bytes. Besides being unnecessarily
complicated, this introduced a number of issues:

1) The bytes stored in bw_rest could still be there at the end of
writing the file, never having been written, thus losing some of the
file content on write.

2) bw_rest was not cleared out after the "checking_conversion" phase,
leaving them to affect the written file content during the writing
phase, corrupting the file.

3) bw_rest could contain extra bytes that need to be written to the
output buffer during a buf_write_convert call, potentially before any
bytes are consumed. But some conversions are in-place, without a
separate output buffer. Writing bytes from bw_rest to the "output"
buffer actually overwrote bytes from the input buffer before they were
read, corrupting the data to be written.

4) The extra bytes in bw_rest that need to be written to the conversion
output buffer were not originally accounted for in the size calculation
for the output buffer, causing a buffer overflow (previously fixed in
Vim patch 9.1.2028).

Solution:

Rather than maintaining a separate buffer, the unconverted bytes at the
end of the buffer can just be shifted to the beginning of the buffer,
and the buffer size updated. This requires a bit of refactoring, and
buf_write_convert and buf_write_convert_with_iconv need to report the
number of bytes they consumed so that buf_write_bytes can handle the
remaining bytes.

Following conversion, bw_buf can be checked for any remaining bytes.
Leftover bytes in this case result in a conversion error, which is
better than silently dropping them.

A short section of dead code was removed from buf_write_convert, for
converting a non-UTF-8 buffer to UTF-8. Neovim buffers are always UTF-8.

A few additional tests for iconv conversions have been added. Vim's
iconv tests are disabled in Neovim because they use unsupported values
for 'encoding'.
2026-02-12 17:38:11 -05:00
Elijah Koulaxis
8a0cbf04d6 feat(iter): peek(), skip(predicate) for non-list iterators #37604
Problem:
Iter:peek() only works if the iterator is a |list-iterator| (internally, an `ArrayIter`).
However, it is possible to implement :peek() support for any iterator.

Solution:
- add `_peeked` buffer for lookahead without actually consuming values
- `peek()` now works for function, pairs(), and array iterators
- `skip(predicate)` stops at the first non matching element without consuming it
- keep existing optimized behavior for `ArrayIter` to maintain backward compatibility
- use `pack`/`unpack` to support iterators that return multiple values
2026-02-12 11:55:16 -05:00
phanium
179e7fccd7 fix(ui2): incomplete :echon message in g< pager #37819
Problem:
`:echo 1 | echon 2<cr>g<` shows "2", but should be "12".

Solution:
Don't clear temp msg (g<) if we are appending.
2026-02-12 11:10:37 -05:00
Justin M. Keyes
858576777e docs: lsp, options, promptbuf
Close #37630
Close #37682
Close #37762
Close #37785

Co-authored-by: Daniel Schmitt <d.schmitt@lansoftware.de>
Co-authored-by: Duane Hilton <duane9@gmail.com>
Co-authored-by: NeOzay <colpaert.benoit@gmail.com>
Co-authored-by: Yi Ming <ofseed@foxmail.com>
Co-authored-by: "Justin M. Keyes" <justinkz@gmail.com>
2026-02-12 13:46:45 +01:00
zeertzjq
16da47f474 fix(terminal): changing height may lead to wrong scrollback (#37824)
Problem:  Changing terminal height immediately after outputting lines
          may lead to wrong scrollback.
Solution: Insert pending scrollback lines before the old window height.
2026-02-12 20:10:02 +08:00