Skip to content

Commit

Permalink
fix(folds): cursorline highlight is not always applied on closed folds
Browse files Browse the repository at this point in the history
Problem:    The cursorline highlight logic checks for `w_cursor.lnum`
            which may be different from the line number passed to
            `win_line()` even when the cursor is actually on that line.
Solution:   Update cursor line highlight logic to check for the line
            number of the start of a closed fold if necessary.

Fix #22232
  • Loading branch information
luukvbaal committed Feb 13, 2023
1 parent 5d3769e commit c3bd43c
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 87 deletions.
1 change: 1 addition & 0 deletions src/nvim/buffer_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,7 @@ struct window_S {
// time through cursupdate() to the
// current virtual column

linenr_T w_cursorline; ///< where cursor line is (different for closed fold)
linenr_T w_last_cursorline; ///< where last 'cursorline' was drawn
pos_T w_last_cursormoved; ///< for CursorMoved event

Expand Down
6 changes: 3 additions & 3 deletions src/nvim/drawline.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode,
static bool use_cursor_line_sign(win_T *wp, linenr_T lnum)
{
return wp->w_p_cul
&& lnum == wp->w_cursor.lnum
&& lnum == wp->w_cursorline
&& (wp->w_p_culopt_flags & CULOPT_NBR);
}

Expand Down Expand Up @@ -517,7 +517,7 @@ static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_st
static bool use_cursor_line_nr(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines)
{
return wp->w_p_cul
&& lnum == wp->w_cursor.lnum
&& lnum == wp->w_cursorline
&& (wp->w_p_culopt_flags & CULOPT_NBR)
&& (row == startrow + filler_lines
|| (row > startrow + filler_lines
Expand Down Expand Up @@ -960,7 +960,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
filler_todo = filler_lines;

// Cursor line highlighting for 'cursorline' in the current window.
if (lnum == wp->w_cursor.lnum) {
if (lnum == wp->w_cursorline) {
// Do not show the cursor line in the text when Visual mode is active,
// because it's not clear what is selected then.
if (wp->w_p_cul && !(wp == curwin && VIsual_active)
Expand Down
11 changes: 8 additions & 3 deletions src/nvim/drawscreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1549,6 +1549,11 @@ static void win_update(win_T *wp, DecorProviders *providers)
}

bool cursorline_standout = win_cursorline_standout(wp);
// Make sure that the cursorline on a closed fold is redrawn
if (cursorline_standout) {
foldinfo_T cul_fi = fold_info(wp, wp->w_cursor.lnum);
wp->w_cursorline = cul_fi.fi_level && cul_fi.fi_lines ? cul_fi.fi_lnum : wp->w_cursor.lnum;
}

win_check_ns_hl(wp);

Expand Down Expand Up @@ -1604,7 +1609,7 @@ static void win_update(win_T *wp, DecorProviders *providers)
// if lines were inserted or deleted
|| (wp->w_match_head != NULL
&& buf->b_mod_xlines != 0)))))
|| (cursorline_standout && lnum == wp->w_cursor.lnum)
|| (cursorline_standout && lnum == wp->w_cursorline)
|| lnum == wp->w_last_cursorline) {
if (lnum == mod_top) {
top_to_mod = false;
Expand Down Expand Up @@ -1849,9 +1854,9 @@ static void win_update(win_T *wp, DecorProviders *providers)

// Now that the window has been redrawn with the old and new cursor line,
// update w_last_cursorline.
wp->w_last_cursorline = cursorline_standout ? wp->w_cursor.lnum : 0;
wp->w_last_cursorline = cursorline_standout ? wp->w_cursorline : 0;

wp->w_last_cursor_lnum_rnu = wp->w_p_rnu ? wp->w_cursor.lnum : 0;
wp->w_last_cursor_lnum_rnu = wp->w_p_rnu ? wp->w_cursorline : 0;

if (idx > wp->w_lines_valid) {
wp->w_lines_valid = idx;
Expand Down
207 changes: 126 additions & 81 deletions test/functional/ui/fold_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ local meths = helpers.meths
local exec = helpers.exec
local exec_lua = helpers.exec_lua
local assert_alive = helpers.assert_alive
local poke_eventloop = helpers.poke_eventloop


local content1 = [[
Expand Down Expand Up @@ -90,112 +91,156 @@ describe("folded lines", function()
end)

it("highlights with CursorLineFold when 'cursorline' is set", function()
command("set cursorline foldcolumn=2 foldmethod=marker")
command("set number cursorline foldcolumn=2")
command("hi link CursorLineFold Search")
insert(content1)
feed("zf3j")
feed("ggzf3jj")
if multigrid then
screen:expect([[
## grid 1
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[3:---------------------------------------------]|
## grid 2
{7: }This is a |
{7: }valid English |
{7: }sentence composed by |
{7: }an exhausted developer |
{7: }in his cave. |
{6: }{12:^ }|
{1:~ }|
## grid 3
|
## grid 1
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[3:---------------------------------------------]|
## grid 2
{7:+ }{8: 1 }{5:+-- 4 lines: This is a················}|
{6: }{9: 5 }{12:^in his cave. }|
{7: }{8: 6 } |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
## grid 3
|
]])
else
screen:expect([[
{7: }This is a |
{7: }valid English |
{7: }sentence composed by |
{7: }an exhausted developer |
{7: }in his cave. |
{6: }{12:^ }|
{1:~ }|
|
{7:+ }{8: 1 }{5:+-- 4 lines: This is a················}|
{6: }{9: 5 }{12:^in his cave. }|
{7: }{8: 6 } |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]])
end
feed("k")
if multigrid then
screen:expect([[
## grid 1
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[3:---------------------------------------------]|
## grid 2
{7: }This is a |
{7: }valid English |
{7: }sentence composed by |
{7: }an exhausted developer |
{6: }{12:^in his cave. }|
{7: } |
{1:~ }|
## grid 3
|
## grid 1
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[3:---------------------------------------------]|
## grid 2
{6:+ }{9: 1 }{12:^+-- 4 lines: This is a················}|
{7: }{8: 5 }in his cave. |
{7: }{8: 6 } |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
## grid 3
|
]])
else
screen:expect([[
{7: }This is a |
{7: }valid English |
{7: }sentence composed by |
{7: }an exhausted developer |
{6: }{12:^in his cave. }|
{7: } |
{1:~ }|
|
{6:+ }{9: 1 }{12:^+-- 4 lines: This is a················}|
{7: }{8: 5 }in his cave. |
{7: }{8: 6 } |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]])
end
-- CursorLine is applied correctly with screenrow motions
feed("jgk")
poke_eventloop()
-- CursorLine is applied correctly when closing a fold when cursor is not at fold start
screen:expect_unchanged()
feed("zo4Gzc")
poke_eventloop()
screen:expect_unchanged()
command("set cursorlineopt=line")
if multigrid then
screen:expect([[
## grid 1
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[3:---------------------------------------------]|
## grid 2
{7: }This is a |
{7: }valid English |
{7: }sentence composed by |
{7: }an exhausted developer |
{7: }{12:^in his cave. }|
{7: } |
## grid 1
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[3:---------------------------------------------]|
## grid 2
{7:+ }{8: 1 }{12:^+-- 4 lines: This is a················}|
{7: }{8: 5 }in his cave. |
{7: }{8: 6 } |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
## grid 3
|
]])
else
screen:expect([[
{7:+ }{8: 1 }{12:^+-- 4 lines: This is a················}|
{7: }{8: 5 }in his cave. |
{7: }{8: 6 } |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
## grid 3
|
]])
end
command("set relativenumber cursorlineopt=number")
feed("jk")
if multigrid then
screen:expect([[
## grid 1
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[2:---------------------------------------------]|
[3:---------------------------------------------]|
## grid 2
{6:+ }{9:1 }{5:^+-- 4 lines: This is a················}|
{7: }{8: 1 }in his cave. |
{7: }{8: 2 } |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
## grid 3
|
]])
else
screen:expect([[
{7: }This is a |
{7: }valid English |
{7: }sentence composed by |
{7: }an exhausted developer |
{7: }{12:^in his cave. }|
{7: } |
{1:~ }|
|
{6:+ }{9:1 }{5:^+-- 4 lines: This is a················}|
{7: }{8: 1 }in his cave. |
{7: }{8: 2 } |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]])
end
end)
Expand Down

0 comments on commit c3bd43c

Please sign in to comment.