commit 8305af9bd2eb645d4a0be39d32bea5dc81fe69a1
parent 6256adde2f8b3caf67db48b2a9ade5f1874928a2
Author: luukvbaal <luukvbaal@gmail.com>
Date: Sat, 3 May 2025 23:24:11 +0200
fix(statusline): clear ruler when it is no longer drawn #33765
Problem: Ruler is not cleared from the screen/ext_messages state when
it is no longer drawn after e.g. `set noruler` or when moving
from a floating to a regular window.
Solution: Remember if ruler was drawn and clear it.
Diffstat:
3 files changed, 39 insertions(+), 42 deletions(-)
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
@@ -1118,20 +1118,7 @@ int showmode(void)
clear_showcmd();
}
- // If the current or last window has no status line and global statusline is disabled,
- // the ruler is after the mode message and must be redrawn
- win_T *ruler_win = curwin->w_status_height == 0 ? curwin : lastwin_nofloating();
- if (redrawing() && ruler_win->w_status_height == 0 && global_stl_height() == 0
- && !(p_ch == 0 && !ui_has(kUIMessages))) {
- if (!ui_has(kUIMessages)) {
- grid_line_start(&msg_grid_adj, Rows - 1);
- }
- win_redr_ruler(ruler_win);
- if (!ui_has(kUIMessages)) {
- grid_line_flush();
- }
- }
-
+ redraw_ruler(); // check if ruler should be redrawn
redraw_cmdline = false;
redraw_mode = false;
clear_cmdline = false;
diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c
@@ -333,9 +333,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
int start_col = col;
// Draw each snippet with the specified highlighting.
- if (!draw_ruler) {
- screengrid_line_start(grid, row, 0);
- }
+ screengrid_line_start(grid, row, 0);
int curattr = attr;
char *p = buf;
@@ -363,10 +361,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
// fill up with "fillchar"
grid_line_fill(col, maxcol, fillchar, curattr);
-
- if (!draw_ruler) {
- grid_line_flush();
- }
+ grid_line_flush();
// Fill the tab_page_click_defs, w_status_click_defs or w_winbar_click_defs array for clicking
// in the tab page line, status line or window bar
@@ -399,14 +394,24 @@ void win_redr_winbar(win_T *wp)
entered = false;
}
-/// must be called after a grid_line_start() at the intended row
-void win_redr_ruler(win_T *wp)
+void redraw_ruler(void)
{
- bool is_stl_global = global_stl_height() > 0;
+ static int did_ruler_col = -1;
static bool did_show_ext_ruler = false;
+ win_T *wp = curwin->w_status_height == 0 ? curwin : lastwin_nofloating();
+ bool is_stl_global = global_stl_height() > 0;
- // If 'ruler' off, don't do anything
- if (!p_ru) {
+ // Check if ruler should be drawn, clear if it was drawn before.
+ if (!p_ru || wp->w_status_height > 0 || is_stl_global || (p_ch == 0 && !ui_has(kUIMessages))) {
+ if (did_ruler_col > 0 && ui_has(kUIMessages)) {
+ ui_call_msg_ruler((Array)ARRAY_DICT_INIT);
+ did_show_ext_ruler = false;
+ } else if (did_ruler_col > 0) {
+ msg_col = did_ruler_col;
+ msg_row = Rows - 1;
+ msg_clr_eos();
+ }
+ did_ruler_col = -1;
return;
}
@@ -418,8 +423,7 @@ void win_redr_ruler(win_T *wp)
// Don't draw the ruler while doing insert-completion, it might overwrite
// the (long) mode message.
- win_T *ruler_win = curwin->w_status_height == 0 ? curwin : lastwin_nofloating();
- if (wp == ruler_win && ruler_win->w_status_height == 0 && !is_stl_global) {
+ if (wp->w_status_height == 0 && !is_stl_global) {
if (edit_submode != NULL) {
return;
}
@@ -513,6 +517,7 @@ void win_redr_ruler(win_T *wp)
ADD_C(content, ARRAY_OBJ(chunk));
ui_call_msg_ruler(content);
did_show_ext_ruler = true;
+ did_ruler_col = 1;
} else {
if (did_show_ext_ruler) {
ui_call_msg_ruler((Array)ARRAY_DICT_INIT);
@@ -528,8 +533,11 @@ void win_redr_ruler(win_T *wp)
}
}
- int w = grid_line_puts(off + this_ru_col, buffer, -1, attr);
- grid_line_fill(off + this_ru_col + w, off + width, fillchar, attr);
+ grid_line_start(&msg_grid_adj, Rows - 1);
+ did_ruler_col = off + this_ru_col;
+ int w = grid_line_puts(did_ruler_col, buffer, -1, attr);
+ grid_line_fill(did_ruler_col + w, off + width, fillchar, attr);
+ grid_line_flush();
}
}
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
@@ -1834,31 +1834,33 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim
it('supports ruler with laststatus=0', function()
command('set ruler laststatus=0')
- screen:expect {
- grid = [[
+ screen:expect([[
^ |
{1:~ }|*5
0,0-1 All |
- ]],
- }
+ ]])
command('hi MsgArea guibg=#333333')
- screen:expect {
- grid = [[
+ screen:expect([[
^ |
{1:~ }|*5
{101: 0,0-1 All }|
- ]],
- }
+ ]])
command('set rulerformat=%15(%c%V\\ %p%%%)')
- screen:expect {
- grid = [[
+ screen:expect([[
^ |
{1:~ }|*5
{101: 0,0-1 100% }|
- ]],
- }
+ ]])
+
+ -- Ruler is cleared when it is no longer drawn.
+ command('set noruler')
+ screen:expect([[
+ ^ |
+ {1:~ }|*5
+ {101: }|
+ ]])
end)
it('supports echo with CRLF line separators', function()