Commit Graph

246 Commits

Author SHA1 Message Date
Justin M. Keyes
680d25e5b3 fix(api): use standard error messages 2026-03-16 14:52:04 +01:00
Sean Dewar
3115e3d0d1 fix(api): improve external window validation
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...
2026-03-14 20:48:32 +00:00
Sean Dewar
094b297a3b feat(api): nvim_win_set_config can move split to other tp as floatwin
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.
2026-03-14 20:48:32 +00:00
Sean Dewar
3325536150 fix(winfloat): last_status when changing split to floatwin
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.
2026-03-14 20:48:32 +00:00
Sean Dewar
7be4ae796f fix(api): relax config validation for "win"
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.
2026-03-14 20:48:31 +00:00
Sean Dewar
ef084b5c22 fix(api): don't config split as floatwin relative to itself
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.
2026-03-14 19:27:20 +00:00
Sean Dewar
c924c2a7b3 fix(api): win_config_float_tp grid removal, redraw
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.
2026-03-14 19:27:20 +00:00
luukvbaal
e1b3ca6629 fix(compositor): clear old position with last known dimensions #38229
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>
2026-03-11 07:38:18 -04:00
Sean Dewar
4362132b10 fix(api): don't re-apply minimal style if unchanged #38152
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.
2026-03-09 14:28:36 -04:00
Sean Dewar
137d5ab01d fix(api): merge split window config only on success
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.
2026-03-08 19:41:33 +00:00
Sean Dewar
1901832f26 fix(api): return "style" in nvim_win_get_config() #38122
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)
2026-03-03 12:17:20 +00:00
glepnir
84d84e9b5b fix(window): style=minimal window loses local options when switching buffers #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.
2026-03-03 11:51:58 +00:00
glepnir
5943a81fe7 fix(float): style=minimal leaks into normal windows #25185
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.
2026-02-28 13:20:56 +00:00
luukvbaal
d131d67e67 fix(float): clamp floating window above cmdline #37899
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'.
2026-02-16 09:33:32 -05:00
Sean Dewar
da7580498a test(float): cursor unobscured by hidden float and in cmdline 2026-02-04 18:55:21 +00:00
glepnir
a2b92a5efb feat(ui): show "empty" cursor behind unfocused floatwin #37624
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.
2026-02-04 10:09:50 -05:00
zeertzjq
e51f5e17e1 vim-patch:9.0.0909: error message for layout change does not match action (#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)

9fda81515b

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>
2026-01-17 10:58:26 +08:00
zeertzjq
df62cb3e69 fix(window): crash closing split if autocmds close other splits (#37233)
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.
2026-01-05 11:17:00 +08:00
Sean Dewar
c14de47f1a fix(window): crash closing only non-float if autocmds :tabonly (#37218)
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.
2026-01-04 13:15:08 +00:00
skewb1k
3b6e8e484e fix(float): prevent truncation of title that fits exactly #36880
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
2025-12-09 13:37:32 -05:00
glepnir
cb171ee7cb fix(float): tail truncate long title #28387
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.
2025-12-08 01:52:07 -05:00
luukvbaal
c7fd0c17b1 fix(window): don't make hidden/unfocusable previous window current #36142
Problem:  Previous window is made current while it is unfocusable/hidden.
Solution: Treat hidden/unfocusable window as an invalid previous window.
2025-10-11 19:41:09 -07:00
phanium
020d5e0f7e fix: stale lines("w$") after nvim_win_set_height when splitkeep=screen #36056
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
2025-10-11 14:48:39 -07:00
Sean Dewar
3ccba4cdff fix(float): crash from nasty :fclose autocmds (#36134)
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.
2025-10-11 18:08:24 +01:00
fredizzimo
8ae9a44d38 feat(ui): support grid=0 in nvim_input_mouse #32535
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.
2025-09-13 14:57:04 -07:00
zeertzjq
9269a1da35 fix(floatwin): handle viewport width properly at end of window (#35490)
Also avoid repeated calls of compute_foldcolumn().
2025-08-27 19:27:50 +08:00
Sean Dewar
1e1619de83 fix(eval): winnrs of unfocusable/hidden windows #35474
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
2025-08-26 13:13:05 -07:00
zeertzjq
5f9f706462 fix(ui): check for cmdline mode properly (#35202) 2025-08-07 04:22:01 +00:00
luukvbaal
7f5b5d34cf fix(window): don't store invalid height in window config (#34885)
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.
2025-07-11 16:53:30 +00:00
glepnir
5803994a1c fix(highlight): preserve bg transparency with winblend=100 #34825
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.
2025-07-10 05:42:45 -07:00
glepnir
fb0dc825e9 feat(option): custom chars in 'winborder' #33772
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).
2025-07-09 18:15:08 -07:00
phanium
1c52e90cd5 fix(help): :help can focus unfocusable/hide window #34442
Problem:
:help/:helpgrep/:lhelpgrep can focus unfocusable/hide window

Solution:
Ignore unfocusable/hidden window when reusing help buffer.
2025-06-29 14:44:17 +00:00
glepnir
64753b5c37 fix(highlight): spurious underline in 'winblend' floating window #34614
Problem: When a floating window with high winblend uses a highlight group
         with underline (but without guisp), the underline appears red.

Solution: Only blend the special color (for underline/undercurl) if the
          foreground highlight actually has underline or undercurl set.
          Otherwise, ignore the special color.
2025-06-27 02:52:28 -07:00
glepnir
a5c55d200b fix(cmd): bar "|" not allowed after :fclose #34613
Problem: `:fclose` command failed when used with trailing `|` bar.
Solution: Add `TRLBAR` flag to fclose command to support trailing bar.
2025-06-23 05:41:31 -07:00
luukvbaal
66e4784f5a fix(float): ensure relative window grid is allocated (#34459)
Problem:  Uninitialized grid for a "win" relative float when redrawing
          just after it has been opened.
Solution: Ensure window grid is allocated or assigned the default grid.
2025-06-12 08:51:29 +02:00
glepnir
336b46a879 fix(highlight): preserve background transparency in 'winblend' #34302
Problem: When using 'winblend', transparent backgrounds (-1) are forced
to default colors (usually black) during attribute blending, breaking
the transparency effect.

Solution: Check original background colors before blending in
hl_blend_attrs(). If both background and foreground originally had
transparent backgrounds, preserve transparency instead of forcing
default colors.
2025-06-09 08:24:46 -07:00
glepnir
e21c54000e test: remove unnecessary line breaks #34369
Problem: The test included too many unnecessary line breaks.
Solution: Remove the extra line breaks to make the test code more concise.
2025-06-08 03:26:45 -07:00
luukvbaal
3165e94a64 fix(api): ensure win_get_config() "border" is reciprocal (#34322)
fix(api): ensure win_get_config() is reciprocal

Problem:  win_get_config() does not include a 'none' border field,
          causing nvim_open_win() to apply the 'winborder' value.
Solution: Include a 'none' border field in the returned config,
          such that it can be used reciprocally in nvim_open_win()
          to yield the same window layout.
2025-06-06 12:40:57 +02:00
luukvbaal
eeacd7bd71 fix(api): adjust fix for reconfiguring float "relative" (#34287)
Problem:  "win" is cleared in float config after 96330843, even with
          unchanged "relative".
Solution: Don't clear "win". Avoid erroring for deleted "win" by setting
          the parent win to curwin directly when "win" is zero or not
          present in config.
2025-06-03 13:27:07 +02:00
luukvbaal
963308439a fix(api): reconfiguring float "relative" does not clear "win" (#34271)
Problem:  Unable to change the "relative" of a flag after its target
          "win" no longer exists.
Solution: Unset target window if it is not present in config and
          reconfigured "relative" no longer expects a target window.
2025-06-02 14:59:19 +02:00
luukvbaal
981d4ba45e fix(eval): winnr('$') counts non-current hidden/unfocusable windows #34207
Problem:  Non-visible/focusable windows are assigned a window number,
          whereas commands that use this window number skip over them.

Solution: Skip over non-visible/focusable windows when computing
          the window number, unless it is made the current window
          through the API in which case an identifiable window number
          is still useful. This also ensures it matches the window
          number of the window entered by `<winnr>wincmd w` since
          403fcacf.
2025-06-01 15:12:12 -07:00
glepnir
f2373a89d7 vim-patch:9.1.1408: not easily possible to complete from register content (#34198)
Problem:  not easily possible to complete from register content
Solution: add register-completion submode using i_CTRL-X_CTRL-R
          (glepnir)

closes: vim/vim#17354

0546068aae
2025-05-28 09:10:00 +00:00
Justin M. Keyes
f5b5f2095e refactor(tests): lint decorations_spec, float_spec, multigrid_spec #33274
Problem:
decorations_spec.lua, float_spec.lua, multigrid_spec.lua are not
auto-formatted.

Solution:
Add a special `formatlua2` cmake target, which invokes `stylua` with
an alternative `.stylua2.toml` config.
2025-05-06 18:00:20 -07:00
Sean Dewar
403fcacfc1 fix(window): skip unfocusable and hidden floats with "{count}<C-W>w" #33810
Problem: Using `<C-W>w`, `<C-W>W` or the ":wincmd" variants with a count can
enter unfocusable or hidden floating windows. This is especially problematic
when using the new in-development extui, which creates many unfocusable floats
for various UI elements.

Solution: Skip unfocusable and hidden floating windows. Instead, skip to the
next focusable, non-hidden window in the current tabpage's window list. Reword
the documentation a bit (hopefully an improvement?)
2025-05-03 11:30:24 -07:00
bfredl
f02484118c fix(ui): correct condition for "wrap" flag in a floating grid
In a floating window grid, "wrap" flag should not
be set when vertical borders are used, as the the wrapped
text will be broken up by border chars.

fixes #33719
2025-04-30 12:29:03 +02:00
Justin M. Keyes
52a4bc4548 docs: lsp, emoji, startup #33446
Co-authored-by: Maria José Solano <majosolano99@gmail.com>
2025-04-27 13:40:46 -07:00
Skoh
bc814cfb2c fix(winblend): treat braille blank (\u2800) as whitespace #32741
Problem:
'winblend' does not display text behind blank unicode characters other than 0x20 ascii space.

Solution:
In ui_compositor.c -> compose_line() check for either 0x20 or 0x80A0E2 (utf8 \u2800).
2025-04-23 05:27:21 -07:00
glepnir
d4f2b9050d fix(float): cursor visible in "hidden" floating window #30866
Problem:
Cursor is visible in "hidden" floating window.

Solution:
Hide cursor when curwin is a hidden floating window.
Show cursor after returning to a normal (non-hidden) window.
2025-04-23 05:22:43 -07:00
Fred Sundvik
f29856d034 feat(ui): include compositor info with multigrid
Provide compositor information, like composition index and absolute
position.
2025-04-15 10:52:57 +02:00
zeertzjq
04901f4ee7 test(float): restore border tests (#33222) 2025-03-31 14:08:54 +00:00