fix(statusline): default 'statusline' improvements #41597

Problem: there should be exactly one cell of padding between sections,
and exactly one cell of minimum padding between the left and the right.
- Spaces between sections waste space when a section is empty.
  According to a comment in #33036, this was the reason to avoid `%k`
  and implement the keymap section with a vim expression, but other
  sections still have this problem.
- The diagnostics section wastes space because it is not entirely empty
  when there are diagnostics in another buffer.
- The terminal exit code section can touch the right side, e.g. the
  ruler, even though it belongs to the left side.
Solution:
- Use auto-hiding item groups (`%(` without width fields) to get rid of
  unneeded spaces when a section shows no information.
  This simplifies the 'showcmd' and 'keymap' sections in particular.
- As a slight simplification, `term_exitcode` is moved into the flags
  section since it is formatted with square brackets like a flag.
- Count the diagnostics for the current buffer specifically.
- Ensure at least one cell of padding between the left and the right
  side by adding a space next to the separator `%=`.

Problem: some sections are implemented with `%{%`, even though
reevaluation of the expression result is not needed.
This leads to otherwise needless %-escaping in `progress_status`.
Solution: use `%{` instead.

Problem: `%{` and `%{%` (without items) replace spaces with fillchars.
This looks out-of-place inside the terminal exit code section, and in
contrast to all other sections, the 'busy' section is surrounded by
fillchars, which looks inconsistent, and with some terminal-font
combinations, ◐ overlaps the fillchar, e.g. Alacritty & JetBrains Mono.
Solution: use non-breaking spaces U+202F to avoid fillchar substitution.

Problem: sections that appear/disappear frequently can make otherwise
more stable sections jump around a lot.
Solution: sort the sections on the right roughly by volatility:
'showcmd' in first place, 'keymap' next to the ruler.
This commit is contained in:
Sébastien Hoffmann
2026-09-03 18:44:30 +02:00
committed by GitHub
parent ba0ee081c8
commit 3808c00fc8
5 changed files with 27 additions and 27 deletions

View File

@@ -121,7 +121,8 @@ function M.term_exitcode()
local info = vim.api.nvim_get_chan_info(chan_id)
if info.exitcode and info.exitcode >= 0 then
return string.format('[Exit: %d]', info.exitcode)
-- use non-breaking space to avoid fillchar
return string.format('[Exit:\226\128\175%d]', info.exitcode)
end
return ''
end

View File

@@ -7074,7 +7074,7 @@ vim.wo.stc = vim.wo.statuscolumn
---
---
--- @type string
vim.o.statusline = "%<%f %h%w%m%r %{% v:lua.require('vim._core.util').term_exitcode() %}%=%{% luaeval('(package.loaded[''vim.ui''] and vim.api.nvim_get_current_win() == tonumber(vim.g.actual_curwin or -1) and vim.ui.progress_status()) or '''' ')%}%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &busy > 0 ? '◐ ' : '' %}%{% luaeval('(package.loaded[''vim.diagnostic''] and next(vim.diagnostic.count()) and vim.diagnostic.status() .. '' '') or '''' ') %}%{% &ruler ? &rulerformat : '' %}"
vim.o.statusline = "%<%f%( %h%w%m%r%{ v:lua.require('vim._core.util').term_exitcode() }%)%= %(%-10S %)%{ &busy > 0 ? '◐ ' : '' }%(%{ luaeval('(package.loaded[''vim.ui''] and vim.api.nvim_get_current_win() == tonumber(vim.g.actual_curwin or -1) and vim.ui.progress_status()) or '''' ')} %)%{% luaeval('(package.loaded[''vim.diagnostic''] and next(vim.diagnostic.count(0)) and vim.diagnostic.status() .. '' '') or '''' ') %}%(%k %)%{% &ruler ? &rulerformat : '' %}"
vim.o.stl = vim.o.statusline
vim.wo.statusline = vim.o.statusline
vim.wo.stl = vim.wo.statusline

View File

@@ -385,7 +385,7 @@ do
sum = sum + (progress_item.percent or 0)
end
local avg = math.floor(sum / count)
return string.format('%d%%%%(%d) ', avg, count)
return string.format('%d%%(%d)', avg, count)
end
end