aboutsummaryrefslogtreecommitdiff
path: root/test/functional/ui/float_spec.lua
Commit message (Collapse)AuthorAge
* test: simplify functional test expectationsLewis Russell2026-10-05
| | | | | | | | | | | | Problem: Repeated default fields and field-by-field assertions obscure the values that each functional test is meant to check. Solution: Add eq_partial() to check selected record fields while preserving list length and order. Use local helpers to fill fixed expected defaults where tests need full equality. Keep explicit absence checks and test-specific values at the call sites. AI-assisted
* vim-patch:9.2.1114: Visual selection is not highlighted at the cursor ↵Takumi Katase2026-09-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | position #42105 vim-patch:9.2.1114: Visual selection is not highlighted at the cursor position Problem: In a terminal the character under the cursor is normally not shown as part of the visual selection. Solution: Don't set "noinvcur" in win_line() (Shane Harper). The problem did not occur in the GUI, only in a terminal. The name "noinvcur" ("don't invert the cursor") was misleading: the variable did not affect the cursor, but whether the character under the cursor could be displayed as part of the visual selection. The "noinvcur" handling may have been meant to help during a visual selection when Visual is shown in reverse video and the terminal draws the cursor by inverting the character under it, as otherwise the character under the cursor would not look highlighted like the rest of the selection. But Vim cannot know in general how a terminal draws the cursor, and when either the cursor is not drawn by inverting the character under it or Visual is not shown in reverse video, the handling just left a character of the visual selection unhighlighted. closes: vim/vim#21317 https://github.com/vim/vim/commit/d10aab4ba6602f8f2f2576d2d62ceb63869db6fb Co-authored-by: Shane Harper <shane@shaneharper.net> AI-assisted
* fix(ruler)!: consistent width in last line and statuslineSébastien Hoffmann2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Traditionally, the ruler in the last line is one cell shorter than in the statusline, leaving the last cell of the screen blank. According to code comments, this is in order to prevent unwanted scrolling on "some" (unspecified, but presumably ancient) terminals. Berkeley vi is more specific in its `vs_modeline` function: dumb terminals with hardware scroll, SunOS 4.1.1 and Ultrix 4.2 curses. (n)curses still has a similar limitation in `(w)addstr`, but apparently only for historical reasons. Maintaining the different widths leads to awkward inconsistencies when the ruler is configured with 'rulerformat', except for the special case where it contains a top-level `%=`. Shifting the ruler in the last line to the left would be a solution, but the empty cell at the end doesn't seem to be relevant anymore. Solution: extend the ruler in the last line all the way to the right edge of the screen, just like in the statusline. The exact same amount of place will be available to the rest of the UI as before. BREAKING CHANGE: - the default ruler width is now 18 cells - the last cell of the screen is no longer empty Closes #41076
* fix(floatwin): relative='cursor' may use outdated cursor position #40768tianrking2026-07-28
| | | | | | | | | Problem: Cursor-relative floats can use stale screen coordinates after a cursor move is restored without a redraw. Solution: Validate the current cursor before converting cursor-relative coordinates. Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* Merge #40873 fix(ui): handle combining chunked float titlesJustin M. Keyes2026-07-21
|\
| * fix(ui): handle combining chunked float titlesArtem Krinitsyn2026-07-20
| | | | | | | | | | | | | | | | | | | | | | Problem: The title is combined with window's attributes only if the title is a string (which implies the FloatTitle / FloatFooter highlight groups), but not when the title is text-hl chunks. Solution: Combine specified highlight group with window-local Normal highlight as well.
* | test(harness): migrate away from magic globalsJustin M. Keyes2026-07-21
|/ | | | | | | | | | | | | | | | | | | | | Problem: The magic globals `it`, `describe`, etc., are more trouble than they are worth. - Hooking into `after_each` requires `getfenv()` hacks. - They confuse luals/emmylua, because the top-level `.luarc.json` isn't merged with `test/.luarc.json` (apparently a luals limitation?) - They totally defeat discoverability because the user just has to "know" about the various magic symbols. So they harm DX, which means they serve no purpose at all. Solution: - Expose the test API from `testutil`, so tests can call `t.it()`, `t.describe()`, etc., in the conventional way. - Drop `getfenv()` hacks. - Drop the `setfenv()` injection in `load_chunk`. - Drop `test/_meta.lua`.
* fix(ui): combine float border with window background #40796Artem Krinitsyn2026-07-19
| | | | | | | | | | Problem: Float border highlight groups (FloatBorder, FloatTitle and FloatFooter) fall back to Normal background highlight if no background color set. Solution: Combine border colors with window-local Normal highlight. Fix #38330
* fix(window): yeet grid later when closing float in other tabpage #40758Sean Dewar2026-07-15
| | | | | | | Problem: #40731 may still crash if close_buffer autocmds reinsert the float's grid. Plus removing the grid (and posting win_close) is unneeded if win_close_othertab refuses to close the window later, which is possible. Solution: do the stuff before freeing the window, like win_close.
* fix(window): remove float grid from compositor layers before free #40731phanium2026-07-15
| | | | | | | | | Problem: Closing a floating window from a non-current tab frees its grid without removing it from the compositor's `layers` table, so the next `ui_comp_put_grid()` walks a dangling pointer (UAF). Solution: Call `ui_comp_remove_grid()` (and `ui_call_win_close()` for multigrid UIs) before `win_free_mem()`, matching `win_close()` since PR #21551.
* fix(highlight): keep guisp underline color in float with 'winblend' #40283glepnir2026-06-16
| | | | | | | | | Problem: A colored (guisp) underline showing through a 'winblend' float lost its special color and followed the foreground instead. Solution: In the blend-through case, blend the underline's special color only when the cell below sets sp explicitly; otherwise clear it.
* fix(option): allow empty/blank edges in 'winborder' #40112glepnir2026-06-05
| | | | | | | | | | Problem: The comma form of 'winborder' is split with copy_option_part(), whose skip_to_option_part() eats spaces after a comma, and empty fields are rejected. Solution: Split the comma form literally on ',', keeping empty fields and single-space fields.
* Merge #40057 from luukvbaal/hidenodrawJustin M. Keyes2026-06-02
|\ | | | | perf(redraw): don't redraw hidden windows
| * fix(float): validate conflicts for nvim_win_set_config()Luuk van Baal2026-06-01
| | | | | | | | | | | | | | | | Problem: nvim_win_set_config() does not error on flags not allowed for non-floating windows. `hide` should not be allowed for non-floating windows. Solution: Check that a window is a split when reconfiguring. Error when trying to hide a split window.
* | fix(float): title/footer shows printable control chars #40047glepnir2026-05-30
|/ | | | | | | | | | Problem: Literal tab (or other control char) in a float title/footer is not made printable, so it renders incorrectly instead of as "^I". Solution: Normalize title/footer text for display like 'statusline' tab to "^I", parameterize parse_virt_text() with untab and recompute the width.
* fix(float): :bufdelete in floatwin may change focus #39858glepnir2026-05-21
| | | | | | | | | | Problem: (Followup to 54f22a8f01c0feb27a531b52aedf5cdbd5e51b24.) Deleting another buffer from a floatwin could move focus into the holder window and fire BufEnter for the buffer being deleted. Solution: Use switch_win_noblock() instead of buf_jump_open_win() before recursing into do_buffer_ext().
* fix(excmd): :bufdelete may fail from floating window #39800glepnir2026-05-16
| | | | | | | | | | Problem: with a float focused and the target buf only shown in the last non-float window, do_buffer_ext goes down the buf != curbuf path. close_windows can't touch the last non-float, b_nwindows stays > 0, close_buffer is skipped, returns OK silently. Solution: if a non-float still holds buf after close_windows, jump into it and recurse. Then buf == curbuf and the existing replacement path takes over.
* fix(float): don't unload 'hidden' float buffer with :close! (#39096)luukvbaal2026-04-16
| | | | | | | 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.
* feat(api): use zindex to determine dimmed cursor shape #39054luukvbaal2026-04-14
| | | | | | | | | | | Problem: The cursor shape is changed to indicate when it is behind an unfocused floating window (since a2b92a5e). This behavior cannot be controlled by a floating window that doesn't want to dim the cursor. Solution: Assign a zindex-offset of 50 to the zindex of the current window. To not dim the cursor when creating a floating window on top of the current window one can assign the zindex accordingly.
* fix(api): use standard error messagesJustin M. Keyes2026-03-16
|
* fix(api): improve external window validationSean Dewar2026-03-14
| | | | | | | | | | | | | | | | | 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...
* feat(api): nvim_win_set_config can move split to other tp as floatwinSean Dewar2026-03-14
| | | | | | | Problem: not possible for nvim_win_set_config to convert a split to a floatwin, then move it to another tabpage in one call. Solution: allow it.
* fix(winfloat): last_status when changing split to floatwinSean Dewar2026-03-14
| | | | | | | | | | | | 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.
* fix(api): relax config validation for "win"Sean Dewar2026-03-14
| | | | | | | | | | | | | | | | 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.
* fix(api): don't config split as floatwin relative to itselfSean Dewar2026-03-14
| | | | | | | | | | 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.
* fix(api): win_config_float_tp grid removal, redrawSean Dewar2026-03-14
| | | | | | | | | | | | | | | | | | | | | | | | 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.
* fix(compositor): clear old position with last known dimensions #38229luukvbaal2026-03-11
| | | | | | | | 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>
* fix(api): don't re-apply minimal style if unchanged #38152Sean Dewar2026-03-09
| | | | | | | | | | Problem: nvim_win_set_config with style=minimal re-applies option values even if the new style is unchanged from the old. This may be undesirable after #38122. Solution: don't bother in this case. See https://github.com/neovim/neovim/pull/38122#issuecomment-3996994189. A reversal of https://github.com/neovim/neovim/pull/22865#discussion_r1161598973 so its associated test has been updated.
* fix(api): merge split window config only on successSean Dewar2026-03-08
| | | | | | | | | | | | | | | 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.
* fix(api): return "style" in nvim_win_get_config() #38122Sean Dewar2026-03-03
| | | | | | | | | | 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)
* fix(window): style=minimal window loses local options when switching buffers ↵glepnir2026-03-03
| | | | | | | | | | | #38138 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.
* fix(float): style=minimal leaks into normal windows #25185glepnir2026-02-28
| | | | | | 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.
* fix(float): clamp floating window above cmdline #37899luukvbaal2026-02-16
| | | | | 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'.
* test(float): cursor unobscured by hidden float and in cmdlineSean Dewar2026-02-04
|
* feat(ui): show "empty" cursor behind unfocused floatwin #37624glepnir2026-02-04
| | | | | | | Problem: There is no indication of when cursor is "behind" an unfocused, floating window. Solution: Set underline cursor to indicate when an unfocused floatwin is over the active cursor.
* vim-patch:9.0.0909: error message for layout change does not match action ↵zeertzjq2026-01-17
| | | | | | | | | | | | | | (#37436) Problem: Error message for layout change does not match action. Solution: Pass the command to where the error is given. (closes vim/vim#11573) https://github.com/vim/vim/commit/9fda81515b26ecd3c1e99f95334aaed3f7b6fea3 Thinking about this again, it's actually OK to check split_disallowed in window_layout_locked(), so add the check. Also add missing window_layout_locked() in tabpage_close(). Co-authored-by: Bram Moolenaar <Bram@vim.org>
* fix(window): crash closing split if autocmds close other splits (#37233)zeertzjq2026-01-05
| | | | | Problem: Crash when closing a split window if autocmds close other split windows but there are still floating windows. Solution: Bail out and give the window back its buffer.
* fix(window): crash closing only non-float if autocmds :tabonly (#37218)Sean Dewar2026-01-04
| | | | | | | | | | Problem: null pointer member access when closing the only non-float in the current tab page if autocommands after closing all floats also close all other tab pages. (making it the last window) Solution: check last_window again after closing the floats. Also reduce the scope of "wp"; it would be bugprone to use it before it's later reassigned to the rv of win_free_mem if freed by Buf/WinLeave.
* fix(float): prevent truncation of title that fits exactly #36880skewb1k2025-12-09
| | | | | | | | | | | Problem: The `over_flow` parameter in `grid_draw_bordertext` always added 1 for the '<' character. As a result, titles that fit exactly were still truncated with an unnecessary '<'. Solution: Adjust `over_flow` only when the actual overflow is greater than 0. Fix #36872
* fix(float): tail truncate long title #28387glepnir2025-12-08
| | | | | | | | | Problem: We truncate the title from start, this is somewhat inconsistent with the way vim works. Usually we use < to truncate and keep more trailing characters. Solution: Keep more trailing characters.
* fix(window): don't make hidden/unfocusable previous window current #36142luukvbaal2025-10-11
| | | | Problem: Previous window is made current while it is unfocusable/hidden. Solution: Treat hidden/unfocusable window as an invalid previous window.
* fix: stale lines("w$") after nvim_win_set_height when splitkeep=screen #36056phanium2025-10-11
| | | | | | Problem: when splitkeep=screen, after enlarge float window with nvim_win_set_height, lines("w$") return stale value Solution: update in win_set_inner_size
* fix(float): crash from nasty :fclose autocmds (#36134)Sean Dewar2025-10-11
| | | | | | | | Problem: :fclose may crash Nvim if autocommands close floats prematurely. Alternatively, :fclose may call win_close for windows not in curtab if autocommands change curtab or move windows between tab pages via nvim_win_set_config (may not crash, but is wrong). Solution: check win_valid before calling win_close.
* feat(ui): support grid=0 in nvim_input_mouse #32535fredizzimo2025-09-13
| | | | | | | | | | | | | | | | | Problem: Multigrid UIs have to find out which window to send the input by using the Nvim focus rules, which are not fully documented. Furthermore,`getmousepos()` has several problems when multigrid is enabled, with the main one being that screenrow and screencol are window relative instead of screen relative, due to the fact that the UI don't send any absolute coordinates. Solution: Allow passing 0 as grid to `nvim_input_mouse`, with absolute coordinates, which lets nvim determine the actual window to send the mouse input to. This works as long as nvim is in charge of the window positioning. If the UI repositions or resizes the windows, it can still pass the grid it determines like before.
* fix(floatwin): handle viewport width properly at end of window (#35490)zeertzjq2025-08-27
| | | Also avoid repeated calls of compute_foldcolumn().
* fix(eval): winnrs of unfocusable/hidden windows #35474Sean Dewar2025-08-26
| | | | | | | | | Problem: various functions may return incorrect window numbers for unfocusable or hidden windows. Solution: fix the checks. Make sure current windows in non-current tabpages have a window number. Fixes #35453
* fix(ui): check for cmdline mode properly (#35202)zeertzjq2025-08-07
|
* fix(window): don't store invalid height in window config (#34885)luukvbaal2025-07-11
| | | | | | | Problem: When 'winminheight' is zero and the window height is set to zero, the actual height is clamped whereas the stored config value is not. Reciprocal window configuration through nvim_win_get_config() then results in an error. Solution: Also clamp the stored dimensions in the window config.
* fix(highlight): preserve bg transparency with winblend=100 #34825glepnir2025-07-10
| | | | | | | Problem: When winblend=100 is set on floating windows with transparent background, the desktop background is not visible through the window. Solution: Add special case to preserve transparency (-1) when blend ratio is 100% and background was originally transparent.
* feat(option): custom chars in 'winborder' #33772glepnir2025-07-09
| | | | | Problem: winborder option only supported predefined styles and lacked support for custom border characters. Solution: implement parsing for comma-separated list format that allows specifying 8 individual border characters (topleft, top, topright, right, botright, bottom, botleft, left).