Problem: "win" is allowed in external window configs in some cases. External
window converted to normal float can't move tabpages in one nvim_win_set_config
call. External window can't be turned into a normal split.
Solution: disallow setting "win" for external windows. Allow external window to
move tabpages, which turns it non-external. Allow external window to be turned
into a (non-external) split.
parse_win_config has more validation issues from not considering the window's
existing config enough (not from this PR). For example, zindex can be set for an
existing split if "split"/"vertical" isn't given, despite intending for that to
be an error. Plus the logic is confusing.
It could do with a refactor at some point...
Problem: more cases where it may not be safe to move a window between tabpages.
Solution: check them.
Rather speculative... I haven't spend much time looking, but I didn't find
existing code that sets these locks to skip checking win_valid. (what I did find
called it anyway, like in win_close) Still, I think it's a good precaution for
what future code might do.
If the fact that nvim_win_set_config *actually* moves windows between tabpages
causes unforeseen issues, "faking" it like ":wincmd T" may be an alternative:
split a new window, close the old one, but instead also block autocmds, copy the
old window's config, and give it its handle?
Problem: converting a split to a floatwin may not remove the last statusline
when needed. (e.g: 'ls' is 1)
Solution: call last_status/win_comp_pos in win_new_float, after win_remove.
Also fix float_pos formatting for screen snapshots so it doesn't give a nil
error for external windows.
Not an issue from this PR.
Problem: only possible to move floats between tabpages if relative=win, which
has the restrictive effect of also anchoring it to the target window.
Solution: allow "win" without "relative" or "split"/"vertical". Only assume
missing "win" is 0 if relative=win is given to maintain that behaviour. (or when
configuring a new window)
Also add an error when attempting to change a split into a float that's in
another tabpage, as this isn't actually supported yet. (until the next commit)
Maybe this could do with some bikeshedding. Unclear if "win" should require
"relative" to be given, like with "row"/"col"; this can be annoying though as
specifying "relative" requires other fields to be given too.
Problem: possible to configure a split as a floatwin with relative=win that is
relative to itself.
Solution: fix the check.
Not caused by this PR; just something I noticed when about to fix the validation
logic.
Problem: when nvim_win_set_config moves a floatwin between tabpages, its grid
may remain if temporarily inside another tabpage. Also, things like tablines
aren't redrawn.
Solution: always remove its grid. Set must_redraw so things are redrawn even if
w_redr_type was already set for the old tabpage.
I don't think it's necessary to do anything extra here when removing the grid:
- win_ui_flush calls ui_call_win_hide anyway, and calling it manually ends up
sending two win_hide events.
- ui_comp_remove_grid safely does nothing if the grid doesn't exist.
- w_pos_changed is set by win_config_float later, if that's needed. I think the
pending_comp_index_update set by ui_comp_remove_grid is enough anyway, at
least for making sure win_ui_flush sends win_hide.
Added test fails with the prior approach of checking `parent_tp != curtab`, but
also `win_tp == curtab`. (which is a better, but still flawed alternative)
The added redrawing here also supersedes setting w_hl_needs_update, and also
redraws stuff like the tabline to pass the new test.
- Factor out logic to keep nvim_win_set_config clean.
- Clean up a few things, remove redundant logic, reflow some lines.
- Add some more comments where appropriate.
- Don't consider negative "win", as that's only relevant for splits.
- Add more test coverage.
- Add news.txt entry.
Problem: nvim_win_set_config can't move floating windows to different tab pages.
Solution: allow it.
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Problem: `get_doc` throws error with "attempt to get length of a userdata
value" when `item.documentation` is truthy but not a string (e.g. vim.NIL
from a JSON null).
Solution: Check `type(item.documentation)` before taking its length.
Problem: 'showcmd' buffer is being populated for :norm commands, which
can result in a recursive uv_run() when called from a msg_show
vim.ui_attach callback for a shell message.
Solution: The 'showcmd' buffer is never displayed while executing a
:normal command so prevent unnecessary work, avoiding the crash.
Problem: Statusline component of diagnostics allows only the default
format "sign:count".
Solution: Extend vim.diagnostic.Opts.Status to allow a custom signs
or formatting function that provides the status presentation.
Problem: The floating preview window (e.g. completion info)
has mouse=false, so scroll wheel events pass right through it.
Solution: Set mouse=true on the preview float so users can
scroll its content with the mouse wheel.
Problem: #38169 used compl_used_match to determine the CompleteDone
reason, but this fires too broadly, it also changes the reason to
"accept" when the popup was shown and the user dismissed it with <Esc>
or <Space>, breaking snippet completion with autocomplete.
Solution: Instead of checking compl_used_match in, check whether the pum
was never shown (compl_match_array == NULL) in ins_compl_stop().
When a match was inserted but the pum never displayed,
set the completed word so CompleteDone fires with reason "accept".
This keeps the "discard" reason intact when the user dismisses a visible
pum without confirming.
Problem: nvim_parse_cmd rejects valid commands like `:1` (range-only)
or `aboveleft` (modifier-only).
Solution: allow empty command when range or modifiers exist, and handle
execution using existing range command logic.
If the Nvim session has exited, the nvim_command will fail too.
ERROR test/functional/core/fileio_spec.lua @ 342: tmpdir failure modes
test\functional\testnvim.lua:133: sending request after EOF from Nvim
stack traceback:
test\functional\testnvim.lua:133: in function 'command'
test\functional\testnvim.lua:847: in function 'rmdir'
test/functional/core\fileio_spec.lua:353: in function <test/functional/core\fileio_spec.lua:342>
Problem: Mimicked block mode for cmdline entered while expanded
does not work intuitively for repeated commands yielding
messages exceeding the screen height. The expanded cmdline
resizes and scrolls to bottom/top when appending a message
and entering the cmdline. Also includes the entered command,
as opposed to the UI1 behavior.
Crash when scrolling to bottom of pager due to recursive
uv_run after shell message callback executes `nvim_command()`
with 'showcmd'.
Solution: Still mimic block mode when entering the expanded cmdline,
but when the entered command emits a message open the pager
with the current message content in the expanded cmdline.
Always route typed commands to the pager when it is open.
Use `nvim_buf_set_cursor()` instead of `nvim_command()`.
Problem:
In autocmd examples, using "args" as the event-object name is vague and
may be confused with a user-command.
Solution:
Use "ev" as the conventional event-object name.
Problem:
When `pum_above` is set, the info window uses `anchor=SW`. Updating the
info window height during `CompleteChanged` causes its top edge to shift,
so it no longer aligns with the top of the pum.
Solution:
Use `NW` as the anchor even when `pum_above` is true so the info window
remains aligned with `pum_row`.
Problem:
If NVIM_LOG_FILE, or the default fallback, is inaccessible (e.g.
directory is owned by root), users get confused.
Solution:
Show a warning when $NVIM_LOG_FILE or $XDG_STATE_HOME are inaccessible.
Also fix a latent memory leak: `os_mkdir_recurse` returns a uv error
code (int), but it was stored as `bool`, causing `os_strerror` to
receive an invalid error code and leak memory.
See: https://docs.libuv.org/en/v1.x/errors.html#c.uv_strerror
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Problem:
When stopping a PTY process on Windows, the exit code indicates that the
process is stopped by SIGTERM even when closing all streams is enough to
terminate the process. This is inconsistent with other platforms.
Solution:
Set exit_signal to SIGHUP instead of SIGTERM when using SIGHUP.
Problem:
In aec3d7915c Vim changed prompt-buffers
to respect 'modified' so the termdebug plugin can "control closing the
window". But for most use-cases (REPL, shell, AI "chat", …),
prompt-buffers are in practice always "modified", and no way to "save"
them, so *implicitly* setting 'modified' is noisy and annoying.
Solution:
Don't implicitly set 'modified' when a prompt-buffer is updated.
Plugins/users can still explicitly set 'modified', which will then
trigger the "E37: No write since last change" warning.
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.
Problem: When reconfiguring a float reallocates the grid before the old
area is cleared, artifacts are left on the screen.
Solution: Use the last known compositor dimensions of a grid when
clearing the area covered by the old position.
Co-authored-by: glepnir <glephunter@gmail.com>
Problem:
No completionItem/resolve handler.
Solution:
If completeopt=popup is set, invoke completionItem/resolve when
a completion item is selected. Show resolved documentation in popup next
to the completion menu.
Problem: Since the "[Process exited]" msg is no longer part of buffer
contents, `jobstart`'s reuse of unmodified finished terminal buffers
does not clear the msg.
Solution: Delete the extmark if `term` is already closed.
Problem:
Exit code in :terminal channel test depends on whether the shell or Nvim
TUI in the terminal has registered its SIGHUP handler when jobstop() is
called.
Solution:
Don't use a shell as shells on different systems may handle SIGHUP
differently. Add a screen:expect() to wait for the TUI to start.
Problem:
Under certain circumstances (e.g. gzipped manpages with mandoc),
:Man will not find the correct page because it does not process
multiple extensions correctly.
For example, with a file named strcpy.3p.gz, it will only check the .gz
part to try to check the section.
This leads to some pages being inaccessible because it will return the
page from the wrong section.
Solution:
Loop and try multiple extensions to try to find one which matches
the name of the section.
Also refactor the man.get_path function so that it can be tested.
Problem: Exception error message only prints the first chunk of a
multi-chunk nvim_echo() message.
Solution: Concatenate consecutive message chunks in the exception
message list.
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.
Problem
The logic that clears codelenses beyond the buffer also removes the codelenses on the last line.
Solution
Do not clear the codelens on the last line.
Problem: vim.ui_attach() is unable to display streamed shell output,
and will display it as individual messages.
Unwanted newlines in "shell_ret" message.
Solution: Treat the "shell_*" kinds as non-fast and set msg_show->append
for the streamed stdout/err messages.
Remove leading newline from (translated) message with
ext_messages, remove trailing newline altogether.
Problem:
There is an inconsistency between extmarks/highlights regarding the
`end_col` param.
Solution:
Allow end_col=-1 to mean "end of line" (if strict=false).
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Problem: CompleteDone fires with reason="discard" even when the candidate
text was inserted and left in the buffer, because reason was determined
solely by the terminating keycode (Ctrl-Y).
Solution: Check compl_used_match to detect whether inserted
text remains in the buffer, and set reason="accept" accordingly.
Problem: nvim_win_set_config may raise unnecessary errors when not moving a
split.
Solution: skip checks related to moving when only maybe resizing a split.