fix(api): nvim_win_resize tweaks #40596

This commit is contained in:
Justin M. Keyes
2026-07-05 13:22:16 -04:00
committed by GitHub
parent 1f18ea1cf7
commit 8dfe4d6629
6 changed files with 43 additions and 59 deletions

View File

@@ -4251,32 +4251,29 @@ nvim_win_is_valid({win}) *nvim_win_is_valid()*
(`boolean`) true if the window is valid, false otherwise
nvim_win_resize({win}, {width}, {height}, {opts}) *nvim_win_resize()*
Resize a window, choosing which edge stays anchored.
Resizes a window, anchored to a given edge.
The window first takes space from the non-anchored side (the window below
or to the right by default), and only then from the anchored side. The
"anchor" selects the fixed edge, so a window can also grow upwards or
leftwards.
The window first takes space from the non-anchored side, and only then
from the anchored side. The "anchor" decides the fixed edge, so a window
can grow or shrink in any direction.
Can set the height, the width, or both in a single call. "anchor" applies
to the matching axis ("top"/"bottom" for height, "left"/"right" for
width); the other axis, if also resized, uses its default anchor.
Can set height, width (only for a vertical split), or both. The "anchor"
applies to the matching axis (top/bottom for height, left/right for
width); the other axis uses its default anchor.
Attributes: ~
Since: 0.13.0
Parameters: ~
• {win} (`integer`) |window-ID|, or 0 for current window
• {width} (`integer`) New width as a count of columns, set -1 as "no
change"
• {height} (`integer`) New height as a count of rows, set -1 as "no
change"
• {width} (`integer`) New width (columns), or -1 for "no change".
• {height} (`integer`) New height (rows), or -1 for "no change".
• {opts} (`vim.api.keyset.win_resize`) Optional parameters.
• anchor: Edge that stays fixed while the opposite edge
moves; the neighbor on the moving side is resized first.
One of:
• "top" (default for height) or "bottom"
• "left" (default for width) or "right"
• "top" (default) or "bottom"
• "left" (default) or "right"
nvim_win_set_buf({win}, {buf}) *nvim_win_set_buf()*
Sets the current buffer in a window.

View File

@@ -138,9 +138,8 @@ The following new features were added.
API
• |nvim_win_resize()| resizes a window with a choosable anchor edge, letting a
window grow upwards or leftwards by taking space from the window above or to
the left first. |nvim_win_set_height()| and |nvim_win_set_width()| are now deprecated.
• |nvim_win_resize()| resizes a window with a specified anchor edge.
|nvim_win_set_height()| and |nvim_win_set_width()| are now deprecated.
• |nvim_buf_call()| and |nvim_win_call()| now preserve multiple return values.
• |nvim_set_hl()| supports "font" key.
• |nvim_open_win()| `zindex` controls whether the UI will use a dimmed cursor

View File

@@ -584,7 +584,7 @@ CTRL-W _ Set current window height to N (default: highest possible).
:{winnr}res[ize] [+-]N
Like `:resize` above, but apply the size to window {winnr}
instead of the current window.
instead of the current window. See also |nvim_win_resize()|.
z{nr}<CR> Set current window height to {nr}.

View File

@@ -2504,24 +2504,22 @@ function vim.api.nvim_win_hide(win) end
--- @return boolean # true if the window is valid, false otherwise
function vim.api.nvim_win_is_valid(win) end
--- Resize a window, choosing which edge stays anchored.
--- Resizes a window, anchored to a given edge.
---
--- The window first takes space from the non-anchored side (the window below or
--- to the right by default), and only then from the anchored side. The "anchor"
--- selects the fixed edge, so a window can also grow upwards or leftwards.
--- The window first takes space from the non-anchored side, and only then from the anchored side.
--- The "anchor" decides the fixed edge, so a window can grow or shrink in any direction.
---
--- Can set the height, the width, or both in a single call. "anchor" applies to the
--- matching axis ("top"/"bottom" for height, "left"/"right" for width); the other
--- axis, if also resized, uses its default anchor.
--- Can set height, width (only for a vertical split), or both. The "anchor" applies to the matching
--- axis (top/bottom for height, left/right for width); the other axis uses its default anchor.
---
--- @param win integer `window-ID`, or 0 for current window
--- @param width integer New width as a count of columns, set -1 as "no change"
--- @param height integer New height as a count of rows, set -1 as "no change"
--- @param width integer New width (columns), or -1 for "no change".
--- @param height integer New height (rows), or -1 for "no change".
--- @param opts vim.api.keyset.win_resize Optional parameters.
--- - anchor: Edge that stays fixed while the opposite edge moves; the
--- neighbor on the moving side is resized first. One of:
--- - "top" (default for height) or "bottom"
--- - "left" (default for width) or "right"
--- - "top" (default) or "bottom"
--- - "left" (default) or "right"
function vim.api.nvim_win_resize(win, width, height, opts) end
--- Sets the current buffer in a window.

View File

@@ -535,24 +535,22 @@ DictAs(win_text_height_ret) nvim_win_text_height(Window win, Dict(win_text_heigh
return rv;
}
/// Resize a window, choosing which edge stays anchored.
/// Resizes a window, anchored to a given edge.
///
/// The window first takes space from the non-anchored side (the window below or
/// to the right by default), and only then from the anchored side. The "anchor"
/// selects the fixed edge, so a window can also grow upwards or leftwards.
/// The window first takes space from the non-anchored side, and only then from the anchored side.
/// The "anchor" decides the fixed edge, so a window can grow or shrink in any direction.
///
/// Can set the height, the width, or both in a single call. "anchor" applies to the
/// matching axis ("top"/"bottom" for height, "left"/"right" for width); the other
/// axis, if also resized, uses its default anchor.
/// Can set height, width (only for a vertical split), or both. The "anchor" applies to the matching
/// axis (top/bottom for height, left/right for width); the other axis uses its default anchor.
///
/// @param win |window-ID|, or 0 for current window
/// @param width New width as a count of columns, set -1 as "no change"
/// @param height New height as a count of rows, set -1 as "no change"
/// @param width New width (columns), or -1 for "no change".
/// @param height New height (rows), or -1 for "no change".
/// @param opts Optional parameters.
/// - anchor: Edge that stays fixed while the opposite edge moves; the
/// neighbor on the moving side is resized first. One of:
/// - "top" (default for height) or "bottom"
/// - "left" (default for width) or "right"
/// - "top" (default) or "bottom"
/// - "left" (default) or "right"
/// @param[out] err Error details, if any
void nvim_win_resize(Window win, Integer width, Integer height, Dict(win_resize) *opts, Error *err)
FUNC_API_SINCE(15)
@@ -563,16 +561,14 @@ void nvim_win_resize(Window win, Integer width, Integer height, Dict(win_resize)
return;
}
VALIDATE_EXP((height >= 0 || height == -1), "height",
"a non-negative count of rows, or -1 for no change", NULL, {
VALIDATE_EXP((height >= 0 || height == -1), "height", "non-negative number or -1", NULL, {
return;
});
VALIDATE_EXP((width >= 0 || width == -1), "width",
"a non-negative count of columns, or -1 for no change", NULL, {
VALIDATE_EXP((width >= 0 || width == -1), "width", "non-negative number or -1", NULL, {
return;
});
VALIDATE_R((height >= 0 || width >= 0), "must set at least one of 'height', 'width'", {
VALIDATE_R((height >= 0 || width >= 0), "'height' or 'width'", {
return;
});
@@ -589,15 +585,12 @@ void nvim_win_resize(Window win, Integer width, Integer height, Dict(win_resize)
anchor, { return; });
// anchor must match a dimension that is actually being resized.
VALIDATE_CON(!(is_height && height == -1) && !(is_width && width == -1), anchor,
"this dimension", {
is_width ? "width" : "height", {
return;
});
if (is_height) {
from_top = strequal("top", anchor);
} else {
from_left = strequal("left", anchor);
}
from_top = !strequal("bottom", anchor);
from_left = !strequal("right", anchor);
}
if (height >= 0) {
TRY_WRAP(err, win_setheight_win((int)height, w, from_top));

View File

@@ -490,23 +490,20 @@ describe('API/win', function()
end
)
it('failure modes', function()
it('validation', function()
command('split')
eq("Required: 'height' or 'width'", pcall_err(api.nvim_win_resize, 0, -1, -1, {}))
eq(
"Required: must set at least one of 'height', 'width'",
pcall_err(api.nvim_win_resize, 0, -1, -1, {})
)
eq(
"Invalid 'width': expected a non-negative count of columns, or -1 for no change",
"Invalid 'width': expected non-negative number or -1",
pcall_err(api.nvim_win_resize, 0, -2, 5, {})
)
eq(
"Invalid 'height': expected a non-negative count of rows, or -1 for no change",
"Invalid 'height': expected non-negative number or -1",
pcall_err(api.nvim_win_resize, 0, 5, -2, {})
)
-- anchor not applicable to the dimension(s) being changed
eq(
"Conflict: 'left' not allowed with this dimension",
"Conflict: 'left' not allowed with 'width'",
pcall_err(api.nvim_win_resize, 0, -1, 5, { anchor = 'left' })
)
-- unrecognized anchor value