commit 7ba043f0f31cc0c9a783bcb28d6f700a42ba6ff4
parent 98ec3fdf744ffce5e685da76a5ef6f2b000649f6
Author: luukvbaal <luukvbaal@gmail.com>
Date: Mon, 21 Apr 2025 13:48:26 +0200
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").
Diffstat:
10 files changed, 424 insertions(+), 186 deletions(-)
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
@@ -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.
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
@@ -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
diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua
@@ -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
diff --git a/runtime/lua/vim/_meta/api_keysets.lua b/runtime/lua/vim/_meta/api_keysets.lua
@@ -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?
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
@@ -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
diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h
@@ -229,6 +229,7 @@ typedef struct {
Integer end_row;
Integer start_vcol;
Integer end_vcol;
+ Integer max_height;
} Dict(win_text_height);
typedef struct {
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
@@ -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;
}
diff --git a/src/nvim/plines.c b/src/nvim/plines.c
@@ -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;
}
diff --git a/src/nvim/window.c b/src/nvim/window.c
@@ -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;
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
@@ -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
@@ -902,6 +887,10 @@ describe('API/win', function()
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(
api.nvim_win_text_height,
@@ -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 = 0, fill = 0 },
+ ]])
+ 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 = 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 = 6, fill = 0, end_row = 0, end_vcol = 252 },
+ api.nvim_win_text_height(0, { start_row = 0, end_row = 0 })
+ )
eq(
- { all = 0, fill = 0 },
+ { 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)