fix(ui2)!: don't constrain ruler to ru_wid, fix leading item group

Problem: ui2's ruler is no longer of fixed width, and the internal width
variable `ru_wid` now acts as an arbitrary maximum, which is unnecessary
because the same can now be achieved transparently with an item group.
Furthermore, the old way of setting `ru_wid` with an overloaded subset
of the item group syntax leads to a number of inconsistencies. In
particular, when the configured ruler expression is reused for including
the ruler into the statusline, where the item group syntax is
interpreted in the usual way. The fact that this width is set in the
`minwid` position is more confusing now that it is a de-facto maximum.

Solution: for ui2, constrain the ruler only by half the screen width,
which previously was an additional limit relevant on small screens.
Skip the special-case treatment of the ruler's leading item group spec,
process it like a normal item group.

Example: the current fallback ruler expression in the default statusline
now actually works for `rulerformat` itself:
  set rulerformat=%-14.(%l,%c%V%)\ %P
because the result can naturally expand to 18 cells instead of being
truncated to the default 17 cells, and removing the period after
`minwid` doesn't change the result, whereas before, it would unhelpfully
lead to setting the fixed ruler width to 14 cells.

BREAKING CHANGE: if the user used to set the ruler's fixed width, it
will now be treated as minimum instead of a maximum width, which in
practice increases backwards-compatibility with ui1 and vim. The main
remaining difference is that item groups are right-aligned by default,
but backwards-compatibility can be achieved by setting a negative
`minwid`, which ui1 and vim ignore. To restore the previous fixed width,
specify `maxwid` as well, but this does not work in ui1 and vim.
If `rulerformat` contains a `%=` without enclosing item group, it will
now expand to fill half the screen width. But in that case, it will
already spread out similarly in the new expression-based statusline, so
consistency of the ruler in both positions is increased.
To simulate the previous default behaviour, wrap it in `%-17.17(...%)`.
For best compatibility and reuse with vim, leave out `maxwid` and make
`minwid` negative, e.g. `%-20(...%)`.

fix https://github.com/neovim/neovim/issues/40247
This commit is contained in:
Sébastien Hoffmann
2026-06-28 14:40:33 +02:00
parent 0f1e0a7900
commit c5be331502
6 changed files with 39 additions and 5 deletions

View File

@@ -44,7 +44,11 @@ DIAGNOSTICS
OPTIONS
todo
When |ui2| is enabled, since the ruler is no longer a left-aligned box of
fixed width, there is no longer an inconsistent special handling of item
groups in 'rulerformat' to configure that fixed width. An old-style left-
aligned fixed-width ruler can now be achieved by using item groups exactly
as they are documented, e.g. `%-20.20(...%)`.
TREESITTER

View File

@@ -5169,6 +5169,13 @@ A jump table for the options with a short description can be found at |Q_op|.
Example: >vim
set rulerformat=%15(%c%V\ %p%%%)
<
This looks like an item group, but there are some differences in this
particular case. Most notably, the width is fixed and not a minimum,
and the ruler is left-aligned, whereas the alignment of item groups is
configurable and right-aligned by default.
When |ui2| is enabled, the ruler no longer has a fixed width and the
item group syntax has no special meaning for 'rulerformat'.
*'runtimepath'* *'rtp'* *vimfiles*
'runtimepath' 'rtp' string (default "$XDG_CONFIG_HOME/nvim,

View File

@@ -5380,6 +5380,13 @@ vim.go.ru = vim.go.ruler
--- set rulerformat=%15(%c%V\ %p%%%)
--- ```
---
--- This looks like an item group, but there are some differences in this
--- particular case. Most notably, the width is fixed and not a minimum,
--- and the ruler is left-aligned, whereas the alignment of item groups is
--- configurable and right-aligned by default.
---
--- When `ui2` is enabled, the ruler no longer has a fixed width and the
--- item group syntax has no special meaning for 'rulerformat'.
---
--- @type string
vim.o.rulerformat = ""

View File

@@ -7073,6 +7073,13 @@ local options = {
Example: >vim
set rulerformat=%15(%c%V\ %p%%%)
<
This looks like an item group, but there are some differences in this
particular case. Most notably, the width is fixed and not a minimum,
and the ruler is left-aligned, whereas the alignment of item groups is
configurable and right-aligned by default.
When |ui2| is enabled, the ruler no longer has a fixed width and the
item group syntax has no special meaning for 'rulerformat'.
]=],
full_name = 'rulerformat',
modelineexpr = true,

View File

@@ -52,6 +52,7 @@
#include "nvim/tag.h"
#include "nvim/terminal.h"
#include "nvim/types_defs.h"
#include "nvim/ui.h"
#include "nvim/vim_defs.h"
#include "nvim/window.h"
#include "nvim/winfloat.h"
@@ -1917,7 +1918,7 @@ static const char *did_set_statustabline_rulerformat(optset_T *args, bool rulerf
win_config_float(win, win->w_config);
}
if (rulerformat && *s == '%') {
if (rulerformat && !ui_has(kUIMessages) && *s == '%') {
// set ru_wid if 'ruf' starts with "%99("
if (*++s == '-') { // ignore a '-'
s++;
@@ -1932,8 +1933,8 @@ static const char *did_set_statustabline_rulerformat(optset_T *args, bool rulerf
errmsg = check_stl_option(p_ruf);
}
}
} else if (rulerformat || s[0] != '%' || s[1] != '!') {
// check 'statusline', 'winbar', 'tabline' or 'statuscolumn'
} else if (s[0] != '%' || s[1] != '!') {
// check 'statusline', 'rulerformat', 'winbar', 'tabline' or 'statuscolumn'
// only if it doesn't start with "%!"
errmsg = check_stl_option(s);
}

View File

@@ -308,7 +308,15 @@ static void win_redr_stl_expr(win_T *wp, bool draw_winbar, bool draw_ruler, bool
wp->w_status_click_defs = stl_alloc_click_defs(wp->w_status_click_defs, maxwidth,
&wp->w_status_click_defs_size);
if (draw_ruler) {
if (draw_ruler && ui_event) {
stl = p_ruf;
opt_idx = kOptRulerformat;
maxwidth = Columns / 2;
if (!in_status_line) {
fillchar = schar_from_ascii(' ');
group = HLF_MSG;
}
} else if (draw_ruler) {
stl = p_ruf;
opt_idx = kOptRulerformat;
// advance past any leading group spec - implicit in ru_col