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().
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.
- 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.
Problem:
HLF_8 is used by :intro and :map. And none of the other HLF_x things
use the other Special groups. So we have a darkgray highlight that's
very common, and not easy to read.
Darkgray makes sense for "Conceal", "non-printing chars", etc. But not
for keycodes or similar common elements.
Solution:
Link SpecialKey to Special.
Problem:
- tee was vendored in ceb7eb5230 but
forgot to add it to `build.zig`.
- xxd was vendored in 5bb8734fb6 but
the old XXD_URL is still referenced.
Solution:
- update `build.zig`
- remove XXD_URL
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.)
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.
Problem: Terminal buffers are not refreshed when processing keys that
trigger partial mappings.
Solution: Process due terminal refreshes before redrawing.
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.
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.
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.
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.
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.
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.
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'.
Problem: Changing terminal height immediately after outputting lines
may lead to wrong scrollback.
Solution: Insert pending scrollback lines before the old window height.
Problem:
`vim.json.decode()` could not parse JSONC (JSON with Comments)
extension, which is commonly used in configuration files.
Solution:
Introduce an `skip_comments` option, which is disabled by default. When
enabled, allows JavaScript-style comments within JSON data.
Problem: Crash on failed sockconnect() if a new connection is accepted
while polling for uv events.
Solution: Don't use channel_destroy_early().
Also test "tcp" mode failure properly.
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.
Problem: cterm field in Dict(highlight) is declared as Union(Integer, String)
but it actually expects a Dict(highlight_cterm).
Solution: change cterm type to DictAs(highlight__cterm) and simplify the
handling in dict2hlattrs since type validation and empty array compat are
already handled by api_dict_to_keydict.
In particular, also mention the difference between the regex atom \k and
what Vim considers for a word character.
closes: vim/vim#186889e456e52df
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: Wrong scrollback when passing a buffer with many lines to
nvim_open_term().
Solution: Delete all buffer lines before opening the terminal.
I tried to use buf_clear(), but it crashes inside deleted_lines_mark(),
so I'll just use deleted_lines_buf() for now. The behavior of marks can
be decided later.
Problem: heap use-after-free if OptionSet autocommands from setting a terminal's
&buftype wipe the buffer.
Solution: set b_locked during OptionSet for &buftype.
Problem: Terminal doesn't handle ED 3 (clear scrollback) properly.
Solution: Add vterm callback for sb_clear().
Also fix another problem that scrollback lines may be duplicated when
pushing to scrollback immediately after reducing window height, as can
be seen in the changes to test/functional/terminal/window_spec.lua.
Problem: TermResponse deferred due to blocked autocommands lacks "data" payload.
Also, it may not fire if a new v:termresponse reuses the same string address.
Solution: add it. Use the value of v:termresponse for "data.sequence". Replace
pointer comparisons with a flag.
The removal of "old_termresponse" comparisons is required to pass the test on
the CI, or locally for me when compiled in RelWithDebInfo.
Problem: if buf_free_all autocommands open a terminal, it will remain open after
the buffer is freed.
Solution: close terminals again later, this time while blocking autocommands.
Did consider terminal_open checking stuff like b_locked_split instead, but
that's set during BufHidden, etc., which doesn't mean the buffer's being wiped.
Problem: close_buffer autocmds may switch buffers at the last moment when
closing a window, causing terminal_check_size to prefer the size of a closed
window, or TabClosed to set an old <abuf>.
Solution: use the actual last buffer, similar to what TabClosed did before.
NOTE: If buffer was unloaded/deleted (not wiped), then TabClosed's <abuf> may
not use it. (w_buffer = NULL) Maybe odd, but it's how it worked before anyhow.
Relies on close_buffer reliably setting w_buffer to NULL if freed, otherwise
buf_valid is better. Only concern I see is if the window wasn't in the window
list after closing the buffer (close_buffer won't set it to NULL then), but then
win_close{_othertab} should've returned earlier.
Problem: win_free_mem can free w_buffer (via qf_free_all), which may cause a
heap use-after-free if used as TabClosed's <abuf>. I think TabClosed is also the
only event to conditionally set <abuf> not based on event type.
Solution: use the buffer saved by the bufref. Fall back to curbuf if invalid,
like WinResized/WinScrolled.
NOTE: Not always equivalent if close_buffer autocmds switch buffers at the last
moment; previously <abuf> would be set to that buffer. Fixed in next commit.
https://github.com/neovim/neovim/actions/runs/21765657455/job/62800643599?pr=37758#step:9:159
for an example of qf_free_all being a nuisance.
Problem: terminal's size may not update after one of its windows close.
Solution: call terminal_check_size after closing a window.
Disable test for Windows, as for some reason it only shows a few lines...
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.
Problem: The following strchar functions have incorrect types:
strcharlen() - Currently any. Always returns an integer, including on
error
strcharpart() - The skipcc annotation does not specify that 0 and 1 are
valid. These inputs are required for vimscript usage. The current
return type is any, even though the function returns an empty string
on error
strchars() - The skipcc annotation does not specify that 0 and 1 are
valid
Solution: Update the problem types.
Problem: In eval.lua, setcharsearch() has an incorrect param type,
causing Lua_Ls to display an error when a valid table is passed.
While getcharsearch correctly states that it returns a table, the type
is non-specific about the contents.
Solution: Update eval.lua with the correct types.
vim-patch:9.1.2111: Vim9: no error for elseif/else after else
vim-patch:9.1.2117: unnecessary braces in terminal.c
vim-patch:602e6042a runtime(doc): Reformat example at :h gui-w32-fullscreen
vim-patch:9.1.2125: MS-Windows: DirectX rendering can be improved
vim-patch:9.1.2127: MS-Windows: DirectX renders font too small
vim-patch:1cac0a575 translation(sv): Remove duplicates from [g]vim.desktop.in
vim-patch:91ec2c3ba CI: update FreeBSD runner to 15.0
Problem: With 'autochdir' win_execute() can corrupt the buffer name,
causing :write to use wrong path.
Solution: Save and restore b_fname when 'autochdir' is active
(Ingo Karkat).
This is caused by a bad interaction of the 'autochdir' behavior,
overriding of the current directory via :lchdir, and the temporary
window switching done by win_execute(), manifesting when e.g. a custom
completion inspects other buffers:
1. In the initial state after the :lcd .. we have curbuf->b_fname =
"Xsubdir/file".
2. do_autochdir() is invoked, temporarily undoing the :lcd .., changing
back into the Xsubdir/ subdirectory.
3. win_execute() switches windows, triggering win_enter_ext() →
win_fix_current_dir() → shorten_fnames(TRUE)
4. shorten_fnames() processes *all* buffers
5. shorten_buf_fname() makes the filename relative to the current
(wrong) directory; b_fname becomes "file" instead of "Xsubdir/file"
6. Directory restoration correctly restores working directory via
mch_chdir() (skipping a second do_autochdir() invocation because
apply_acd is FALSE), but b_fname remains corrupted, with the
"Xsubdir/" part missing.
7. expand("%:p") (and commands like :write) continue to use the
corrupted filename, resolving to a wrong path that's missing the
"Xsubdir/" part.
To fix the problem the short filename is saved if its in effect (i.e.
pointed to by curbuf->b_fname) and 'autochdir' happened. It's then
restored in case of a local cwd override. The conditions limit this
workaround to when 'autochdir' is active *and* overridden by a :lchdir.
closes: vim/vim#19343abb4d74033
Co-authored-by: Ingo Karkat <swdev@ingo-karkat.de>
Problem: :tab sbuffer may close old tabpage if BufLeave autocommand
splits window (after 9.1.0143).
Solution: Only close other windows if the buffer will be unloaded
(zeertzjq).
related: neovim/neovim#37749closes: vim/vim#193526da9f757c4
Problem: windows may scroll horizontally upon resize using the old terminal
size, which may be unnecessary and cause the content to be partially out-of-view.
Solution: reset the horizontal scroll after resizing.
Problem:
$NVIM_APPNAME was not respected when searching $XDG_CONFIG_DIRS for
config files. Nvim hardcoded "nvim" when constructing paths like
`$XDG_CONFIG_DIRS/nvim/init.lua`, ignoring the $NVIM_APPNAME environment
variable.
This meant that config files like `$XDG_CONFIG_DIRS/myapp/init.lua` were
not loaded, even though $NVIM_APPNAME was set to "myapp".
Solution:
Use `get_appname()` instead of hardcoded "nvim" for $XDG_CONFIG_DIRS
paths in `do_system_initialization()` and `do_user_initialization()`.
This makes $XDG_CONFIG_DIRS behave consistently with $XDG_CONFIG_HOME,
which already respected $NVIM_APPNAME.
As documented in `runtime/doc/starting.txt` (L1440-L1441):
"In the help wherever `$XDG_CONFIG_…/nvim` is mentioned it is understood
as `$XDG_CONFIG_…/$NVIM_APPNAME`."
See:
43339dee40/runtime/doc/starting.txt (L1440-L1441)
Relates to #37405
Problem:
The E5422 error message was duplicated in two places in main.c, and
hardcoded error strings should be centralized in errors.h for consistency.
Solution:
Add e_conflicting_configs to errors.h and replace both inline error
strings with the centralized constant.
Problem:
`init.lua` files in `$XDG_CONFIG_DIRS` directories were not being sourced during startup, even though the documentation states they should be searched alongside `init.vim`.
See:
e51f5e17e1/runtime/doc/starting.txt (L495-L496)
Solution:
Modify `do_user_initialization()` to search for `init.lua` in each `$XDG_CONFIG_DIRS` directory before falling back to `init.vim`, matching the behavior for `$XDG_CONFIG_HOME`. Also show `E5422` error if both `init.lua` and `init.vim` exist in the same directory.
Fixes#37405
Problem: Exmode is missing cmdline_block events.
Solution: Emit cmdline_block_show/append when executing a cmdline during
exmode. Emit cmdline_block_hide when leaving exmode.