refactor(ruler)!: replace C implementation with 'rulerformat' expression

Problem:
The default 'ruler' is implemented in C instead of the 'statusline' DSL.

Solution:
Replace the C implementation with a default 'rulerformat' expression.
This is a continuation of #1248 and #33036.

Advantages:
- configuration is more discoverable, the default being a useful example
- users and plugins can augment the default
- code reuse and less C code to maintain
- ui2: due to the use of an item group with `minwid`, it can expand
  instead of truncating when the content gets too long, which is
  particularly useful for locales with long translations of Top/Bot/All

Implementation details:
As is the case for 'statusline', when trying to set 'rulerformat' to an
empty string, the default expression is restored instead, mimicking how
previously the default C implementation would have been activated.
Just like before, `:set rulerformat=` and `:set rulerformat&` have the
same effect, and the ruler is disabled with `:set noruler`.

The default expression uses an item group with `%=`, unlike the fallback
in the previous default statusline `%-14.(%l,%c%V%) %P`, because the
total width and how it is configured is immediately clear without
documentation, it is a more useful pattern in general that works when
both sides have flexible width, and it also works for vim, which is
useful for configuration sharing/reuse.

A truncation marker `%<` is added at the end to mimic how at small
screen widths, the scroll percentage would disappear first, so that the
cursor position can remain fully visible.

BREAKING CHANGES:
- `&rulerformat` can no longer be set to an empty string
- ui2: the default ruler is no longer of fixed width, but can expand
- at very small screen widths (< 36 columns)
  - ui2: it will no longer try to shrink white-space before truncating
  - it truncates gradually from the right, whereas previously, the
    scroll percentage would disappear all at once
- l10n can no longer add a space after the comma between line and column
  (this was only done for one language: Ukrainian)
This commit is contained in:
Sébastien Hoffmann
2026-07-20 21:35:16 +02:00
parent 9be130304d
commit ca07e505f9
12 changed files with 224 additions and 226 deletions

View File

@@ -561,14 +561,14 @@ describe('API/win', function()
api.nvim_set_option_value('statusline', 'window-status', { win = 0 })
eq('window-status', api.nvim_get_option_value('statusline', { win = 0 }))
eq(
"%<%f %{%nvim_eval_statusline('%h%w%m%r', {'maxwidth': 30}).width > 0 ? '%h%w%m%r ' : ''%}%=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}",
"%<%f %{%nvim_eval_statusline('%h%w%m%r', {'maxwidth': 30}).width > 0 ? '%h%w%m%r ' : ''%}%=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? &rulerformat : '' %}",
api.nvim_get_option_value('statusline', { scope = 'global' })
)
command('set modified')
command('enew') -- global-local: not preserved in new buffer
-- confirm local value was not copied
eq(
"%<%f %{%nvim_eval_statusline('%h%w%m%r', {'maxwidth': 30}).width > 0 ? '%h%w%m%r ' : ''%}%=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}",
"%<%f %{%nvim_eval_statusline('%h%w%m%r', {'maxwidth': 30}).width > 0 ? '%h%w%m%r ' : ''%}%=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &ruler ? &rulerformat : '' %}",
api.nvim_get_option_value('statusline', { win = 0 })
)
eq('', eval('&l:statusline'))