Commit Graph

7396 Commits

Author SHA1 Message Date
Justin M. Keyes
2bbc90f4d5 Merge #36585 feat: has() can check multiple Vim versions 2025-12-03 00:28:53 -05:00
Justin M. Keyes
65141153d9 Merge #36792 unreliable tests 2025-12-02 01:06:40 -05:00
Justin M. Keyes
ebd758f809 test: unreliable "channel opened, ..., deleted by pressing a key"
Problem:
Test sometimes fails on macos:

    test/functional/terminal/channel_spec.lua:96: Expected objects to be the same.
    Passed in:
    (number) 3
    Expected:
    (number) 2

Solution:
Retry a few times.
2025-12-02 00:14:09 -05:00
Justin M. Keyes
c8f2b10a40 test: unreliable "job exit event on jobstart(…,{term=true})"
Problem:
Test often fails in cirrus (bsd) ci:

    FAILED   test/functional/terminal/channel_spec.lua @ 149: no crash when TermOpen autocommand processes job exit event when using jobstart(…,{term=true})
    test/functional/terminal/channel_spec.lua:158: Row 1 did not match.
    Expected:
      |*^ready $ foobar                                              |
      |*                                                            |
      |*[Process exited 0]                                          |
      |                                                            |
    Actual:
      |*^ready $                                                     |
      |*[Process exited 0]                                          |
      |*                                                            |
      |                                                            |

Solution:
Use one printf call instead of multiple.
2025-12-02 00:08:38 -05:00
benarcher2691
ad438b6b14 fix(ui): exclude hidden windows from tabline window count #36779
Problem: When `vim._extui` is enabled, the default tabline shows an
incorrect window count (e.g., "2" when only 1 window is visible). This
happens because the extui pager window has `focusable=true` (needed for
user interaction) but `hide=true` (not visible by default).

Solution: Modify the window counting logic in `statusline.c` and
`ex_docmd.c:ex_tabs()` to also exclude hidden windows
(`wp->w_config.hide`), not just non-focusable windows.

Also updates test expectations in `cmdline2_spec.lua` which previously
expected the incorrect window count "2" when extui was enabled. The test
now correctly expects no window count indicator when only 1 visible
window exists.

Fixes #36759
2025-12-01 23:57:56 -05:00
zeertzjq
b64e36cef0 vim-patch:9.1.1943: Memory leak with :breakadd expr
Problem:  Memory leak with :breakadd expr
Solution: Free debug_oldval and debug_newval before assigning to them.
          Verify the existing (though confusing) :breakadd expr behavior
          (zeertzjq).

It seems that :breakadd expr doesn't work as documented at all. This PR
only fixes the memory leak. The tests are for the existing behavior.

closes: vim/vim#18844

a474de64df
2025-12-02 07:24:28 +08:00
benarcher2691
7f2d5d6883 fix(msgpack): use fixstr encoding for strings of length 20-31 #36737
Problem:
MessagePack fixstr format supports string lengths 0-31, but mpack_str()
only used fixstr for lengths < 20. Strings of 20-31 bytes were
incorrectly encoded as str8 (2-byte header) instead of fixstr (1-byte
header).

Solution:
Change the condition from `len < 20` to `len < 32` to match the
MessagePack specification.

This fix affects message timing which exposed a pre-existing race
condition in the channels_spec PTY test. The test now uses a helper
function to accumulate partial PTY reads, making it more robust.

Fixes #32784
2025-12-01 13:16:44 -05:00
Jan Edmund Lazo
5196162540 feat(version): support multiple Vim versions
Group up to 15 vimpatch numbers in 1 line to guard against
'make formatc'.
1-liner for vim_versions, num_patches.

Automate '*Version' to remove version.h macros.

'-V1 -v' lists merged Vim versions.
2025-12-01 02:34:51 -05:00
Tristan Knight
23ddb2028b feat(lsp): semanticTokens/range #36705
Problem:
Nvim supports `textDocument/semanticTokens/full` and `…/full/delta`
already, but most servers don't support `…/full/delta` and Nvim will try
to request and process full semantic tokens response on every buffer
change. Even though the request is debounced, there is noticeable lag if
the token response is large (in a big file).

Solution:
Support `textDocument/semanticTokens/range`, which requests semantic
tokens for visible screen only.
2025-11-30 21:06:56 -05:00
CompileAndConquer
f9ef1a4cab fix(buffer): defer w_buffer clearing to prevent dict watcher crash #36748 2025-11-30 20:56:53 -05:00
zeertzjq
14d65dae91 fix(buffer): don't allow changedtick watcher to delete buffer (#36764) 2025-12-01 09:14:14 +08:00
Olivia Kinnear
12d4c624bb feat(ex_cmds): consistent :restart behavior (#36723) 2025-11-30 02:14:28 -08:00
Riley Bruins
03d6cf7aae feat(lsp): support version in textDocument/publishDiagnostics #36754
This commit makes it so that push diagnostics received for an outdated
document version are ignored.
2025-11-29 23:38:11 -05:00
benarcher2691
5bb8734fb6 build(windows): vendor xxd.c #36746
Problem:
Currently we fetch a prebuilt xxd.exe from neovim/deps for Windows,
which is not ideal in terms of obviousness, misses updates, and is
clumsy to update.

Solution:
Similar to tee.c (#36363), vendor xxd.c from Vim and build it as part
of the Neovim build process. This makes the source obvious, enables
analyzer checks, and simplifies updates.

Fixes #36664
2025-11-29 23:15:47 -05:00
Evgeni Chasnovski
28ff4deda7 fix(colorscheme): adjust StatusLine[NC] for diagnostics #36719
Problem: It is desirable for the default statusline to contain colored
  diagnostics information. However, current `StatusLine` group is
  purposefully defined as almost inverted `Normal` to "make current
  window obvious". This makes diagnostic information from
  `vim.diagnostic.status()` barely visible: it uses established
  `DiagnosticSignXxx` groups which have colored foreground with
  lightness close to `StatusLine` background.

  Also the `StatusLineNC` group is fairly different from `Normal` in
  order to both "makes window separators clear" and "be different from
  `CursorLine`". But not as mush different as `StatusLine` because
  "`StatusLine` and `StatusLineNC` should be clearly different".

Solution: Make both `StatusLine` and `StatusLineNC` be slightly closer
  in lightness to `Normal`. This makes `StatusLine` and `StatusLineNC`
  groups satisfy their conditions in the following way:
  - `vim.diagnostic.count()` is readable on `StatusLine` - yes.
  - `vim.diagnostic.count()` is readable on `StatusLineNC` - yes.
  - `StatusLine` makes current window obvious - I'd say yes.
  - `StatusLine` and `StatusLineNC` are clearly different - it depends
    on the eyes and monitor. The current is clearly better, but the new
    ones I'd say are still visibly different.
  - `StatusLineNC` makes window separators clear - I'd say yes, but
    depends on the eyes and monitor.
  - `StatuslineNC` is different from `CursorLine` - NO, they are same.

  Another approach to solve this would be to introduce dedicated
  `DiagnosticStatuslineXxx` groups to use in `vim.diagnostics.status()`.
  They can be defined using foreground colors from the same lightness as
  `Normal`. This would make them readable in `StatusLine`. But not
  `StatusLineNC`, though.
2025-11-29 12:36:05 -05:00
zeertzjq
812186e2dc vim-patch:9.1.1930: completion: 'completefuzzycollect' is too obscure
Problem:  completion: 'completefuzzycollect' option is too obscure
Solution: Deprecate the option, but don't error out for existing scripts,
          behave like 'completefuzzycollect' is set when fuzzy
          completion is enabled (Girish Palya).

fixes: vim/vim#18498
closes: vim/vim#18788

33fbfe003c

Remove this option completely, as it's introduced in Nvim v0.12 cycle.

Co-authored-by: Girish Palya <girishji@gmail.com>
2025-11-28 07:53:49 +08:00
glepnir
31c814a0ed fix(float): respect statusline=3, don't inherit local 'statusline' #36716
Problem: When creating floating window from existing window, the
window-local 'statusline' option is inherited, causing unwanted
statusline display. Additionally, with laststatus=3 (global statusline),
the early return skipped clearing wp->w_redr_status flag.

Solution: Clear inherited window-local 'statusline' in win_new_float
for style="minimal". Restructure win_redr_status to always clear the
flag before any early returns, and only render floating window statusline
when window-local 'statusline' is explicitly set. And respect 'laststatus'
option.
2025-11-27 10:23:46 -08:00
zeertzjq
9a864d0a3c fix(edit): handle cindent properly with completion (#36711)
Don't handle cindent in insert_check(). Instead, do that just before
returning from insert_execute() if required.
This also makes the in_cinkeys() change from #12894 unnecessary.
2025-11-27 11:30:02 +08:00
glepnir
8a626e5c4a feat(float): 'statusline' in floating windows #36521
Problem:
Can't show 'statusline' in floating windows.

Solution:
Use window-local 'statusline' to control floating window statusline visibility.
2025-11-26 09:10:45 -08:00
Rob Pilling
612b2e7850 feat(api): nvim_get_commands returns function fields #36415
Problem:
nvim_get_commands does not return callbacks defined for
"preview", "complete", or the command itself.

Solution:
- Return Lua function as "callback" field in a Lua context.
- Return "preview" function in a Lua context.
- BREAKING: Return "complete" as a function instead of a boolean.
2025-11-25 21:12:39 -08:00
Maria Solano
7e09fedf43 feat(diagnostic): config.status #36693
Problem:
`diagnostic.status()` is configured via `config.signs`, but users may
want diagnostics only in statusline, not in the gutter (signs).

Solution:
Add `config.status`.
2025-11-25 21:00:00 -08:00
Kent Sibilev
0a0c349b6f fix(events): crash on WinScrolled #35995
Problem: apply_autocmds function can free both buf_T and win_T pointers

Solution: instead retain winids for WinResized and WinScrolled
autocmds and use curbuf pointer, which is consistent with other uses
of apply_autocmds function
2025-11-25 18:27:52 -08:00
Riley Bruins
4107442103 feat(diagnostic): highlights in diagnostic.status() #36685
Applies the appropriate `DiagnosticSign*` highlight to each group,
resetting the highlights at the end of the expression.
2025-11-25 10:14:46 -08:00
Justin M. Keyes
bf820b1b94 docs: misc, build, lsp 2025-11-22 19:32:45 -05:00
Justin M. Keyes
83d22e0979 refactor: deduplicate test 2025-11-22 17:04:32 -05:00
Justin M. Keyes
9044d64af9 feat: has('terminfo')
Problem:
No way to detect at runtime if the build includes unibilium (or whatever
terminfo layer we swap it with later).

Solution:
Support `has('terminfo')`.
2025-11-22 15:59:07 -05:00
Riccardo Mazzarini
7da4d6abe2 fix(api): on_bytes gets stale data on :substitute #36487
Problem: `extmark_splice()` was being called before `ml_replace()`,
which caused the on_bytes callback to be invoked with the old buffer
text instead of the new text.

Solution: store metadata for each match in a growing array, call
`ml_replace()` once to update the buffer, then call `extmark_splice()`
once per match.

Closes https://github.com/neovim/neovim/issues/36370.
2025-11-20 21:40:08 -08:00
zeertzjq
1eec08d1a2 vim-patch:9.1.1922: Wrong virtcol('$') with virtual text at EOL (#36643)
Problem:  Wrong virtcol('$') with virtual text at EOL (rickhowe).
Solution: Also add 1 to end virtcol when there is virtual text.
          (zeertzjq)

fixes: vim/vim#18761
closes: vim/vim#18762

d434f6c2a5
2025-11-21 08:02:20 +08:00
Oleh Volynets
ea70d2ad85 fix(ui2): unset Search highlighting (#36633)
Problem:
Trying to match the search highlight groups to the Normal highlight for
the window can fail when the message highlighting contains a fg/bg that
the Normal highlight doesn't (like an error message in cmd will have
ErrorMsg highlight instead of MsgArea - which is Normal in cmd.)

Solution:
Link the search highlight groups to an empty group in 'winhighlight'
thus disabling them instead of overriding them with Normal/MsgArea/etc.
2025-11-20 17:19:31 +00:00
Lewis Russell
e9b6474ae7 fix(statusline): scope truncation bookkeeping
Limit the default truncation item to the current recursion range so
nested `nvim_eval_statusline()` calls don't reuse stale `stl_items`
pointers. Add a functional regression that evaluates a Lua statusline
helper which forces truncation to ensure the nested scenario stays
stable.

AI-Assist: OpenAI ChatGPT

Fixes #36616
2025-11-20 09:53:11 +00:00
Michele Sorcinelli
69b286c3bf fix(vim.net): filetype detection, mark unmodified #36297
Problem:
When running ":edit <url>", filetype detection is not triggered.

Solution:
Run the autocmds in the filetypedetect group after loading the content.

Problem:
After fetching remote content from a URL and adding it to the buffer,
the buffer is marked as modified. This is inconsistent with the original
netrw behavior, and it causes problems with `:e` to refresh or `:q` as
it prompts for saving the file even if the user hasn't touched the
content at all.

Solution:
Mark the buffer as unmodified right after adding the remote content to
the buffer.
2025-11-19 22:04:59 -08:00
altermo
caa9419355 refactor!: optwin.lua #36505
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2025-11-19 20:43:15 -08:00
zeertzjq
a04c73cc17 fix(input): discard following keys when discarding <Cmd>/K_LUA (#36498)
Technically the current behavior does match documentation. However, the
keys following <Cmd>/K_LUA aren't normally received by vim.on_key()
callbacks either, so it does makes sense to discard them along with the
preceding key.

One may also argue that vim.on_key() callbacks should instead receive
the following keys together with the <Cmd>/K_LUA, but doing that may
cause some performance problems, and even in that case the keys should
still be discarded together.
2025-11-20 12:33:02 +08:00
luukvbaal
ba6fc90b6f fix(ui2): hide search highlights in msg window #36626
fix(ui2): hide search highlights in msg window.

Problem:  Search highlighting is shown in the msg (and dialog) window.
Solution: Hide search highlighting in all but the pager window.
2025-11-19 17:02:32 -08:00
Justin M. Keyes
7c2d4df2d3 revert: "fix(tutor): remove hyperlinks, simplify non-interactive examples" #36622
This reverts commit 5e039c8e97.
2025-11-19 13:47:48 -08:00
Jeff Martin
ff792f8e69 fix(lsp): enable insertReplaceSupport for use in adjust_start_col #36569
Problem:
With the typescript LSes typescript-language-server and vtsls,
omnicompletion on partial tokens for certain types, such as array
methods, and functions that are attached as attributes to other
functions, either results in no entries populated in the completion menu
(typescript-language-server), or an unfiltered completion menu with all
array methods included, even if they don't share the same prefix as the
partial token being completed (vtsls).

Solution:
Enable insertReplaceSupport and uses the insert portion of the lsp
completion response in adjust_start_col if it's included in the
response.

Completion results are still filtered client side.
2025-11-18 23:03:40 -08:00
glepnir
c22b03c771 feat(lsp): user-specified sorting of lsp.completion multi-server results #36401
Problem: No way to customize completion order across multiple servers.

Solution: Add `cmp` function to `vim.lsp.completion.enable()` options
for custom sorting logic.
2025-11-18 21:38:53 -08:00
glepnir
4998b8d7b5 feat(api): nvim_win_set_config accepts unchanged "noautocmd" #36463
Problem: Cannot reuse same config with noautocmd for both window
creation and updates, even when value is unchanged.

Solution: Only reject noautocmd changes for existing windows.
2025-11-18 20:23:50 -08:00
Justin M. Keyes
4244a96774 test: fix failing lsp/utils_spec #36609
Problem:
098da1fc2c was merged without rebasing on 4b8980949c, which
changed how this test behaves.

Solution:
Update the test.
2025-11-18 19:06:44 -08:00
zeertzjq
677446c70f fix(cmdline): make sure pum is removed on leave (#36608) 2025-11-19 09:40:20 +08:00
skewb1k
4b8980949c fix(lsp): set concealcursor='' in LSP floating windows #36596
Problem:
Users often jump and navigate through LSP windows to yank text.
Concealed markdown can make navigation through hyperlinks and code
blocks more difficult.

Solution:
Change 'concealcursor' from 'n' to '' to preserve clean display
while improving navigation and selection of the LSP response.

Closes #36537
2025-11-17 17:49:14 -08:00
Justin M. Keyes
5df1112e5f Merge #36338 vim.pack: lockfile synchronization 2025-11-17 09:55:11 -08:00
Grzegorz Rozdzialik
2767eac320 feat(diagnostics): stack DiagnosticUnnecessary,DiagnosticDeprecated highlights #36590
Problem: unnecessary and deprecated diagnostics use their own highlight
groups (`DiagnosticUnnecessary` and `DiagnosticDeprecated`) which
override the typical severity-based highlight groups (like
`DiagnosticUnderlineWarn`).

This can be misleading, since diagnostics about unused variables which
are warnings or errors, are shown like comments, since then only the
`DiagnosticUnnecessary` highlight group is used. Users do not see the
more eye-catching red/yellow highlight.

Solution: Instead of overriding the highlight group to
`DiagnosticUnnecessary` or `DiagnosticDeprecated`, set them in addition
to the normal severity-based highlights.
2025-11-17 09:37:59 -08:00
Evgeni Chasnovski
f492f62c3d fix(pack): rename confirmation buffer to again use nvim-pack:// scheme
Problem: `nvim://` scheme feels more like a generalized interface that
  may be requested externally, and it acts like CLI args (roughly).
  This is how `vscode://` works.

  Anything that behaves like an "app" or a "protocol" deserves its own
  scheme. For such Nvim-owned things they will be called `nvim-xx://`.

Solution: Use `nvim-pack://confirm#<bufnr>` template for confirmation
  buffer name instead of `nvim://pack-confirm#<bufnr>`.
2025-11-17 12:47:29 +02:00
Evgeni Chasnovski
b151aa761f feat(pack)!: synchronize lockfile with installed plugins when reading it
Problem: Lockfile can become out of sync with what is actually installed
  on disk when user performs (somewhat reasonable) manual actions like:
    - Delete lockfile and expect it to regenerate.
    - Delete plugin directory without `vim.pack.del()`.
    - Manually edit lock data in a bad way.

Solution: Synchronize lockfile data with installed plugins on every
  lockfile read. In particular:

    1. Install immediately all missing plugins with valid lock data.
       This helps with "manually delete plugin directory" case by
       prompting user to figure out how to properly delete a plugin.

    2. Repair lock data for properly installed plugins.
       This helps with "manually deleted lockfile", "manually edited
       lockfile in an unexpected way", "installation terminated due to
       timeout" cases.

    3. Remove unrepairable corrupted lock data and their plugins. This
       includes bad lock data for missing plugins and any lock data
       for corrupted plugins (right now this only means that plugin
       path is not a directory, but can be built upon).

  Step 1 also improves usability in case there are lazy loaded plugins
  that are rarely loaded (like on `FileType` event, for example):
    - Previously starting with config+lockfile on a new machine only
      installs rare `vim.pack.add()` plugin after it is called (while
      an entry in lockfile would still be present). This could be
      problematic if there is no Internet connection, for example.
    - Now all plugins from the lockfile are installed before actually
      executing the first `vim.pack.add()` call in 'init.lua'. And later
      they are only loaded on a rare `vim.pack.add()` call.

  ---

  Synchronizing lockfile on its every read makes it work more robustly
  if other `vim.pack` functions are called without any `vim.pack.add()`.

  ---

  Performance for a regular startup (good lockfile, everything is
  installed) is not affected and usually even increased. The bottleneck
  in this area is figuring out which plugins need to be installed.

  Previously the check was done by `vim.uv.fs_stat()` for every plugin
  in `vim.pack.add()`. Now it is replaced with a single `vim.fs.dir()`
  traversal during lockfile sync while later using lockfile data to
  figure out if plugin needs to be installed.

  The single `vim.fs.dir` approach scales better than `vim.uv.fs_stat`,
  but might be less performant if there are many plugins that will be
  not loaded via `vim.pack.add()` during startup.

  Rough estimate of how long the same steps (read lockfile and normalize
  plugin array) take with a single `vim.pack.add()` filled with 43
  plugins benchmarking:
  - Before commit: ~700 ms
  - After commit:  ~550 ms
2025-11-17 12:47:29 +02:00
Evgeni Chasnovski
c3ac329c7a fix(pack)!: ensure plugin is fully absent if not fully installed
Problem: Currently it is possible to have plugin in a "partial install"
  state when `git clone` was successfull but `git checkout` was not.
  This was done to not checkout default branch by default in these
  situations (for security reasons).

  The problem is that it adds complexity when both dealing with lockfile
  (plugin's `rev` might be `nil`) and in how `src` and `version` are
  treated (wrong `src` - no plugin on disk; wrong `version` - "partial"
  plugin on disk).

Solution: Treat plugin as "installed" if both `git clone` and
  `git checkout` are successful, while ensuring that not installed
  plugins are not on disk and in lockfile.

  This also means that if in 'init.lua' there is a `vim.pack.add()` with
  bad `version`, for first install there will be an informative error
  about it BUT next session will also try to install it. The solution is
  the same - adjust `version` beforehand.
2025-11-17 12:47:29 +02:00
Evgeni Chasnovski
9e2599df05 fix(pack)!: adjust install confirm (no error on "No", show names)
Problem: Installation confirmation has several usability issues:
    - Choosing "No" results in a `vim.pack.add()` error. This was by
      design to ensure that all later code that *might* reference
      presumably installed plugin will not get executed. However, this
      is often too restrictive since there might be no such code (like
      if plugin's effects are automated in its 'plugin/' directory).
      Instead the potential code using not installed plugin will throw
      an error.

      No error on "No" will also be useful for planned lockfile repair.

    - List of soon-to-be-installed plugins doesn't mention plugin names.
      This might be confusing if plugins are installed under different
      name.

Solution: Silently drop installation step if user chose "No" and show
  plugin names in confirmation text (together with their pretty aligned
  sources).
2025-11-17 12:46:22 +02:00
Justin M. Keyes
1f9d9cb2e5 fix(vim.fs): abspath(".") returns "/…/." #36583 2025-11-16 22:36:03 -08:00
Cameron Ring
f11f8546e7 fix(vim.fs): root() should always return absolute path #36466 2025-11-16 21:41:26 -08:00
tao
6e2b514813 fix(system): handle SIGINT in --headless mode #36557
Problem:
When running with `--headless --listen ./hello`, pressing Ctrl-C
doesn’t log anything and doesn’t clean up the socket file.

Solution:
handle SIGINT like SIGTERM.
2025-11-16 18:44:30 -08:00