Problem: A vim.ui_attach() callback that redraws to show a 'verbose'
regex message during 'incsearch' results in recusive redrawing.
Solution: Check that curwin was redrawn instead of just any window when
determining if 'incsearch' highlighting was cleared.
(cherry picked from commit 61fb88992d)
fix(ui2): ensure msg window is visible after closing tab
Problem: After closing a tabpage while the msg window is showing a
message, it is hidden while the msg window still contains a
message.
Solution: Unhide the msg window after entering a tabpage and it still
contains a message.
(cherry picked from commit 607fcfb37a)
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
Co-authored-by: Linykq <yukunlin590@gmail.com>
Problem: When closing floating windows to close a tabpage, if the current
buffer will unload, buffers contained in those floating windows
will too (unexpectedly).
Solution: Don't pass along "free_buf" argument; check 'bufhidden' for
the buffer in the to be closed float.
(cherry picked from commit 5b0ad4a060)
Co-authored-by: luukvbaal <luukvbaal@gmail.com>
Problem:
In the default 'titlestring', if the containing directory is the CWD, it renders as "."
Solution:
Add `:p` to the titlestring.
(cherry picked from commit e68e769352)
Problem: Invalid check for non-typed key to dismiss expanded cmdline.
Unable to delay the timer that removes a message from the msg
window.
Solution: Check for empty string instead of nil to determine whether a
key is typed.
Restart the timer if it expires while the user is in the msg
window. Allow entering the msg window with a mouse click.
(cherry picked from commit faa7c15b5a)
Problem:
win_line() falls into infinite loop when a diff window has top filler
above its first visible buffer line, that first visible buffer line is a
closed fold, and the folded line uses normal non-empty foldtext.
Solution:
Allow flushing pending diff filler rows even when the underlying buffer
line is folded with foldtext.
AI-assisted: Codex
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
(cherry picked from commit f2cc0a249d)
Since Nvim uses a compositor, redrawing windows won't lead to flicker in
the popup menu, so the pum_visible() checks in move.c can be removed.
(cherry picked from commit 724fccd46f)
Problem: - Paging keys in the dialog window consume input when the user
may not expect it. The dismissable title hint intended to
mitigate that results in having to press Escape twice to
abandon the prompt.
- Mimicked "msgsep" float border is taking up unnecessary
space when window takes up the entire screen.
Solution: - Use (conventional, albeit less convenient) keys intended
for scrolling to page the dialog window:
<(Mousewheel/Page)Up/Down>, <Home/End>.
- Only set the float top border when separation is actually
necessary, i.e. window does not reach the first row.
(cherry picked from commit f0a8e6f337)
Replace the busted-based Lua test runner with a repo-local harness.
The new harness runs spec files directly under `nvim -ll`, ships its own
reporter and lightweight `luassert` shim, and keeps the helper/preload
flow used by the functional and unit test suites.
Keep the file boundary model shallow and busted-like by restoring `_G`,
`package.loaded`, `package.preload`, `arg`, and the process environment
between files, without carrying extra reset APIs or custom assertion
machinery.
Update the build and test entrypoints to use the new runner, add
black-box coverage for the harness itself, and drop the bundled
busted/luacheck dependency path.
AI-assisted: Codex
(cherry picked from commit 55f9c2136e)
Problem: Attempting to emit cmdline_block event with NULL cmdbuff after
<C-\><C-N> in Ex-mode.
Solution: Don't emit cmdline_block event when cmdbuff is NULL.
(cherry picked from commit f0f9620b38)
Problem: win_linetabsize() includes wrap overhead from 'linebreak'
based on current window width, but the result sizes the window,
causing a feedback loop.
Solution: Temporarily set w_view_width to Columns before measuring.
(cherry picked from commit fcdb148437)
Problem: When the 'ruler' is in the last line of the screen, it takes
local highlight definitions of the current window, tripping an
assert (since c1648cf8).
Solution: Don't use window-local highlight definitions when the ruler is
not part of a statusline.
Co-authored-by: glepnir <glephunter@gmail.com>
(cherry picked from commit b35a2e58e9)
Problem: pum_col goes negative when item width + border exceeds screen.
Solution: account for border_width in pum_compute_horizontal_placement()
instead of adjusting pum_col after the fact
(cherry picked from commit 8603fc9180)
Problem: When emitting a msg_show event with the "empty" kind,
there may still be messages waiting to be emitted, which
are then dropped as a result of recursion protection.
Solution: Flush messages before emitting "empty" message show.
(cherry picked from commit 7fff91359e)
Problem: 'inccommand' preview is not executed after setcmdline(),
and as a result cmdline_show event is emitted when redrawing
is not allowed (5b6477be).
Solution: Call command_line_changed() when ccline.cmdbuff_replaced is
set (by setcmdline()).
(cherry picked from commit 1354787029)
Problem: When messages are appended to an already expanded cmdline,
the spilled lines indicator is not updated.
Solution: Remove early return for updating virtual text while cmdline is
expanded, guard updating "msg" virt_text at callsite instead.
(cherry picked from commit 2663f51890)
fix(ui2): flicker when entering pager from expanded cmdline #38639
Problem: 'showcmd' causes flickering when pressing "g<" to enter the
pager when the cmdline is expanded for messages.
Initial keypress for an incomplete mapping is not giving 'showcmd'
feedback while cmdline is expanded for messages (which is only
dismissed upon the vim.on_key callback after 'timeoutlen').
Solution: Delay dismissing expanded cmdline when vim.on_key() callback
receives "g".
Place 'showcmd' "last" virtual text during expanded cmdline.
(cherry picked from commit 75e5e37942)
Co-authored-by: luukvbaal <luukvbaal@gmail.com>
Problem: When 'ruler' is in last line of the screen and the current
floating window is closed, the ruler is not cleared.
Solution: When closing the current floating window, redraw the cmdline
if that contained, and will no longer contain the 'ruler'.
(cherry picked from commit cd2a27507a)
Problem: Cmdline is not redrawn after an empty message clears it.
Remembered last drawn cursor position may be outdated but
equal to the current cmdline content with UI2.
Solution: Ensure cmdline is redrawn after an empty message clears it.
Compare wanted cursor position with actual cursor position.
(cherry picked from commit 1685ced335)
Problem:
- Progress-events are filtered by "source". But "source" is not required by nvim_echo.
- Without "++nested" (force=false), nvim_echo in an event-handler does not trigger Progress events.
- vim.health does not declare a "source".
Solution:
- Make source mandatory for progress-messages
- Enable ++nested (force=true) by default when firing Progress event.
- Set "source" in vim.health module.
Problem:
When running nvim in headless mode with `cmdheight=0`, an extra newline
is prepended to output (eg. `nvim --clean --cmd 'set cmdheight=0'
--headless -c 'echo 1 | q' ` prints `\n1` instead of `1`), because
`!ui_has(kUIMessages)` is always true in headless mode, causing `p_ch ==
0` in `msg_start()` to unconditionally trigger `msg_putchar('\n')` which
writes a newline to stdout.
Solution:
When in headless printf mode with `p_ch == 0` and no prior output on the
current line, call `msg_puts_display("\n", ...)` directly instead of
`msg_putchar('\n')`, so the grid is still updated for correct screen
positioning but no newline is written to stdout.
Problem:
Currently, there's no way to distinguish progress messages coming from
different sources. Nor can Progress event be easily filtered based on
source.
Solution:
- Add "source" field to nvim_echo-opts.
- The Progress event pattern is now defined by the "source" field.
- Include the "title" as ev.data.
- Unrelated change: set force=false to disable nesting.
fix(ui2): prevent <CR> from focusing pager in insert/terminal mode
Problem: <CR> in insert/terminal mode can focus pager unexpectedly.
Solution: Don't enter the pager when <CR> is pressed during expanded
cmdline in insert/terminal mode.
Problem: When entering the cmdline below expanded messages, those
messages are moved to the dialog window. The dialog window
supports paging but that is unexpected in this situation where
it just serves to keep (some of, exactly those that were
visible before the cmdline was entered) the messages visible.
Wrong highlight group for dialog "more" message.
Solution: Don't create the `vim.on_key()` dialog pager callback after
entering the cmdline below expanded messages.
Use the MsgMore highlight group for the paging hint title.
Problem:
Currently we are using
if 1 item then
{title}: {percent}%
else
Progress: {AVG}%({N})
dropping {title} and Progress text saves up space in statusline plus makes the format consistent, less jumping around.
Solution:
Use `{AVG}%({N})` for all cases.
Problem: - With expanded messages exceeding cfg.msg.cmd.height, entering
the cmdline scrolls to the bottom and expands to the full "cmd"
buffer text height.
- Cursor in the pager is not always at the last message and at
the bottom of the window when appending to the pager.
- unreliable test: messages2_spec: "closed msg window timer removes
empty lines".
Solution: - Achieve separation of the cmdline and message text by moving
messages to the dialog window when entering the cmdline below
expanded messages.
- Set cursor to start of the first message only when first
entering the pager. Use `norm! zb` to position last message
at the bottom of the window (which shouldn't crash anymore
since 911337eb).
- Increase cfg.msg.msg.timeout used in the test file.
Problem:
Currently same progress stat get's displayed on statusline of all
windows. This is repeatitive and noisy.
Solultion:
Only display progress-status on the focused window
Problem:
Currently, when multiple progress are on going we show it as Progress:
{N} items {percent}% format. It can be simplified sinnce items doesn't
really add enough value for the valuable space it takes in statusline
Solution:
Change format to Progress: {percent}%({N})
Problem:
- Window height is set dynamically to match the text height,
making it difficult for the user to use a different height.
- Cmdwin is closed to enter the pager but still taken into
account for the pager position, and not restored when
the pager is closed.
- Dialog pager handler may unnecessarily consume <Esc>.
Solution:
- Add maximum height config fields for each of the UI2 windows,
where a number smaller than one is a fraction of 'lines',
absolute height otherwise (i.e. `cfg.msg.pager.height = 0.5`).
- If the cmdwin will be closed to enter the pager, don't try
to position the pager above it. Re-enter the cmdwin when the
pager is closed.
- Only add vim.on_key() handler for the dialog paging is actually
possible.
Problem:
Default statusline doesn't show progress status.
Solution:
- Provide `vim.ui.progress_status()`.
- Include it in the default 'statusline'.
How it works:
Status text summarizes "running" progress messages.
- If none: returns empty string
- If one running item: "title: percent%"
- If multiple running items: "Progress: N items avg-percent%"
Problem:
Mouse popup menus (right-click context menus) do not respect the
'pumborder' option and could overflow screen boundaries when borders
were enabled near the edge.
Solution:
- Remove the mouse menu exclusion from border rendering.
- Add boundary check to shift menu left when border would exceed screen
width, ensuring complete visibility of menu content and borders.
Problem: Entering the pager is scheduled to avoid errors while in the
cmdwin. Meanwhile the current window is used as a condition to
detect an active pager.
Solution: Keep track of when the user is in the pager (or entered the
cmdwin while the pager was open).
Problem:
`nvim_echo(…, {id=…})` accepts user-defined id as a string or integer.
Generated ids are always higher than last highest msg-id used. Thus
plugins may accidentally advance the integer id "address space", which,
at minimum, could lead to confusion when troubleshooting, or in the
worst case, could overflow or "exhaust" the id address space.
There's no use-case for it, and it could be the mildly confusing, so we
should just disallow it.
Solution:
Disallow *integer* user-defined message-id.
Only allow *string* user-defined message-id.
vim-patch:9.2.0174: diff: inline word-diffs can be fragmented
Problem: When using 'diffopt=inline:word', lines were excessively
fragmented with punctuation creating separate highlight
blocks, making it harder to read the diffs.
Solution: Added 'diff_refine_inline_word_highlight()' to merge
adjacent diff blocks that are separated by small gaps of
non-word characters (up to 5 bytes by default) (HarshK97).
When using inline:word diff mode, adjacent changed words separated by
punctuation or whitespace are now merged into a single highlight block
if the gap between them contains fewer than 5 non-word characters.
This creates more readable diffs and closely matches GitHub's own diff
display.
closes: vim/vim#1909842c6686c78
Problem:
No way to disable progress messages in cmdline message area. If
a third-party plugin handles Progress events + messages, the user may
not want the "redundant" progress displayed in the cmdline message area.
Solution:
Support "progress:c" entry in 'messageopts' option.
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.