commit e9b6474ae7ea847ab1854fe5bc28b289f7eb2775
parent 69b286c3bfb386597af9fc66625fdb6934594544
Author: Lewis Russell <lewis6991@gmail.com>
Date: Wed, 19 Nov 2025 10:59:12 +0000
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
Diffstat:
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c
@@ -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) {
diff --git a/test/functional/ui/statusline_spec.lua b/test/functional/ui/statusline_spec.lua
@@ -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()