From e8a0b400d8d35d994d2b2ef639566f6d36ecc729 Mon Sep 17 00:00:00 2001 From: Volodymyr Chernetskyi Date: Sun, 6 Sep 2026 17:24:52 +0200 Subject: [PATCH] fix(statusline): "%.0" renders garbage #41685 Problem: `getdigits_int(pp, strict, def)` returns `def` only when the number fails to parse or overflows, never when the text parses to a literal `0`, so `%.0` leaves `maxwid` at 0. Both render paths then break down: `l > maxwid` is always true and `while (l >= maxwid)` consumes the whole string, so `%.0f` comes out as `<` and `%.0l` as `0>3`. Vim guards for this right after the same call. Nvim had the guard too until 3344cffe7b ("getdigits: introduce `strict`, `def` parameters"), which folded it into the new `def` argument and so changed what a literal zero means. The neighbouring `minwid` call was translated correctly. Solution: Fall back to 50 when the parsed width is not positive, as Vim does. AI-assisted --- src/nvim/statusline.c | 3 +++ test/functional/api/vim_spec.lua | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 9876936d5d..7d77a6989a 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -1377,6 +1377,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op fmt_p++; if (ascii_isdigit(*fmt_p)) { maxwid = getdigits_int(&fmt_p, false, 50); + if (maxwid <= 0) { // overflow or an explicit zero + maxwid = 50; + } } } diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 16a2acb0e5..b42a8bbb01 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -4537,6 +4537,13 @@ describe('API', function() }, api.nvim_eval_statusline('Should be truncated%<', { maxwidth = 15 })) end) + it('does not take a zero item width literally', function() + command('file some/dir/testfile.txt') + eq({ str = 'abc', width = 3 }, api.nvim_eval_statusline('%.0(abc%)', {})) + eq(api.nvim_eval_statusline('%.50f', {}), api.nvim_eval_statusline('%.0f', {})) + eq(api.nvim_eval_statusline('%.50l', {}), api.nvim_eval_statusline('%.0l', {})) + end) + it('has correct default fillchar', function() local oldwin = api.nvim_get_current_win() command('set fillchars=stl:#,stlnc:$,wbr:%')