Skip to content

Commit 53090ab

Browse files
lewis6991github-actions[bot]
authored andcommitted
fix(statusline): scope truncation bookkeeping
Limit the default truncation item to the current recursion range so nested `nvim_eval_statusline()` calls don't reuse stale `stl_items` pointers. Add a functional regression that evaluates a Lua statusline helper which forces truncation to ensure the nested scenario stays stable. AI-Assist: OpenAI ChatGPT Fixes #36616 (cherry picked from commit e9b6474)
1 parent 63c5a10 commit 53090ab

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

src/nvim/statusline.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,7 +1969,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
19691969
int width = vim_strsize(out);
19701970
if (maxwidth > 0 && width > maxwidth && (!stcp || width > MAX_STCWIDTH)) {
19711971
// Result is too long, must truncate somewhere.
1972-
int item_idx = 0;
1972+
int item_idx = evalstart;
19731973
char *trunc_p;
19741974

19751975
// If there are no items, truncate from beginning
@@ -1979,8 +1979,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
19791979
// Otherwise, look for the truncation item
19801980
} else {
19811981
// Default to truncating at the first item
1982-
trunc_p = stl_items[0].start;
1983-
item_idx = 0;
1982+
trunc_p = stl_items[item_idx].start;
19841983

19851984
for (int i = evalstart; i < itemcnt + evalstart; i++) {
19861985
if (stl_items[i].type == Trunc) {

test/functional/ui/statusline_spec.lua

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,4 +802,26 @@ describe('statusline', function()
802802
|
803803
]])
804804
end)
805+
806+
it('truncation inside nested nvim_eval_statusline does not crash #36616', function()
807+
exec_lua(function()
808+
function _G.statusline_truncating()
809+
local win = vim.api.nvim_get_current_win()
810+
local res = vim.api.nvim_eval_statusline('%f', { winid = win, maxwidth = 5 })
811+
return res.str
812+
end
813+
vim.o.laststatus = 2
814+
vim.o.statusline = '%#Special#B:%{%v:lua.statusline_truncating()%}'
815+
end)
816+
local truncated = exec_lua(function()
817+
return vim.api.nvim_eval_statusline('%f', { maxwidth = 5 }).str
818+
end)
819+
local rendered = exec_lua(function()
820+
return vim.api.nvim_eval_statusline(
821+
vim.o.statusline,
822+
{ winid = vim.api.nvim_get_current_win() }
823+
).str
824+
end)
825+
eq('B:' .. truncated, rendered)
826+
end)
805827
end)

0 commit comments

Comments
 (0)