From c5be3315027de331bc201c3a4bb69180e33f6360 Mon Sep 17 00:00:00 2001 From: Sébastien Hoffmann Date: Sun, 28 Jun 2026 14:40:33 +0200 Subject: 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 --- runtime/lua/vim/_meta/options.gen.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/_meta/options.gen.lua b/runtime/lua/vim/_meta/options.gen.lua index e7296cea5d..7b76ddbdc4 100644 --- a/runtime/lua/vim/_meta/options.gen.lua +++ b/runtime/lua/vim/_meta/options.gen.lua @@ -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 = "" -- cgit From fcc391d89a2a30b02c3ba25a6351d37cdcd79e12 Mon Sep 17 00:00:00 2001 From: Sébastien Hoffmann Date: Sun, 5 Jul 2026 11:06:46 +0200 Subject: fix(ui2): clear showcmd virt_text together with search count Problem: when the search count is displayed, the showcmd virt_text is set to 11 empty spaces to ensure a consistent distance between search count and ruler, or screen edge in case of noruler. But when the search count is removed to make place for a message, the empty dummy showcmd remains and unnecessarily erases part of the message. Solution: properly remove showcmd together with search count. --- runtime/lua/vim/_core/ui2/messages.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/_core/ui2/messages.lua b/runtime/lua/vim/_core/ui2/messages.lua index 07dc9c205a..1961084c38 100644 --- a/runtime/lua/vim/_core/ui2/messages.lua +++ b/runtime/lua/vim/_core/ui2/messages.lua @@ -462,6 +462,7 @@ function M.msg_show(kind, content, replace_last, _, append, id, trigger) M.cmd.last_emsg = (kind == 'emsg' or kind == 'wmsg') and os.time() or M.cmd.last_emsg -- Should clear the search count now, mark itself is cleared by invalidate. M.virt.last[M.virt.idx.search][1] = nil + M.virt.last[M.virt.idx.cmd] = {} end -- When message was emitted below an already expanded cmdline, move and route to pager. tgt = ui.cmd.expand > 0 and 'pager' or tgt -- cgit From 2473cb62b7f4d77e2691d5040e06a2a61ab34462 Mon Sep 17 00:00:00 2001 From: Sébastien Hoffmann Date: Sun, 5 Jul 2026 13:55:22 +0200 Subject: fix(ui2): correctly crop message at multibyte/multicell character --- runtime/lua/vim/_core/ui2/messages.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/_core/ui2/messages.lua b/runtime/lua/vim/_core/ui2/messages.lua index 1961084c38..4182fd573b 100644 --- a/runtime/lua/vim/_core/ui2/messages.lua +++ b/runtime/lua/vim/_core/ui2/messages.lua @@ -126,7 +126,7 @@ local function set_virttext(type, tgt) }) local row = texth.end_row local col = fn.virtcol2col(win, row + 1, texth.end_vcol) - local scol = fn.screenpos(win, row + 1, col).col ---@type integer + local scol = fn.screenpos(win, row + 1, col).endcol ---@type integer if type ~= 'last' then -- Calculate at which column to place the virt_text such that it is at the end @@ -179,7 +179,8 @@ local function set_virttext(type, tgt) -- Crop text on last screen row and find byte offset to place mark at. local vcol = texth.end_vcol - (scol - M.cmd.last_col) - col = vcol <= 0 and 0 or fn.virtcol2col(win, row + 1, vcol) + col = vcol <= 0 and 0 or fn.virtcol2col(win, row + 1, vcol + 1) - 1 + scol = fn.screenpos(win, row + 1, col).endcol M.cmd.prev_msg = mode > 0 and '' or M.cmd.prev_msg M.virt.cmd = mode > 0 and { {}, {} } or M.virt.cmd api.nvim_buf_set_text(ui.bufs.cmd, row, col, row, -1, { mode > 0 and ' ' or '' }) -- cgit From 0ffd74ae85bf9c6c41c904775ec6ec6d8a3eebb6 Mon Sep 17 00:00:00 2001 From: Sébastien Hoffmann Date: Sat, 11 Jul 2026 16:38:12 +0200 Subject: fix(ui2): fix ruler on repeated messages Problem: a long message is cropped to keep the ruler visible. But when the message is repeated, it can be written over the ruler, while the repetition indicator "(1)" is still placed just before the ruler, which ends up somewhere inside the message. Solution: currently, long messages are only cropped when setting the 'last' virttext. Make sure this happens after a repeated long message. --- runtime/lua/vim/_core/ui2/messages.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/_core/ui2/messages.lua b/runtime/lua/vim/_core/ui2/messages.lua index 4182fd573b..7a6bd6e4c0 100644 --- a/runtime/lua/vim/_core/ui2/messages.lua +++ b/runtime/lua/vim/_core/ui2/messages.lua @@ -390,6 +390,13 @@ function M.show_msg(tgt, kind, content, replace_last, append, id) M.virt[tgt][M.virt.idx.dupe][1] = dupe > 0 and { 0, ('(%d)'):format(dupe) } or nil M.virt[tgt][M.virt.idx.spill][1] = tgt == 'cmd' and M.virt.cmd[M.virt.idx.spill][1] or nil set_virttext(tgt --[[@as 'cmd'|'msg']], tgt) + if tgt == 'cmd' then + -- make sure repeated long messages are cropped to keep the ruler intact + -- (if this is not scheduled, it breaks messages during textlock) + vim.schedule(function() + set_virttext('last', 'cmd') + end) + end end -- Reset message state the next event loop iteration. -- cgit From 935a14bb72f7b3b2da6c653314f6060901ed1f6d Mon Sep 17 00:00:00 2001 From: Sébastien Hoffmann Date: Wed, 8 Jul 2026 20:23:01 +0200 Subject: docs(ui2): deprecate v:echospace The purpose of `v:echospace` was to avoid disruptive "Press ENTER" prompts. Since those are no longer a problem with ui2, the complexity of maintaining it up-to-date is no longer justified. --- runtime/lua/vim/_meta/vvars.gen.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/_meta/vvars.gen.lua b/runtime/lua/vim/_meta/vvars.gen.lua index 3bc819b5a1..0154045f20 100644 --- a/runtime/lua/vim/_meta/vvars.gen.lua +++ b/runtime/lua/vim/_meta/vvars.gen.lua @@ -129,7 +129,7 @@ vim.v.dying = ... --- Number of screen cells that can be used for an `:echo` message --- in the last screen line before causing the `hit-enter` prompt ---- (or "overflow" with `ui2`). +--- (no longer applicable when `ui2` is enabled). --- --- Depends on 'showcmd', 'ruler' and 'columns'. You need to --- check 'cmdheight' for whether there are full-width lines -- cgit