408 Commits

Author SHA1 Message Date
Olivia Kinnear
b62c1049c0 feat(pack): :packupdate, :packdel commands #39693
Define `:packupdate` and `:packdel` as separate commands instead of a
unified `:pack {subcommand}` because the semantics between the two
commands vary differently enough that it doesn't make sense to combine
them. Additionally, `:pack! update/del` looks bad.
2026-05-16 05:15:05 -04:00
Justin M. Keyes
d788dd2811 refactor(excmd): pass fargs to Lua for builtin cmds #39528
Problem:
The fallback that tokenizes `eap->arg` by unescaped whitespace (when the
parser doesn't pre-split via `EX_EXPAND` etc.) lives in `nlua_do_ucmd`,
so only user-command callbacks got `eap.fargs`. Builtin commands routed
through `nlua_call_excmd` have to re-parse the args themselves
(e.g. `M.ex_lsp`).

Solution:
- Move the tokenization into `nlua_push_eap` so every Lua handler sees
  `eap.fargs`. Keep only the `EX_NOSPC` override in `nlua_do_ucmd` (the
  `nargs=1`/`?` case which is genuinely user-command-specific).
- Drop the re-parse in `M.ex_lsp`.
2026-05-02 10:46:23 -04:00
Yochem van Rosmalen
84ae70c172 fix(help): fix CTRL character issue for :help {subject} #39537
Problem:
The argument to `:help` is normalized to fit the general tag format.
I.e. i^U-default, iCTRL-U-default and i_CTRL_U-default should all point
to the i_CTRL_U-default tag. Our normalization adds an underscore around
the CTRL keycode, e.g. iCTRL-GCTRL-J becomes i_CTRL-G_CTRL-J. That's not
necessary if the following part starts with a dash, like the case of
iCTRL-U-default.

Solution:
Do not insert an underscore if the following character is a dash/minus
(-).
2026-05-01 06:28:16 -04:00
Justin M. Keyes
18d7dd485b feat(ui): use vim.ui.select for :oldfiles, :recover
Problem:
followup to 55ceb314ca #39478
`:oldfiles` and swapfile `:recover` do not delegate to `vim.ui.select`.

Solution:
- Delegate to `vim.ui.select`.
- Fix a long-standing `recover_names` bug where `concat_fnames(dir_name,
  files[i], true)` produced malformed `<dir>//<dir>/<file>` paths (also
  fixes `swapfilelist()`).
2026-04-30 17:44:31 +02:00
luukvbaal
62db5bebdd fix(messages): message kind for :recover and swapfile attention #39444
Problem:  No message kind and multiple events for :recover and
          (non-prompt) swapfile attention messages.
Solution: Assign these the "list_cmd" and "wmsg" kind.
2026-04-28 10:05:06 -04:00
tao
f130922744 fix(path): normalize path slashes on Windows #37729
Problem:
On Windows, path separators may become inconsistent for various reasons,
which makes normalization quite painful.

Solution:
Normalize paths to `/` at the entry boundaries and always use it
internally, converting back only in rare cases where `\` is really
needed (e.g. cmd.exe/bat scripts?).

This is the first commit in a series of incremental steps.

Note:
* some funcs won't respect shellslash. e.g. `expand/fnamemodify`
* some funcs still respect shellslash, but will be updated in a follow
  PR. e.g. `ex_pwd/f_chdir/f_getcwd`
* uv's built-in funcs always return `\`. e.g. `uv.cwd/uv.exepath`

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-04-24 13:20:25 -04:00
Justin M. Keyes
5c88492a13 fix(trust): always use "/" slashes in filepaths #39355
Problem:
We should not use "\" (backslashes) except where absolutely required.
See references in https://github.com/neovim/neovim/pull/37729

Solution:
There is no reason to use "\" slashes in the trust db, so don't.
2026-04-24 07:37:21 -04:00
Olivia Kinnear
645a588aa6 feat(excmd): add :uptime command #39331
Problem
Nvim marks its v:starttime, but there is no user-friendly way to get Nvim's uptime.

Solution
Add :uptime (based loosely on uptime(1)).
2026-04-23 17:11:59 -04:00
Justin M. Keyes
c42aea3d37 refactor(test): deduplicate trust tests #39354 2026-04-23 16:44:21 -04:00
Barrett Ruth
0a8218a2b4 fix(trust): hash unchanged empty buffers as empty files #39027
Problem:
`vim.secure.trust()` hashes an unchanged empty buffer as
a newline, so trusting an empty file by buffer never works.

Solution:
Hash unchanged empty-buffers `''` so buffer-based
trust matches the on-disk empty file.
2026-04-23 15:01:37 -04:00
Justin M. Keyes
82198d0a66 ci: drop cirrus #39321
Problem:
cirrus will shutdown soon, and we are running out of minutes anyway,
which causes ci failures.

Solution:
Drop cirrus config.
2026-04-22 18:25:07 -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
bfredl
fe60268258 Merge pull request #39076 from bfredl/zig0.16
IT IS HAPPENING: Zig 0.16
2026-04-21 20:09:57 +02:00
zeertzjq
ac8459a09c fix(substitute): don't crash with very large count (#39272) 2026-04-21 11:38:15 +00:00
bfredl
52693e7af3 fix(build): more changes to make zig 0.16.0 work 2026-04-21 12:46:01 +02:00
Justin M. Keyes
4ceca862fc refactor(test): drop deprecated exc_exec #39242 2026-04-20 14:16:41 -04:00
Justin M. Keyes
a38451be40 fix(excmd): nlua_call_excmd require() failure is a "lua_error"
Although `nlua_call_excmd` is semantically for implementing Ex-commands,
the `require()` should never fail, so that's a "Lua error".

But if the call itself fails (the later `semsg` call), that's an "Ex
cmd" error.
2026-04-20 02:31:09 +02:00
Justin M. Keyes
6701b45331 refactor(vimfn): full-Lua impl of vim.fn.environ() 2026-04-18 16:57:37 +02:00
Olivia Kinnear
8715877417 feat(ex): add :log command 2026-04-10 11:08:26 -05:00
zeertzjq
9c5fba5df0 fix(messages): truncate warning messages only in display (#38901)
For now, add a private "_truncate" flag to nvim_echo, using a truncation
method similar to showmode().
2026-04-09 04:11:32 +00:00
zeertzjq
e94e469324 Merge pull request #38669 from SanzharKuandyk/fix-38667
fix(channel): fix Windows console regressions from #37977
2026-04-07 08:48:07 +08:00
Sanzhar Kuandyk
8bb7533639 fix(channel): fix Ctrl-C handling regression in terminal
Problem: Normal Windows builtin-TUI startup spawns the embedded server as DETACHED_PROCESS, which breaks Ctrl-C delivery to :terminal jobs.
Solution: Restores the default behavior once the embedded server has a
console so terminal jobs inherit it.
2026-04-06 11:17:48 +05:00
zeertzjq
9705a1c13b fix(help): show error when using :help! with nothing at cursor #38775
It's possible to still show the old Easter egg, but then the user won't
know about the new feature, so showing E349 is better.
2026-04-05 10:59:22 -04:00
zeertzjq
96d6042689 test(tui_spec): work around flaky test with ASAN (#38619)
FAILED   test/functional/terminal/tui_spec.lua @ 2641: TUI exits immediately when stdin is closed #35744
test/functional/terminal/tui_spec.lua:2648: Failed to match any screen lines.
Expected (anywhere): "%[Process exited 1%]"
Actual:
  |^                                                  |
  |[Process exited 129]{100:                              }|
  |{100:~                                                 }|
  |{100:~                                                 }|
  |{3:[No Name]                                         }|
  |                                                  |
  |{5:-- TERMINAL --}                                    |
2026-03-31 02:26:23 +00:00
Sean Dewar
6617f85b76 vim-patch:9.2.0253: various issues with wrong b_nwindows after closing buffers
Problem:  close_buffer() callers incorrectly handle b_nwindows,
          especially after nasty autocmds, allowing it to go
          out-of-sync.  May lead to buffers that can't be unloaded, or
          buffers that are prematurely freed whilst displayed.
Solution: Modify close_buffer() and review its callers; let them
          decrement b_nwindows if it didn't unload the buffer.  Remove
          some now unneeded workarounds like 8.2.2354, 9.1.0143,
          9.1.0764, which didn't always work (Sean Dewar)

(endless yapping omitted)

related: vim/vim#19728

bf21df1c7b

b_nwindows = 0 change for free_all_mem() was already ported.

Originally Nvim returned true when b_nwindows was decremented before the end was
reached (to better indicate the decrement). That's not needed anymore, so just
return true only at the end, like Vim. (retval isn't used anywhere now anyways)

Set textlock for dict watchers at the end of close_buffer() to prevent them from
switching windows, as that can leave a window with a NULL buffer. (possible
before this PR, but the new assert catches it; added a test)

Despite textlock, things still aren't ideal, as watchers may observe the buffer
as unloaded and hidden (b_nwindows was decremented), yet still in a window...
Likewise, for Nvim, wipe_qf_buffer()'s comment may not be entirely accurate;
autocmds are blocked, but on_detach callbacks (textlocked) and dict watchers may
still run. Might be problematic, but those aren't new issues.

Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
2026-03-29 23:49:24 +01:00
zeertzjq
40a42affa5 test: work around flaky swapfile test with ASAN (#38482)
FAILED   test/functional/ex_cmds/swapfile_preserve_recover_spec.lua @ 118: preserve and (R)ecover with custom 'directory' killing TUI process without :preserve #22096
test/functional/ex_cmds/swapfile_preserve_recover_spec.lua:132: Failed to match any screen lines.
Expected (anywhere): "%[Process exited 1%]"
Actual:
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimDarkGrey2:^sometext                                             }|
  |[Process exited 129]{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:                                 }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimLightGrey4:~                                                    }|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey4, foreground = Screen.colors.NvimDarkGrey2:Xtest_recover_file1 [+]            1,8            All}|
  |{UNEXPECTED background = Screen.colors.NvimLightGrey2, foreground = Screen.colors.NvimDarkGrey2:                                                     }|
  |                                                     |
2026-03-25 13:04:15 +08:00
Justin M. Keyes
e3a1e47bb2 docs: misc 2026-03-20 23:30:09 +01:00
Yi Ming
06befe1e34 feat(defaults): map "grx" to vim.lsp.codelens.run() #37689
Problem
Unlike inlay hints, code lenses are closely related to running commands;
a significant number of code lenses are used to execute a command (such
as running tests). Therefore, it is necessary to provide a default
mapping for them.

Solution
Add a new default mapping "grx" (mnemonic: "eXecute", like "gx").
2026-03-19 13:47:52 -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
Justin M. Keyes
c82f83abb0 fix(ux): drop "Sorry" from messages #38318
Problem:
"Sorry" in a message (1) is noise, and (2) actually reduces the clarity
of the message because the titlecasing of "Sorry" distracts from the
actually important part of the message.

Solution:
Drop "Sorry" from messages.
2026-03-16 07:46:34 -04:00
Justin M. Keyes
16f7440cc7 feat(help): super K (":help!") guesses tag at cursor #36205
Problem:
`K` in help files may fail in some noisy text. Example:

      (`fun(config: vim.lsp.ClientConfig): boolean`)
                            ^cursor

Solution:
- `:help!` (bang, no args) activates DWIM behavior: tries `<cWORD>`,
  then trims punctuation until a valid tag is found.
- Set `keywordprg=:help!` by default.
- Does not affect `CTRL-]`, that is still fully "tags" based.
2026-03-15 19:02:49 -04:00
Justin M. Keyes
ba0baea620 Merge #37830 docs 2026-03-11 13:39:39 -04:00
Justin M. Keyes
a3058abf30 docs: deprecate hit-enter 2026-03-11 18:17:46 +01:00
zeertzjq
0ced216927 test(ex_cmds/mksession_spec): fix possible error log (#38255)
Problem:  :terminal CWD restoration test may lead to an error log if
          after_each() runs before the PTY process calls chdir().
Solution: Wait for some time before wiping the buffer, which can also
          prevent SIGHUP being sent to the parent.
2026-03-11 22:45:32 +08:00
Ayaan
c8693051a8 feat(terminal): surface exit code via virttext + nvim_get_chan_info #37987
Problem:
When a terminal process exits, "[Process Exited]" text is added
to the buffer contents.

Solution:
- Return `exitcode` field from `nvim_get_chan_info`.
- Show it in the default 'statusline'.
- Show exitcode as virtual text in the terminal buffer.
2026-03-10 08:02:50 -04:00
zeertzjq
76db55c137 test(ex_cmds/write_spec): don't create files under test/ (#37963) 2026-02-19 06:30:26 +00:00
zeertzjq
496eca22b3 test: support running functionaltests in parallel by directory (#37918)
Define a CMake target for every subdirectory of test/functional that
contains functional tests, and a functionaltest_parallel target that
depends on all those targets, allowing multiple test runners to run in
parallel.

On CI, use at most 2 parallel test runners, as using more may increase
system load and make tests unstable.
2026-02-18 15:56:50 +08: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
zeertzjq
60730482fe test(testterm): remove useless TermCursor highlight definition (#37827)
TermCursor already has cterm=reverse. Additionally, now that terminal
buffers have a real cursor, the cterm=reverse in TermCursor no longer
shows up in the screen state.
2026-02-12 17:31:12 +08:00
Yochem van Rosmalen
a6252c6683 refactor(help): move escaping logic to Lua #37757
Problem:
Escaping logic for {subject} in ex cmd `:help {subject}` is done in a
messy 200+ lines C function which is hard to maintain and improve.

Solution:
Rewrite in Lua. Use `string.gsub()` instead of looping over characters
to improve clarity and add many more tests to be able to confidently
improve current code later on.
2026-02-10 07:43:17 -05:00
luukvbaal
4260f73e13 fix(messages): unwanted newlines with ext_messages #37733
Problem:  Newlines intended to write messages below the cmdline or to
          mark the start of a new message on message grid are emitted
          through ext_messages. This results in unnecessary newlines for
          a UI that has decoupled its message area from the cmdline.
          msg_col is set directly in some places which is not transmitted
          to msg_show events.
          Various missing message kind for list commands.
          Trailing newlines on various list commands.

Solution: Only emit such newlines without ext_messages enabled.
          Use msg_advance() instead of setting msg_col directly.
          Assign them the "list_cmd" kind.
          Ensure no trailing newline is printed.
2026-02-08 09:47:02 -05:00
Pavel Pisetski
41cac54325 feat(defaults): exclude temp dirs from 'shada' oldfiles #37631
Problem:
Temporary files from /tmp/ and /private/ paths clutter :oldfiles list.
Additionally, the documented Windows default (rA:,rB:) was never applied
due to a missing platform condition.

Solution:
Drop platform-specific shada differences and default to excluding
/tmp/ and /private/ paths.
2026-02-03 08:31:37 -05:00
zeertzjq
19eb75831b ci(test): bump Windows runners to windows-2025 and unskip tests (#37666)
Bumping to windows-2025 seems to fix at least one case of spaces having
wrong attributes in TUI tests, which allow unskipping dozens of tests.
2026-02-03 03:03:41 +08:00
zeertzjq
77162a717a test: wait for uv.pipe_connect() callback (#37640)
Problem:
On Windows, writing to a pipe doesn't work if the pipe isn't connected
yet. This causes an RPC request to a session newly created by connect()
to hang, as it's waiting for a response to a request that never reaches
the server.

Solution:
Wait for uv.pipe_connect() callback to be called when using connect().
2026-02-01 08:14:12 +08:00
zeertzjq
1e6c4ea896 test: add reasons to some skipped tests (#37632) 2026-01-31 00:25:48 +00:00
zeertzjq
1f0dbfea2f fix(tui): log chdir failure properly #37591 2026-01-28 05:44:17 -05:00
Tommy Guo
103ddaf9ae fix(lua): correct line number reporting for options set in coroutines (#37463) 2026-01-21 02:18:33 +00:00
zeertzjq
2d3dc070ce fix(session): window sizes not stored with float windows (#37344) 2026-01-10 14:28:45 +00:00
zeertzjq
49d7f694a8 fix(:ls): check for finished terminal properly (#37303)
Use terminal_running() instead of channel_job_running().
2026-01-09 01:31:00 +00:00
benarcher2691
55a0843b7c feat(editor): :source can run Lua codeblock / ts injection #36799
Problem:
Can't use `:source` to run a Lua codeblock (treesitter injection) in
a help (vimdoc) file.

Solution:
Use treesitter to parse the range and treat it as Lua if detected as
such.
2026-01-07 20:20:53 -05:00