aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/buffer_defs.h9
-rw-r--r--src/nvim/drawline.c39
-rw-r--r--src/nvim/drawscreen.c20
-rw-r--r--test/functional/ui/fold_spec.lua132
4 files changed, 127 insertions, 73 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 3601dc7062..cace4b1364 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -1112,20 +1112,23 @@ struct window_S {
win_T *w_prev; ///< link to previous window
win_T *w_next; ///< link to next window
bool w_closing; ///< window is being closed, don't let
- /// autocommands close it too.
+ ///< autocommands close it too.
frame_T *w_frame; ///< frame containing this window
pos_T w_cursor; ///< cursor position in buffer
colnr_T w_curswant; ///< Column we want to be at. This is
- /// used to try to stay in the same column
- /// for up/down cursor motions.
+ ///< used to try to stay in the same column
+ ///< for up/down cursor motions.
int w_set_curswant; // If set, then update w_curswant the next
// time through cursupdate() to the
// current virtual column
+ linenr_T w_cursorline; ///< Where 'cursorline' should be drawn,
+ ///< can be different from w_cursor.lnum
+ ///< for closed folds.
linenr_T w_last_cursorline; ///< where last 'cursorline' was drawn
pos_T w_last_cursormoved; ///< for CursorMoved event
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index e205850314..3bd55dbe09 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -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);
}
@@ -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
@@ -547,6 +547,12 @@ static inline void get_line_number_str(win_T *wp, linenr_T lnum, char *buf, size
static int get_line_number_attr(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines)
{
+ if (use_cursor_line_nr(wp, lnum, row, startrow, filler_lines)) {
+ // TODO(vim): Can we use CursorLine instead of CursorLineNr
+ // when CursorLineNr isn't set?
+ return win_hl_attr(wp, HLF_CLN);
+ }
+
if (wp->w_p_rnu) {
if (lnum < wp->w_cursor.lnum) {
// Use LineNrAbove
@@ -558,12 +564,6 @@ static int get_line_number_attr(win_T *wp, linenr_T lnum, int row, int startrow,
}
}
- if (use_cursor_line_nr(wp, lnum, row, startrow, filler_lines)) {
- // TODO(vim): Can we use CursorLine instead of CursorLineNr
- // when CursorLineNr isn't set?
- return win_hl_attr(wp, HLF_CLN);
- }
-
return win_hl_attr(wp, HLF_N);
}
@@ -960,20 +960,17 @@ 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) {
- // 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)
- && wp->w_p_culopt_flags != CULOPT_NBR) {
- cul_screenline = (wp->w_p_wrap
- && (wp->w_p_culopt_flags & CULOPT_SCRLINE));
- if (!cul_screenline) {
- apply_cursorline_highlight(wp, lnum, &line_attr, &cul_attr, &line_attr_lowprio);
- } else {
- margin_columns_win(wp, &left_curline_col, &right_curline_col);
- }
- area_highlighting = true;
+ if (wp->w_p_cul && wp->w_p_culopt_flags != CULOPT_NBR && 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.
+ && !(wp == curwin && VIsual_active)) {
+ cul_screenline = (wp->w_p_wrap && (wp->w_p_culopt_flags & CULOPT_SCRLINE));
+ if (!cul_screenline) {
+ apply_cursorline_highlight(wp, lnum, &line_attr, &cul_attr, &line_attr_lowprio);
+ } else {
+ margin_columns_win(wp, &left_curline_col, &right_curline_col);
}
+ area_highlighting = true;
}
SignTextAttrs sattrs[SIGN_SHOW_MAX]; // sign attributes for the sign column
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index 814d443031..2c0b6ea3b0 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -1552,7 +1552,15 @@ static void win_update(win_T *wp, DecorProviders *providers)
wp->w_old_visual_col = 0;
}
- bool cursorline_standout = win_cursorline_standout(wp);
+ foldinfo_T cursorline_fi;
+ wp->w_cursorline = win_cursorline_standout(wp) ? wp->w_cursor.lnum : 0;
+ if (wp->w_p_cul) {
+ // Make sure that the cursorline on a closed fold is redrawn
+ cursorline_fi = fold_info(wp, wp->w_cursor.lnum);
+ if (cursorline_fi.fi_level > 0 && cursorline_fi.fi_lines > 0) {
+ wp->w_cursorline = cursorline_fi.fi_lnum;
+ }
+ }
win_check_ns_hl(wp);
@@ -1608,7 +1616,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)
+ || lnum == wp->w_cursorline
|| lnum == wp->w_last_cursorline) {
if (lnum == mod_top) {
top_to_mod = false;
@@ -1759,7 +1767,8 @@ static void win_update(win_T *wp, DecorProviders *providers)
// When lines are folded, display one line for all of them.
// Otherwise, display normally (can be several display lines when
// 'wrap' is on).
- foldinfo_T foldinfo = fold_info(wp, lnum);
+ foldinfo_T foldinfo = wp->w_p_cul && lnum == wp->w_cursor.lnum ?
+ cursorline_fi : fold_info(wp, lnum);
if (foldinfo.fi_lines == 0
&& idx < wp->w_lines_valid
@@ -1818,7 +1827,8 @@ static void win_update(win_T *wp, DecorProviders *providers)
if (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum) {
// 'relativenumber' set and cursor moved vertically: The
// text doesn't need to be drawn, but the number column does.
- foldinfo_T info = fold_info(wp, lnum);
+ foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum ?
+ cursorline_fi : fold_info(wp, lnum);
(void)win_line(wp, lnum, srow, wp->w_grid.rows, true, true,
info, &line_providers, &provider_err);
}
@@ -1853,7 +1863,7 @@ 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 = wp->w_cursorline;
wp->w_last_cursor_lnum_rnu = wp->w_p_rnu ? wp->w_cursor.lnum : 0;
diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua
index 46a478c1ea..420a4654f8 100644
--- a/test/functional/ui/fold_spec.lua
+++ b/test/functional/ui/fold_spec.lua
@@ -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 = [[
@@ -90,10 +91,10 @@ 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
@@ -106,26 +107,26 @@ describe("folded lines", function()
[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:^ }|
+ {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")
@@ -141,28 +142,36 @@ describe("folded lines", function()
[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: } |
+ {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 #22232
+ feed("jgk")
+ poke_eventloop()
+ screen:expect_unchanged()
+ -- CursorLine is applied correctly when closing a fold when cursor is not at fold start
+ feed("zo4Gzc")
+ poke_eventloop()
+ screen:expect_unchanged()
command("set cursorlineopt=line")
if multigrid then
screen:expect([[
@@ -176,26 +185,61 @@ describe("folded lines", function()
[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: } |
+ {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: }This is a |
- {7: }valid English |
- {7: }sentence composed by |
- {7: }an exhausted developer |
- {7: }{12:^in his cave. }|
- {7: } |
- {1:~ }|
- |
+ {7:+ }{8: 1 }{12:^+-- 4 lines: This is a················}|
+ {7: }{8: 5 }in his cave. |
+ {7: }{8: 6 } |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ end
+ command("set relativenumber cursorlineopt=number")
+ 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([[
+ {6:+ }{9:1 }{5:^+-- 4 lines: This is a················}|
+ {7: }{8: 1 }in his cave. |
+ {7: }{8: 2 } |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
]])
end
end)