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: 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.
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: 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:
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: 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:
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: 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: nvim_win_set_config may merge configs despite failing to configure a
split, and without applying necessary side-effects (like setting style=minimal
options). Plus, autocommands may apply a different config after the merge,
causing side-effects to apply for an outdated config.
Solution: merge configs last, only on success. Include fields only relevant to
splits. Properly set _cmdline_offset for splits.
Maybe better to disallow _cmdline_offset for splits instead, as the pum is
relative to cmdline_row anyway? (I didn't want to change behaviour too much)
Also use expect_unchanged in an unrelated test to quash a warning.
Problem: Expanded cmdline is left open after entering the cmdline again
without entering a command that emits another message (after 301c7065).
Solution: Wait for msg_show to reinstate the vim.on_key() handler.
If there was no message close the expanded cmdline.
Problem: Prompts and message text (in block mode) in the cmdline are
parsed and highlighted as if it is Vimscript.
Entering the cmdline while it is expanded can work more like
it does with UI1, where the press enter prompt is replaced
and previous messages stay on the message grid, while
subsequent messages are placed below it.
Solution: Highlight manually with string parser on lines starting with ':'.
Spoof cmdline block mode when the cmdline is entered while it
is expanded.
Problem: Previous tests for this relied on other events opening the
targets, which are not guaranteed to happen.
Solution: Open target windows when entering a new tabpage.
Problem: Unable to tell whether a msg_show event is emitted as a result
a command typed on the cmdline (UI may want to represent these
differently from other messages).
Solution: Add trigger parameter that is set to "typed_cmd" for
a message emitted due to an interactively typed command.
Possible extensions are mapping/timer/event but it's hard to
imagine a UI distinguishing those so not added here.
Problem: nvim_win_get_config() does not return a window's "style".
Solution: always include it, and document `style=""`.
Always included so it can be used reciprocally with nvim_open_win() or
nvim_win_set_config(). (otherwise the config of a window with kWinStyleUnused
will not unset the kWinStyleMinimal style of another window if passed to
nvim_win_set_config, for example)
Problem: 5943a81 skips saving window options in `buflist_altfpos` for
style=minimal windows, which also prevents the window from restoring its own
options when switching buffers.
Solution: revert the change. In `get_winopts`, don't restore options from the
`WinInfo` of style=minimal windows when reusing values for a different window.
In `win_free`, clear `wi_optset` for minimal windows.
Problem: Unable to configure message targets based on message kind.
Solution: Add cfg.msg.targets mapping message kinds to "cmd/msg/pager".
Check the configured target when writing the message.
cfg.msg = { target = 'cmd', targets = { progress = 'msg', list_cmd = 'pager' } }
will for example use the 'msg' target for progress messages,
immediately open the pager for 'list_cmd' and use the cmdline
for all other message kinds.
Problem: closing a minimal float saves its style-imposed options into
buffer's wininfo, which get picked up by normal windows on :bnext.
Solution: don't save window options to wininfo for style=minimal windows.
Problem: Timer removing a message from the msg buffer does not remove
empty lines if window is closed (col([ui.wins.msg]) fails).
Solution: Use nvim_buf_get_text() to check if line is empty.
Problem: - Unintentionally inserting lines for a replaced multiline
message that also has multiple highlights.
- Scheduled check to see if the expanded cmdline window was
entered makes it difficult to keep track of what happens when
the key pressed to dismiss it results in a message.
- Reading the first line of an error message should be enough
notice for something going wrong.
- "search_cmd" messages should not be shown with 0 'cmdheight'.
- Unable to configure dynamically changed pager height.
- Enabling UI2 doesn't make sense with no UIs attached.
Solution: - Only insert a line for the first chunk after a newline.
- Use getmousepos() to check if the expanded cmdline was
clicked to enter the pager.
entering the pager to serve as a configuration interface.
- Don't expand the cmdline for error messages; user can press g<.
- Don't show "search_cmd" messages with 'cmdheight' set to 0.
- Change 'eventignorewin' to ensure WinEnter is fired when
- Have enable() return early when no UIs are attached.
Problem: Newlines emitted with ext_messages intended to position
the message/prompt on the message grid.
Solution: Don't emit these newlines with ext_messages, followup to 4260f73e.
Problem: after #33036, an error from evaluating 'statusline' clears it and
doesn't draw the statusline. (causing glitchy redraws)
Solution: use the default value instead. If 'stl' is somehow ever empty, still
call redraw_custom_statusline to at least draw an empty statusline.
Ideally our default 'stl' shouldn't itself error too! :-)
Also adjust some prior screen:expect()s to avoid immediate success warnings.
This is a better way to prevent parallel tests from interfering with
each other, as there are many ways files can be created and deleted in
tests, so enforcing different file names is hard.
Using $TMPDIR can also work in most cases, but 'backipskip' etc. have
special defaults for $TMPDIR.
Symlink runtime/, src/, test/ and README.md to Xtest_xdg dir to make
tests more convenient (and symlinking test/ is required for busted).
Also, use README.md instead of test/README.md in the Ex mode inccommand
test, as test/README.md no longer contains 'N' char.
Problem: UIs put ins-completion "scanning" messages one after another,
which are meant to overwrite the previous message.
Solution: Ensure the msg_show "replace_last" parameter is set.
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.
Problem: Implicitly setting message target when 'cmdheight' changes.
Solution: Just use the user configured target. Support "cmd" target
with 'cmdheight' set to 0.
Problem:
When MsgArea highlight is changed, the next message may flash
and disappear because msg_start() renders with stale highlight attributes.
msg_puts_len() uses HL_ATTR(HLF_MSG) to render message text, which
happens before update_screen() calls highlight_changed().
So the message is rendered with outdated attrs.
Solution:
Call highlight_changed() in msg_start().
Problem: Paging keys being consumed without obvious indicator
in the dialog window can be surprising.
Solution: Display a hint with paging keys in the dialog window title
when paging is active. Recognize <Esc> as mapping to stop
paging.
Problem: vim.on_key() called for each message while cmdline is open.
Cursor is on a seemingly random column when pager is entered.
Entering the pager while the cmdline is expanded can be more
convenient than pressing "g<".
Pager window is unnecessarily clamped to half the shell height.
Setting 'laststatus' while pager is open does not adjust its
dimensions.
Solution: Only call vim.on_key() once when dialog window is opened.
Ensure cursor is at the start of the first message when
entering the pager.
Enter the pager window when "<CR>" is pressed while the
cmdline is expanded.
Don't clamp the pager window height.
Set message windows dimensions when 'laststatus' changes.
Problem: Logic determining messages belonging to the last command to
show with "g<" does not flush pending messages. This can
result in clearing the temporary message history before a
message still belonging to the previous command was emitted.
Solution: Flush pending messages when marking the end of messages
belonging to previous command.
Problem: A float whose zindex is below the cmdline can be enlarged and
end up behind the cmdline.
Solution: Clamp height of such windows to not extend beyond 'cmdheight'.
**Problem:** No easy way to stack highlight groups #35806.
**Solution:** Add a way to specify a new statusline chunk with a
highlight group that inherits from previous highlight attributes.
Also applies to tabline, etc.
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: 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: 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.
Problem: "first" parameter added in 912388f5 for grouping printed lines
in a single event is ineffective for the :global command.
Solution: Only set the message kind for the first printed line during a
:global command.