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
This commit is contained in:
Lewis Russell
2025-11-19 10:59:12 +00:00
committed by Lewis Russell
parent 69b286c3bf
commit e9b6474ae7
2 changed files with 24 additions and 3 deletions

View File

@@ -1902,7 +1902,7 @@ stcsign:
int width = vim_strsize(out);
if (maxwidth > 0 && width > maxwidth && (!stcp || width > MAX_STCWIDTH)) {
// Result is too long, must truncate somewhere.
int item_idx = 0;
int item_idx = evalstart;
char *trunc_p;
// If there are no items, truncate from beginning
@@ -1912,8 +1912,7 @@ stcsign:
// Otherwise, look for the truncation item
} else {
// Default to truncating at the first item
trunc_p = stl_items[0].start;
item_idx = 0;
trunc_p = stl_items[item_idx].start;
for (int i = evalstart; i < itemcnt + evalstart; i++) {
if (stl_items[i].type == Trunc) {

View File

@@ -802,6 +802,28 @@ describe('statusline', function()
|
]])
end)
it('truncation inside nested nvim_eval_statusline does not crash #36616', function()
exec_lua(function()
function _G.statusline_truncating()
local win = vim.api.nvim_get_current_win()
local res = vim.api.nvim_eval_statusline('%f', { winid = win, maxwidth = 5 })
return res.str
end
vim.o.laststatus = 2
vim.o.statusline = '%#Special#B:%{%v:lua.statusline_truncating()%}'
end)
local truncated = exec_lua(function()
return vim.api.nvim_eval_statusline('%f', { maxwidth = 5 }).str
end)
local rendered = exec_lua(function()
return vim.api.nvim_eval_statusline(
vim.o.statusline,
{ winid = vim.api.nvim_get_current_win() }
).str
end)
eq('B:' .. truncated, rendered)
end)
end)
describe('default statusline', function()