Problem: parse_cmdline() sets eap->cmdlinep to address of local parameter,
causing invalid memory access when expand_filename() tries to modify it.
This leads to crashes when typing '%' in user commands with preview=true
and complete=file.
Solution: Change parse_cmdline() signature to accept char **cmdline,
allowing cmdlinep to point to caller's variable for safe reallocation.
Problem:
During preview, the `input` still prompts the user to enter something
that won't be used later, which could be a bit confusing.
e.g., `:s/a/\=input("")`.
Solution:
Make the input() return early during 'inccommand' preview.
Problem: Temporary cmdline config is saved to be restored later.
Solution: Close the cmdline window so that it is recreated with the appropriate config.
Problem: Ctrl-G/Ctrl-T does not ignore the end search delimiter
(irisjae)
Solution: Check if the pattern ends with a search delimiter and ignore
it, unless it is part of the pattern.
fixes: vim/vim#17895closes: vim/vim#17933c03990d30f
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: No way to skip install confirmation in `add()`. Having install
confirmation by default is a more secure design. However, users are
usually aware of the fact that plugin will be installed and there is
currently no way to skip confirmation.
Plus it can introduce inconvenience on the clean config initialization
if it is modularized with many `vim.pack.add()` calls (leads to
confirming installation many times in a row).
Solution: Add `opts.confirm` option that can skip install confirmation.
Problem: No way to have full control over how plugin is loaded.
Although `:packadd!` has small side effects (only adds plugin
directory to 'runtimepath'; and maybe its 'after/' subdirectory), it
still has side effects. For example, 'plugin/' directories are still
loaded during startup (as part of `:h load-plugins`).
Solution: Allow function `opts.load` that has full control over how
plugin is loaded.
Problem: the `load=true` in `vim.pack.add()` means that `:packadd` is
executed even during startup. This leads to force source of 'plugin/',
which breaks the intended loading order (`:h load-plugins`) and
results into sourcing them twice. This also makes it ignore
`--noplugin` argument.
Using `:packadd!` during startup is more appropriate, while `:packadd`
afterwards is still more favorable to actually force 'plugin/' source
(as there is no pre-defined mechanism that will load them later).
Solution: have `load=false` default during startup, `true` - afterwards.
Problem: completion: incsearch highlight might be lost after search
completion (Hirohito Higashi)
Solution: Restore incsearch highlight after dismissing pum with Ctrl-E
(Girish Palya)
related: vim/vim#17870closes: vim/vim#1789104c9e78cd3
This change actually isn't needed as Nvim doesn't call update_screen()
to redraw pum, but it doesn't hurt either.
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: tests: Test_search_wildmenu_iminsert() depends on help file
(after 9.1.1594).
Solution: Set buffer text using setline() instead of loading help file.
Add a test for another bug fixed by 9.1.1594 (zeertzjq).
related: vim/vim#17870closes: vim/vim#17922615ad4ced1
- Add delimiter between function signature and documentation, matching hover formatting
- Show title only if there are multiple clients or multiple signatures
- Avoid duplicating the title inside the window if it's already shown in the border
Problem: make_floating_popup_options only shows when opts.border is explicitly set, ignoring global winborder setting
Solution: check both opts.border and vim.o.winborder when determining whether to show title
The cursor movement autocommand can not detect when the final tabstop $0
is directly adjacent to another tabstop, which prevents ending the
snippet session. The fix is an early return when jumping.
Problem:
Previously, 'null' value in LSP responses were decoded as 'nil'.
This caused ambiguity for fields typed as '? | null' and led to
loss of explicit 'null' values, particularly in 'data' parameters.
Solution:
Decode all JSON 'null' values as 'vim.NIL' and adjust handling
where needed. This better aligns with the LSP specification,
where 'null' and absent fields are distinct, and 'null' should
not be used to represent missing values.
This also enables proper validation of response messages to
ensure that exactly one of 'result' or 'error' is present, as
required by the JSON-RPC specification.
Problem:
Not easy for a user to tell ":restart" to "run this command(s) after restarting".
Solution:
All ":restart" args following the optional +cmd arg are treated as a big cmdline that is passed as a "-c" CLI arg when restarting nvim.
Problem: Using `addr` without `range` in nvim_create_user_command gives
"No range allowed" error, inconsistent with `:command -addr` behavior.
Solution: Set EX_RANGE flag when `addr` option is specified to match
`:command` behavior.
This workarounds a bug likely in nvim__get_runtime, and fixes#35124
Though I'd argue it is more correct anyway as the point of
vim.SUBMODULE lazy loading is "only pay for what you use". If no one
has require'vim.diagnostic' yet in LSP or otherwise, there cannot
be any diagostics available and loading the lua module is wasteful.
Problem: Visual block insert on a single line incorrectly triggers two
on_lines callbacks - one for the correct line (0-indexed) and another
for a non-existent additional line.
Solution: Only call changed_lines() in block_insert() when additional
lines beyond the first were actually modified (start.lnum < end.lnum).
Problem:
It's relatively easy to mispress key `a` to (a)llow arbitrary execution
of 'exrc' files. #35050
Solution:
- For exrc files (not directories), remove "allow" menu item.
Require the user to "view" and then explicitly `:trust` the file.
Problem:
diagnostic extmark used for positioning continues to exist after
deleting a range containing it, so it's possible to jump to a
next/previous diagnositc, which isn't visible in any way, including not
being shown via `open_float`.
Solution:
enable `invalidate` flag when setting an extmark to be able to filter
out diagnostics based on `invalid` flag when looking for next/previous
diagnostic to jump to.
When right_gravity is set to true for deactivating tabstop expansion we
have to set end_right_gravity to false to avoid expanding the tabstop
region on the right side. Vice versa for activating tabstop expansion
again.
Problem:
Diagnostic positions are not being updated after text changes, which
means `vim.diagnostic.open_float` and `vim.diagnostic.jump` will work
with outdated positions when text is changed until diagnostics are
updated again (if ever).
Solution:
Create extmarks in `vim.diagnostic.set` and use their positions for
`vim.diagnostic.open_float` and `next_diagnostic` (used by
`vim.diagnostic.jump`, `vim.diagnostic.get_next` and
`vim.diagnostic.get_prev`).
Problem:
":restart" always executes ":qall" to exit the server.
Solution:
Support ":restart +cmd" so the user can control the command
used to exit the server.
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Problem: After filtering out all elements, ArrayIter:last still returns a stale element.
Solution: Add check for self._head == self._tail and return nil early.
Fix#34696
Problem: Routing based on message kinds can be perceived as unpredictable.
Solution: Implement phase 1 of #34281, always showing the full message
in a window dismissed on any user input when it does not fit
in the 'cmdheight'. Also show spill "[+n]" indicator if needed.
Problem: unlike win_close, win_close_othertab could be used to close the
autocommand window from a different tabpage. This causes aucmd_restbuf to close
the wrong window, potentially causing a crash.
Solution: disallow closing it. Also replace a deprecated use of exc_exec in the
test file.
Fixes#21409.
Problem: no check for nvim_open_win opening a new floating window into a closing
buffer, which can lead to crashes.
Solution: call check_split_disallowed; opening a new float semantically splits
from a window, so the same problems as regular splits apply. Also restore the
error if switch_win_noblock in win_set_buf fails (may not be possible to hit
this, but win_set_buf can silently succeed there since #31595).
As the lock check applies to curbuf (not the target buffer) this may feel a bit
restrictive, though this isn't different to how things like ":split" or
nvim_open_win with "split = true" works when targeting a different buffer. Only
checking the target buffer's lock will cause issues if win_set_buf doesn't end
up in the target buffer for whatever reason.
Maybe we could consider checking the lock of the buffer after win_set_buf and
close the window if it's locked (maybe a bit fiddly, especially as closing a
window can fail...), or make the open + switch operation more atomic, like how
Vim does for its popup windows..?
It also used to be the case that win_set_buf would set an error if autocommands
sent us to a different buffer than what was requested, but #31595 appears to
have also changed that... I haven't touched that here.
Problem: can't accurately know if close_buffer directly (e.g: not via autocmds)
decremented b_nwindows. This can cause crashes if win_close_othertab decides to
keep the window after calling close_buffer (if it did not free the buffer), as
b_nwindows may remain out-of-sync.
Solution: change the return value of close_buffer to accurately depict whether
it decremented b_nwindows. Check it in win_close_othertab to avoid a crash.
Similar issues may exist in other places that call close_buffer, but I've not
addressed those here (not to mention only one other place even checks its return
value...)
Problem: TabClosed is fired after close_buffer is called (after b_nwindows is
decremented) and after the tab page is removed from the list, but before it's
freed. This causes inconsistencies such as the removed tabpage having a valid
handle and functions like nvim_tabpage_get_number returning nonsense.
Solution: fire it after free_tabpage. Try to maintain the Nvim-specific
behaviour of setting `<amatch>` to the old tab page number, and the
(undocumented) behaviour of setting `<abuf>` to the buffer it was showing
(close_buffer sets w_buffer to NULL if it was freed, so it should be OK pass it
to apply_autocmds_group, similar to before).