feat(api): add "max_height" argument to nvim_win_text_height (#32835)

Useful to e.g. limit the height to the window height, avoiding unnecessary
work. Or to find out how many buffer lines beyond "start_row" take up a
certain number of logical lines (returned in "end_row" and "end_vcol").
This commit is contained in:
luukvbaal
2025-04-21 13:48:26 +02:00
committed by GitHub
parent 98ec3fdf74
commit 7ba043f0f3
10 changed files with 423 additions and 185 deletions

View File

@@ -3358,13 +3358,24 @@ nvim_win_text_height({window}, {opts}) *nvim_win_text_height()*
0-based inclusive, rounded down to full screen lines. When
omitted include the whole line.
• end_vcol: Ending virtual column index on "end_row",
0-based exclusive, rounded up to full screen lines. When
omitted include the whole line.
0-based exclusive, rounded up to full screen lines. When 0
only include diff filler and virtual lines above
"end_row". When omitted include the whole line.
• max_height: Don't add the height of lines below the row
for which this height is reached. Useful to e.g. limit the
height to the window height, avoiding unnecessary work. Or
to find out how many buffer lines beyond "start_row" take
up a certain number of logical lines (returned in
"end_row" and "end_vcol").
Return: ~
Dict containing text height information, with these keys:
• all: The total number of screen lines occupied by the range.
• fill: The number of diff filler or virtual lines among them.
• end_row: The row on which the returned height is reached (first row
of a closed fold).
• end_vcol: Ending virtual column in "end_row" where "max_height" or
the returned height is reached. 0 if "end_row" is a closed fold.
See also: ~
• |virtcol()| for text width.

View File

@@ -108,6 +108,9 @@ The following new features were added.
API
• |vim.hl.range()| now allows multiple timed highlights
• |nvim_win_text_height()| can limit the lines checked when a certain
`max_height` is reached, and returns the `end_row` and `end_vcol` for which
`max_height` or the calculated height is reached.
DEFAULTS

View File

@@ -2526,9 +2526,20 @@ function vim.api.nvim_win_set_width(window, width) end
--- When omitted include the whole line.
--- - end_vcol: Ending virtual column index on "end_row",
--- 0-based exclusive, rounded up to full screen lines.
--- When omitted include the whole line.
--- When 0 only include diff filler and virtual lines above
--- "end_row". When omitted include the whole line.
--- - max_height: Don't add the height of lines below the row
--- for which this height is reached. Useful to e.g. limit the
--- height to the window height, avoiding unnecessary work. Or
--- to find out how many buffer lines beyond "start_row" take
--- up a certain number of logical lines (returned in
--- "end_row" and "end_vcol").
--- @return table<string,any> # Dict containing text height information, with these keys:
--- - all: The total number of screen lines occupied by the range.
--- - fill: The number of diff filler or virtual lines among them.
--- - end_row: The row on which the returned height is reached (first row of
--- a closed fold).
--- - end_vcol: Ending virtual column in "end_row" where "max_height" or the returned
--- height is reached. 0 if "end_row" is a closed fold.
---
function vim.api.nvim_win_text_height(window, opts) end

View File

@@ -318,6 +318,7 @@ error('Cannot require a meta file')
--- @field end_row? integer
--- @field start_vcol? integer
--- @field end_vcol? integer
--- @field max_height? integer
--- @class vim.api.keyset.xdl_diff
--- @field on_hunk? fun(start_a: integer, count_a: integer, start_b: integer, count_b: integer): integer?

View File

@@ -1649,9 +1649,10 @@ function M.open_floating_preview(contents, syntax, opts)
vim.treesitter.start(floating_bufnr)
if not opts.height then
-- Reduce window height if TS highlighter conceals code block backticks.
local conceal_height = api.nvim_win_text_height(floating_winnr, {}).all
if conceal_height < api.nvim_win_get_height(floating_winnr) then
api.nvim_win_set_height(floating_winnr, conceal_height)
local win_height = api.nvim_win_get_height(floating_winnr)
local text_height = api.nvim_win_text_height(floating_winnr, { max_height = win_height }).all
if text_height < win_height then
api.nvim_win_set_height(floating_winnr, text_height)
end
end
end

View File

@@ -229,6 +229,7 @@ typedef struct {
Integer end_row;
Integer start_vcol;
Integer end_vcol;
Integer max_height;
} Dict(win_text_height);
typedef struct {

View File

@@ -483,10 +483,21 @@ void nvim_win_set_hl_ns(Window window, Integer ns_id, Error *err)
/// When omitted include the whole line.
/// - end_vcol: Ending virtual column index on "end_row",
/// 0-based exclusive, rounded up to full screen lines.
/// When omitted include the whole line.
/// When 0 only include diff filler and virtual lines above
/// "end_row". When omitted include the whole line.
/// - max_height: Don't add the height of lines below the row
/// for which this height is reached. Useful to e.g. limit the
/// height to the window height, avoiding unnecessary work. Or
/// to find out how many buffer lines beyond "start_row" take
/// up a certain number of logical lines (returned in
/// "end_row" and "end_vcol").
/// @return Dict containing text height information, with these keys:
/// - all: The total number of screen lines occupied by the range.
/// - fill: The number of diff filler or virtual lines among them.
/// - end_row: The row on which the returned height is reached (first row of
/// a closed fold).
/// - end_vcol: Ending virtual column in "end_row" where "max_height" or the returned
/// height is reached. 0 if "end_row" is a closed fold.
///
/// @see |virtcol()| for text width.
Dict nvim_win_text_height(Window window, Dict(win_text_height) *opts, Arena *arena, Error *err)
@@ -545,6 +556,14 @@ Dict nvim_win_text_height(Window window, Dict(win_text_height) *opts, Arena *are
});
}
int64_t max = INT64_MAX;
if (HAS_KEY(opts, win_text_height, max_height)) {
VALIDATE_RANGE(opts->max_height > 0, "max_height", {
return rv;
});
max = opts->max_height;
}
if (start_lnum == end_lnum && start_vcol >= 0 && end_vcol >= 0) {
VALIDATE((start_vcol <= end_vcol), "%s", "'start_vcol' is higher than 'end_vcol'", {
return rv;
@@ -552,7 +571,7 @@ Dict nvim_win_text_height(Window window, Dict(win_text_height) *opts, Arena *are
}
int64_t fill = 0;
int64_t all = win_text_height(win, start_lnum, start_vcol, end_lnum, end_vcol, &fill);
int64_t all = win_text_height(win, start_lnum, start_vcol, &end_lnum, &end_vcol, &fill, max);
if (!HAS_KEY(opts, win_text_height, end_row)) {
const int64_t end_fill = win_get_fill(win, line_count + 1);
fill += end_fill;
@@ -560,5 +579,7 @@ Dict nvim_win_text_height(Window window, Dict(win_text_height) *opts, Arena *are
}
PUT_C(rv, "all", INTEGER_OBJ(all));
PUT_C(rv, "fill", INTEGER_OBJ(fill));
PUT_C(rv, "end_row", INTEGER_OBJ(end_lnum - 1));
PUT_C(rv, "end_vcol", INTEGER_OBJ(end_vcol));
return rv;
}

View File

@@ -953,35 +953,37 @@ int plines_m_win_fill(win_T *wp, linenr_T first, linenr_T last)
/// Get the number of screen lines a range of text will take in window "wp".
///
/// @param[in] start_lnum Starting line number, 1-based inclusive.
/// @param[in] start_vcol >= 0: Starting virtual column index on "start_lnum",
/// 0-based inclusive, rounded down to full screen lines.
/// < 0: Count a full "start_lnum", including filler lines above.
/// @param[in] end_lnum Ending line number, 1-based inclusive.
/// @param[in] end_vcol >= 0: Ending virtual column index on "end_lnum",
/// 0-based exclusive, rounded up to full screen lines.
/// < 0: Count a full "end_lnum", not including filler lines below.
/// @param[out] fill If not NULL, set to the number of filler lines in the range.
/// @param[in] start_lnum Starting line number, 1-based inclusive.
/// @param[in] start_vcol >= 0: Starting virtual column index on "start_lnum",
/// 0-based inclusive, rounded down to full screen lines.
/// < 0: Count a full "start_lnum", including filler lines above.
/// @param[in,out] end_lnum Ending line number, 1-based inclusive. Set to last line for
/// which the height is calculated (smaller if "max" is reached).
/// @param[in,out] end_vcol >= 0: Ending virtual column index on "end_lnum",
/// 0-based exclusive, rounded up to full screen lines.
/// < 0: Count a full "end_lnum", not including filler lines below.
/// Set to the number of columns in "end_lnum" to reach "max".
/// @param[in] max Don't calculate the height for lines beyond the line where "max"
/// height is reached.
/// @param[out] fill If not NULL, set to the number of filler lines in the range.
int64_t win_text_height(win_T *const wp, const linenr_T start_lnum, const int64_t start_vcol,
const linenr_T end_lnum, const int64_t end_vcol, int64_t *const fill)
linenr_T *const end_lnum, int64_t *const end_vcol, int64_t *const fill,
int64_t const max)
{
int width1 = 0;
int width2 = 0;
if (start_vcol >= 0 || end_vcol >= 0) {
width1 = wp->w_width_inner - win_col_off(wp);
width2 = width1 + win_col_off2(wp);
width1 = MAX(width1, 0);
width2 = MAX(width2, 0);
}
int width1 = wp->w_width_inner - win_col_off(wp);
int width2 = width1 + win_col_off2(wp);
width1 = MAX(width1, 0);
width2 = MAX(width2, 0);
int64_t height_sum_fill = 0;
int64_t height_cur_nofill = 0;
int64_t height_sum_nofill = 0;
linenr_T lnum = start_lnum;
linenr_T cur_lnum = lnum;
bool cur_folded = false;
if (start_vcol >= 0) {
linenr_T lnum_next = lnum;
hasFolding(wp, lnum, &lnum, &lnum_next);
cur_folded = hasFolding(wp, lnum, &lnum, &lnum_next);
height_cur_nofill = plines_win_nofill(wp, lnum, false);
height_sum_nofill += height_cur_nofill;
const int64_t row_off = (start_vcol < width1 || width2 <= 0)
@@ -991,25 +993,42 @@ int64_t win_text_height(win_T *const wp, const linenr_T start_lnum, const int64_
lnum = lnum_next + 1;
}
while (lnum <= end_lnum) {
while (lnum <= *end_lnum && height_sum_nofill + height_sum_fill < max) {
linenr_T lnum_next = lnum;
hasFolding(wp, lnum, &lnum, &lnum_next);
cur_folded = hasFolding(wp, lnum, &lnum, &lnum_next);
height_sum_fill += win_get_fill(wp, lnum);
height_cur_nofill = plines_win_nofill(wp, lnum, false);
height_sum_nofill += height_cur_nofill;
cur_lnum = lnum;
lnum = lnum_next + 1;
}
if (end_vcol >= 0) {
int64_t vcol_end = *end_vcol;
bool use_vcol = vcol_end >= 0 && lnum > *end_lnum;
if (use_vcol) {
height_sum_nofill -= height_cur_nofill;
const int64_t row_off = end_vcol == 0
const int64_t row_off = vcol_end == 0
? 0
: (end_vcol <= width1 || width2 <= 0)
: (vcol_end <= width1 || width2 <= 0)
? 1
: 1 + (end_vcol - width1 + width2 - 1) / width2;
: 1 + (vcol_end - width1 + width2 - 1) / width2;
height_sum_nofill += MIN(row_off, height_cur_nofill);
}
if (cur_folded) {
vcol_end = 0;
} else {
int linesize = linetabsize_eol(wp, cur_lnum);
vcol_end = MIN(use_vcol ? vcol_end : INT64_MAX, linesize);
}
int64_t overflow = height_sum_nofill + height_sum_fill - max;
if (overflow > 0 && width2 > 0 && vcol_end > width2) {
vcol_end -= (vcol_end - width1) % width2 + (overflow - 1) * width2;
}
*end_lnum = cur_lnum;
*end_vcol = vcol_end;
if (fill != NULL) {
*fill = height_sum_fill;
}

View File

@@ -933,22 +933,26 @@ void ui_ext_win_viewport(win_T *wp)
last_botline = MIN(last_botline, line_count);
if (cur_topline < last_topline
|| (cur_topline == last_topline && wp->w_skipcol < last_skipcol)) {
int64_t vcole = last_skipcol;
linenr_T lnume = last_topline;
if (last_topline > 0 && cur_botline < last_topline) {
// Scrolling too many lines: only give an approximate "scroll_delta".
delta -= win_text_height(wp, cur_topline, wp->w_skipcol, cur_botline, 0, NULL);
delta -= last_topline - cur_botline;
} else {
delta -= win_text_height(wp, cur_topline, wp->w_skipcol, last_topline, last_skipcol, NULL);
lnume = cur_botline;
vcole = 0;
}
delta -= win_text_height(wp, cur_topline, wp->w_skipcol, &lnume, &vcole, NULL, INT64_MAX);
} else if (cur_topline > last_topline
|| (cur_topline == last_topline && wp->w_skipcol > last_skipcol)) {
int64_t vcole = wp->w_skipcol;
linenr_T lnume = cur_topline;
if (last_botline > 0 && cur_topline > last_botline) {
// Scrolling too many lines: only give an approximate "scroll_delta".
delta += win_text_height(wp, last_topline, last_skipcol, last_botline, 0, NULL);
delta += cur_topline - last_botline;
} else {
delta += win_text_height(wp, last_topline, last_skipcol, cur_topline, wp->w_skipcol, NULL);
lnume = last_botline;
vcole = 0;
}
delta += win_text_height(wp, last_topline, last_skipcol, &lnume, &vcole, NULL, INT64_MAX);
}
delta += last_topfill;
delta -= wp->w_topfill;

View File

@@ -177,33 +177,25 @@ describe('API/win', function()
local win = curwin()
feed('gg')
screen:expect {
grid = [[
local s1 = [[
^prologue |
|*8
]],
}
]]
screen:expect(s1)
-- cursor position is at beginning
eq({ 1, 0 }, api.nvim_win_get_cursor(win))
-- move cursor to end
api.nvim_win_set_cursor(win, { 101, 0 })
screen:expect {
grid = [[
screen:expect([[
|*7
^epilogue |
|
]],
}
]])
-- move cursor to the beginning again
api.nvim_win_set_cursor(win, { 1, 0 })
screen:expect {
grid = [[
^prologue |
|*8
]],
}
screen:expect(s1)
-- move focus to new window
command('new')
@@ -211,8 +203,7 @@ describe('API/win', function()
-- sanity check, cursor position is kept
eq({ 1, 0 }, api.nvim_win_get_cursor(win))
screen:expect {
grid = [[
local s2 = [[
^ |
{1:~ }|*2
{3:[No Name] }|
@@ -220,13 +211,12 @@ describe('API/win', function()
|*2
{2:[No Name] [+] }|
|
]],
}
]]
screen:expect(s2)
-- move cursor to end
api.nvim_win_set_cursor(win, { 101, 0 })
screen:expect {
grid = [[
screen:expect([[
^ |
{1:~ }|*2
{3:[No Name] }|
@@ -234,22 +224,11 @@ describe('API/win', function()
epilogue |
{2:[No Name] [+] }|
|
]],
}
]])
-- move cursor to the beginning again
api.nvim_win_set_cursor(win, { 1, 0 })
screen:expect {
grid = [[
^ |
{1:~ }|*2
{3:[No Name] }|
prologue |
|*2
{2:[No Name] [+] }|
|
]],
}
screen:expect(s2)
-- curwin didn't change back
neq(win, curwin())
@@ -860,8 +839,14 @@ describe('API/win', function()
end)
describe('text_height', function()
local screen, ns, X
before_each(function()
screen = Screen.new(45, 22)
ns = api.nvim_create_namespace('')
X = api.nvim_get_vvar('maxcol')
end)
it('validation', function()
local X = api.nvim_get_vvar('maxcol')
insert([[
aaa
bbb
@@ -901,6 +886,10 @@ describe('API/win', function()
"Invalid 'end_vcol': out of range",
pcall_err(api.nvim_win_text_height, 0, { end_row = 2, end_vcol = X + 1 })
)
eq(
"Invalid 'max_height': out of range",
pcall_err(api.nvim_win_text_height, 0, { max_height = 0 })
)
eq(
"'start_vcol' is higher than 'end_vcol'",
pcall_err(
@@ -912,8 +901,6 @@ describe('API/win', function()
end)
it('with two diff windows', function()
local X = api.nvim_get_vvar('maxcol')
local screen = Screen.new(45, 22)
exec([[
set diffopt+=context:2 number
let expr = 'printf("%08d", v:val) .. repeat("!", v:val)'
@@ -923,8 +910,7 @@ describe('API/win', function()
windo diffthis
]])
feed('24gg')
screen:expect {
grid = [[
screen:expect([[
{7: }{8: }{23:----------------}│{7: }{8: 1 }{22:00000001! }|
{7: }{8: }{23:----------------}│{7: }{8: 2 }{22:00000002!! }|
{7: }{8: 1 }00000003!!! │{7: }{8: 3 }00000003!!! |
@@ -947,80 +933,155 @@ describe('API/win', function()
{7: }{8: 41 }{22:00000050!!!!!!!!}│{7: }{8: }{23:----------------}|
{2:[No Name] [+] }{3:[No Name] [+] }|
|
]],
}
]])
screen:try_resize(45, 3)
screen:expect {
grid = [[
screen:expect([[
{7: }{8: 19 }00000028!!!!!!!!│{7: }{8: 24 }^00000028!!!!!!!!|
{2:[No Name] [+] }{3:[No Name] [+] }|
|
]],
}
eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1000, {}))
eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1001, {}))
eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1000, { start_row = 0 }))
eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1001, { start_row = 0 }))
eq({ all = 15, fill = 0 }, api.nvim_win_text_height(1000, { end_row = -1 }))
eq({ all = 15, fill = 0 }, api.nvim_win_text_height(1000, { end_row = 40 }))
eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1001, { end_row = -1 }))
eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1001, { end_row = 40 }))
eq({ all = 10, fill = 5 }, api.nvim_win_text_height(1000, { start_row = 23 }))
eq({ all = 13, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 18 }))
eq({ all = 11, fill = 0 }, api.nvim_win_text_height(1000, { end_row = 23 }))
eq({ all = 11, fill = 5 }, api.nvim_win_text_height(1001, { end_row = 18 }))
eq({ all = 11, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 3, end_row = 39 }))
eq({ all = 11, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 1, end_row = 34 }))
eq({ all = 9, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 4, end_row = 38 }))
eq({ all = 9, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 2, end_row = 33 }))
eq({ all = 9, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 5, end_row = 37 }))
eq({ all = 9, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 3, end_row = 32 }))
eq({ all = 9, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 17, end_row = 25 }))
eq({ all = 9, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 15, end_row = 20 }))
eq({ all = 7, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 18, end_row = 24 }))
eq({ all = 7, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 16, end_row = 19 }))
eq({ all = 6, fill = 5 }, api.nvim_win_text_height(1000, { start_row = -1 }))
eq({ all = 5, fill = 5 }, api.nvim_win_text_height(1000, { start_row = -1, start_vcol = X }))
]])
eq({ all = 20, fill = 5, end_row = 40, end_vcol = 53 }, api.nvim_win_text_height(1000, {}))
eq({ all = 20, fill = 5, end_row = 40, end_vcol = 58 }, api.nvim_win_text_height(1001, {}))
eq(
{ all = 0, fill = 0 },
{ all = 20, fill = 5, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(1000, { start_row = 0 })
)
eq(
{ all = 20, fill = 5, end_row = 40, end_vcol = 58 },
api.nvim_win_text_height(1001, { start_row = 0 })
)
eq(
{ all = 15, fill = 0, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(1000, { end_row = -1 })
)
eq(
{ all = 15, fill = 0, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(1000, { end_row = 40 })
)
eq(
{ all = 20, fill = 5, end_row = 40, end_vcol = 58 },
api.nvim_win_text_height(1001, { end_row = -1 })
)
eq(
{ all = 20, fill = 5, end_row = 40, end_vcol = 58 },
api.nvim_win_text_height(1001, { end_row = 40 })
)
eq(
{ all = 10, fill = 5, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(1000, { start_row = 23 })
)
eq(
{ all = 13, fill = 3, end_row = 40, end_vcol = 58 },
api.nvim_win_text_height(1001, { start_row = 18 })
)
eq(
{ all = 11, fill = 0, end_row = 23, end_vcol = 36 },
api.nvim_win_text_height(1000, { end_row = 23 })
)
eq(
{ all = 11, fill = 5, end_row = 18, end_vcol = 36 },
api.nvim_win_text_height(1001, { end_row = 18 })
)
eq(
{ all = 11, fill = 0, end_row = 39, end_vcol = 52 },
api.nvim_win_text_height(1000, { start_row = 3, end_row = 39 })
)
eq(
{ all = 11, fill = 3, end_row = 34, end_vcol = 52 },
api.nvim_win_text_height(1001, { start_row = 1, end_row = 34 })
)
eq(
{ all = 9, fill = 0, end_row = 25, end_vcol = 0 },
api.nvim_win_text_height(1000, { start_row = 4, end_row = 38 })
)
eq(
{ all = 9, fill = 3, end_row = 20, end_vcol = 0 },
api.nvim_win_text_height(1001, { start_row = 2, end_row = 33 })
)
eq(
{ all = 9, fill = 0, end_row = 25, end_vcol = 0 },
api.nvim_win_text_height(1000, { start_row = 5, end_row = 37 })
)
eq(
{ all = 9, fill = 3, end_row = 20, end_vcol = 0 },
api.nvim_win_text_height(1001, { start_row = 3, end_row = 32 })
)
eq(
{ all = 9, fill = 0, end_row = 25, end_vcol = 0 },
api.nvim_win_text_height(1000, { start_row = 17, end_row = 25 })
)
eq(
{ all = 9, fill = 3, end_row = 20, end_vcol = 0 },
api.nvim_win_text_height(1001, { start_row = 15, end_row = 20 })
)
eq(
{ all = 7, fill = 0, end_row = 24, end_vcol = 37 },
api.nvim_win_text_height(1000, { start_row = 18, end_row = 24 })
)
eq(
{ all = 7, fill = 3, end_row = 19, end_vcol = 37 },
api.nvim_win_text_height(1001, { start_row = 16, end_row = 19 })
)
eq(
{ all = 6, fill = 5, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(1000, { start_row = -1 })
)
eq(
{ all = 5, fill = 5, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(1000, { start_row = -1, start_vcol = X })
)
eq(
{ all = 0, fill = 0, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(1000, { start_row = -1, start_vcol = X, end_row = -1 })
)
eq(
{ all = 0, fill = 0 },
{ all = 0, fill = 0, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(
1000,
{ start_row = -1, start_vcol = X, end_row = -1, end_vcol = X }
)
)
eq(
{ all = 1, fill = 0 },
{ all = 1, fill = 0, end_row = 40, end_vcol = 53 },
api.nvim_win_text_height(
1000,
{ start_row = -1, start_vcol = 0, end_row = -1, end_vcol = X }
)
)
eq({ all = 3, fill = 2 }, api.nvim_win_text_height(1001, { end_row = 0 }))
eq({ all = 2, fill = 2 }, api.nvim_win_text_height(1001, { end_row = 0, end_vcol = 0 }))
eq(
{ all = 2, fill = 2 },
{ all = 3, fill = 2, end_row = 0, end_vcol = 11 },
api.nvim_win_text_height(1001, { end_row = 0 })
)
eq(
{ all = 2, fill = 2, end_row = 0, end_vcol = 0 },
api.nvim_win_text_height(1001, { end_row = 0, end_vcol = 0 })
)
eq(
{ all = 2, fill = 2, end_row = 0, end_vcol = 0 },
api.nvim_win_text_height(1001, { start_row = 0, end_row = 0, end_vcol = 0 })
)
eq(
{ all = 0, fill = 0 },
{ all = 0, fill = 0, end_row = 0, end_vcol = 0 },
api.nvim_win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 0, end_vcol = 0 })
)
eq(
{ all = 1, fill = 0 },
{ all = 1, fill = 0, end_row = 0, end_vcol = 11 },
api.nvim_win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 0, end_vcol = X })
)
eq({ all = 11, fill = 5 }, api.nvim_win_text_height(1001, { end_row = 18 }))
eq(
{ all = 9, fill = 3 },
{ all = 11, fill = 5, end_row = 18, end_vcol = 36 },
api.nvim_win_text_height(1001, { end_row = 18 })
)
eq(
{ all = 9, fill = 3, end_row = 18, end_vcol = 36 },
api.nvim_win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 18 })
)
eq({ all = 10, fill = 5 }, api.nvim_win_text_height(1001, { end_row = 18, end_vcol = 0 }))
eq(
{ all = 8, fill = 3 },
{ all = 10, fill = 5, end_row = 18, end_vcol = 0 },
api.nvim_win_text_height(1001, { end_row = 18, end_vcol = 0 })
)
eq(
{ all = 8, fill = 3, end_row = 18, end_vcol = 0 },
api.nvim_win_text_height(
1001,
{ start_row = 0, start_vcol = 0, end_row = 18, end_vcol = 0 }
@@ -1029,13 +1090,10 @@ describe('API/win', function()
end)
it('with wrapped lines', function()
local X = api.nvim_get_vvar('maxcol')
local screen = Screen.new(45, 22)
exec([[
set number cpoptions+=n
call setline(1, repeat([repeat('foobar-', 36)], 3))
]])
local ns = api.nvim_create_namespace('')
api.nvim_buf_set_extmark(
0,
ns,
@@ -1050,8 +1108,7 @@ describe('API/win', function()
200,
{ virt_text = { { ('!'):rep(75), 'Search' } }, virt_text_pos = 'inline' }
)
screen:expect {
grid = [[
screen:expect([[
{8: 1 }^foobar-foobar-foobar-foobar-foobar-foobar|
-foobar-foobar-foobar-foobar-foobar-foobar-fo|
obar-foobar-foobar-foobar-foobar-foobar-fooba|
@@ -1074,142 +1131,187 @@ describe('API/win', function()
{10:!!!!!!!!!}ar-foobar-foobar-foobar-foobar-fooba|
r-foobar-foobar- |
|
]],
}
]])
screen:try_resize(45, 2)
screen:expect {
grid = [[
screen:expect([[
{8: 1 }^foobar-foobar-foobar-foobar-foobar-foobar|
|
]],
}
eq({ all = 21, fill = 0 }, api.nvim_win_text_height(0, {}))
eq({ all = 6, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 }))
eq({ all = 7, fill = 0 }, api.nvim_win_text_height(0, { start_row = 1, end_row = 1 }))
eq({ all = 8, fill = 0 }, api.nvim_win_text_height(0, { start_row = 2, end_row = 2 }))
]])
eq({ all = 21, fill = 0, end_row = 2, end_vcol = 327 }, api.nvim_win_text_height(0, {}))
eq(
{ all = 0, fill = 0 },
{ all = 6, fill = 0, end_row = 0, end_vcol = 252 },
api.nvim_win_text_height(0, { start_row = 0, end_row = 0 })
)
eq(
{ all = 7, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, end_row = 1 })
)
eq(
{ all = 8, fill = 0, end_row = 2, end_vcol = 327 },
api.nvim_win_text_height(0, { start_row = 2, end_row = 2 })
)
eq(
{ all = 0, fill = 0, end_row = 1, end_vcol = 0 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 0 })
)
eq(
{ all = 1, fill = 0 },
{ all = 1, fill = 0, end_row = 1, end_vcol = 41 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 41 })
)
eq(
{ all = 2, fill = 0 },
{ all = 2, fill = 0, end_row = 1, end_vcol = 42 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 42 })
)
eq(
{ all = 2, fill = 0 },
{ all = 2, fill = 0, end_row = 1, end_vcol = 86 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 86 })
)
eq(
{ all = 3, fill = 0 },
{ all = 3, fill = 0, end_row = 1, end_vcol = 87 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 87 })
)
eq(
{ all = 6, fill = 0 },
{ all = 6, fill = 0, end_row = 1, end_vcol = 266 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 266 })
)
eq(
{ all = 7, fill = 0 },
{ all = 7, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 267 })
)
eq(
{ all = 7, fill = 0 },
{ all = 7, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 311 })
)
eq(
{ all = 7, fill = 0 },
{ all = 7, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 312 })
)
eq(
{ all = 7, fill = 0 },
{ all = 7, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = X })
)
eq(
{ all = 7, fill = 0 },
{ all = 7, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 40, end_row = 1, end_vcol = X })
)
eq(
{ all = 6, fill = 0 },
{ all = 6, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 41, end_row = 1, end_vcol = X })
)
eq(
{ all = 6, fill = 0 },
{ all = 6, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 85, end_row = 1, end_vcol = X })
)
eq(
{ all = 5, fill = 0 },
{ all = 5, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 86, end_row = 1, end_vcol = X })
)
eq(
{ all = 2, fill = 0 },
{ all = 2, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 265, end_row = 1, end_vcol = X })
)
eq(
{ all = 1, fill = 0 },
{ all = 1, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 266, end_row = 1, end_vcol = X })
)
eq(
{ all = 1, fill = 0 },
{ all = 1, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 310, end_row = 1, end_vcol = X })
)
eq(
{ all = 0, fill = 0 },
{ all = 0, fill = 0, end_row = 1, end_vcol = 267 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 311, end_row = 1, end_vcol = X })
)
eq(
{ all = 1, fill = 0 },
{ all = 1, fill = 0, end_row = 1, end_vcol = 131 },
api.nvim_win_text_height(0, { start_row = 1, start_vcol = 86, end_row = 1, end_vcol = 131 })
)
eq(
{ all = 1, fill = 0 },
{ all = 1, fill = 0, end_row = 1, end_vcol = 266 },
api.nvim_win_text_height(
0,
{ start_row = 1, start_vcol = 221, end_row = 1, end_vcol = 266 }
)
)
eq({ all = 18, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, start_vcol = 131 }))
eq({ all = 19, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, start_vcol = 130 }))
eq({ all = 20, fill = 0 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 311 }))
eq({ all = 21, fill = 0 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 312 }))
eq(
{ all = 17, fill = 0 },
{ all = 18, fill = 0, end_row = 2, end_vcol = 327 },
api.nvim_win_text_height(0, { start_row = 0, start_vcol = 131 })
)
eq(
{ all = 19, fill = 0, end_row = 2, end_vcol = 327 },
api.nvim_win_text_height(0, { start_row = 0, start_vcol = 130 })
)
eq(
{ all = 20, fill = 0, end_row = 2, end_vcol = 311 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 311 })
)
eq(
{ all = 21, fill = 0, end_row = 2, end_vcol = 312 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 312 })
)
eq(
{ all = 17, fill = 0, end_row = 2, end_vcol = 311 },
api.nvim_win_text_height(
0,
{ start_row = 0, start_vcol = 131, end_row = 2, end_vcol = 311 }
)
)
eq(
{ all = 19, fill = 0 },
{ all = 19, fill = 0, end_row = 2, end_vcol = 312 },
api.nvim_win_text_height(
0,
{ start_row = 0, start_vcol = 130, end_row = 2, end_vcol = 312 }
)
)
eq({ all = 16, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, start_vcol = 221 }))
eq({ all = 17, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, start_vcol = 220 }))
eq({ all = 14, fill = 0 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 41 }))
eq({ all = 15, fill = 0 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 42 }))
eq(
{ all = 9, fill = 0 },
{ all = 16, fill = 0, end_row = 2, end_vcol = 327 },
api.nvim_win_text_height(0, { start_row = 0, start_vcol = 221 })
)
eq(
{ all = 17, fill = 0, end_row = 2, end_vcol = 327 },
api.nvim_win_text_height(0, { start_row = 0, start_vcol = 220 })
)
eq(
{ all = 14, fill = 0, end_row = 2, end_vcol = 41 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 41 })
)
eq(
{ all = 15, fill = 0, end_row = 2, end_vcol = 42 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 42 })
)
eq(
{ all = 9, fill = 0, end_row = 2, end_vcol = 41 },
api.nvim_win_text_height(0, { start_row = 0, start_vcol = 221, end_row = 2, end_vcol = 41 })
)
eq(
{ all = 11, fill = 0 },
{ all = 11, fill = 0, end_row = 2, end_vcol = 42 },
api.nvim_win_text_height(0, { start_row = 0, start_vcol = 220, end_row = 2, end_vcol = 42 })
)
exec('call setline(1, "foo")')
eq(
{ all = 1, fill = 0, end_row = 0, end_vcol = 3 },
api.nvim_win_text_height(0, { max_height = 1 })
)
eq(
{ all = 8, fill = 0, end_row = 1, end_vcol = 41 },
api.nvim_win_text_height(0, { max_height = 2 })
)
eq(
{ all = 2, fill = 0, end_row = 1, end_vcol = 1 },
api.nvim_win_text_height(0, { max_height = 2, end_row = 1, end_vcol = 1 })
)
eq(
{ all = 8, fill = 0, end_row = 1, end_vcol = 41 },
api.nvim_win_text_height(0, { max_height = 2, end_row = 2, end_vcol = 1 })
)
end)
it('with virtual lines around a fold', function()
local X = api.nvim_get_vvar('maxcol')
local screen = Screen.new(45, 10)
screen:try_resize(45, 10)
exec([[
call setline(1, range(1, 8))
3,6fold
]])
local ns = api.nvim_create_namespace('TEST')
api.nvim_buf_set_extmark(
0,
ns,
@@ -1236,21 +1338,85 @@ describe('API/win', function()
{1:~ }|
|
]])
eq({ all = 8, fill = 3 }, api.nvim_win_text_height(0, {}))
eq({ all = 5, fill = 2 }, api.nvim_win_text_height(0, { end_row = 2 }))
eq({ all = 5, fill = 2 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = X }))
eq({ all = 5, fill = 2 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 90 }))
eq({ all = 5, fill = 2 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 46 }))
eq({ all = 5, fill = 2 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 45 }))
eq({ all = 5, fill = 2 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 1 }))
eq({ all = 4, fill = 2 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 0 }))
eq({ all = 6, fill = 3 }, api.nvim_win_text_height(0, { start_row = 2 }))
eq({ all = 4, fill = 1 }, api.nvim_win_text_height(0, { start_row = 2, start_vcol = 0 }))
eq({ all = 4, fill = 1 }, api.nvim_win_text_height(0, { start_row = 2, start_vcol = 44 }))
eq({ all = 3, fill = 1 }, api.nvim_win_text_height(0, { start_row = 2, start_vcol = 45 }))
eq({ all = 3, fill = 1 }, api.nvim_win_text_height(0, { start_row = 2, start_vcol = 89 }))
eq({ all = 3, fill = 1 }, api.nvim_win_text_height(0, { start_row = 2, start_vcol = 90 }))
eq({ all = 3, fill = 1 }, api.nvim_win_text_height(0, { start_row = 2, start_vcol = X }))
eq({ all = 8, fill = 3, end_row = 7, end_vcol = 1 }, api.nvim_win_text_height(0, {}))
eq(
{ all = 5, fill = 2, end_row = 2, end_vcol = 0 },
api.nvim_win_text_height(0, { end_row = 2 })
)
eq(
{ all = 5, fill = 2, end_row = 2, end_vcol = 0 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = X })
)
eq(
{ all = 5, fill = 2, end_row = 2, end_vcol = 0 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 90 })
)
eq(
{ all = 5, fill = 2, end_row = 2, end_vcol = 0 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 46 })
)
eq(
{ all = 5, fill = 2, end_row = 2, end_vcol = 0 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 45 })
)
eq(
{ all = 5, fill = 2, end_row = 2, end_vcol = 0 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 1 })
)
eq(
{ all = 4, fill = 2, end_row = 2, end_vcol = 0 },
api.nvim_win_text_height(0, { end_row = 2, end_vcol = 0 })
)
eq(
{ all = 6, fill = 3, end_row = 7, end_vcol = 1 },
api.nvim_win_text_height(0, { start_row = 2 })
)
eq(
{ all = 4, fill = 1, end_row = 7, end_vcol = 1 },
api.nvim_win_text_height(0, { start_row = 2, start_vcol = 0 })
)
eq(
{ all = 4, fill = 1, end_row = 7, end_vcol = 1 },
api.nvim_win_text_height(0, { start_row = 2, start_vcol = 44 })
)
eq(
{ all = 3, fill = 1, end_row = 7, end_vcol = 1 },
api.nvim_win_text_height(0, { start_row = 2, start_vcol = 45 })
)
eq(
{ all = 3, fill = 1, end_row = 7, end_vcol = 1 },
api.nvim_win_text_height(0, { start_row = 2, start_vcol = 89 })
)
eq(
{ all = 3, fill = 1, end_row = 7, end_vcol = 1 },
api.nvim_win_text_height(0, { start_row = 2, start_vcol = 90 })
)
eq(
{ all = 3, fill = 1, end_row = 7, end_vcol = 1 },
api.nvim_win_text_height(0, { start_row = 2, start_vcol = X })
)
end)
it('with virt_lines above max_height row', function()
screen:try_resize(45, 10)
exec('call setline(1, range(1, 7) + ["foo"->repeat(20)])')
api.nvim_buf_set_extmark(0, ns, 6, 0, { virt_lines = { { { 'VIRT LINE 1' } } } })
screen:expect([[
^1 |
2 |
3 |
4 |
5 |
6 |
7 |
VIRT LINE 1 |
foofoofoofoofoofoofoofoofoofoofoofoofoofoo{1:@@@}|
|
]])
eq(
{ all = 10, fill = 1, end_row = 7, end_vcol = 45 },
api.nvim_win_text_height(0, { max_height = api.nvim_win_get_height(0) })
)
end)
end)