display: unify cursorline and concealcursor redraw logic

There is various places where 'conceallevel' and 'concealcursor'
necessitates additional redraws. This tries to separate the different
cases and handle each accordingly:

  - Share code with 'cursorline' for the common case: vertical move of
    cursor within the same window (concealcursor not active)
  - Improve the logic for managing 'concealcursor' and switching modes:
    test for the case where the new mode behaves differently from the
    last one.
  - Clarify the special case for horizontal movement within a line when
    'concealcursor' is active, now there is an if-statement only for this
     and not hidden in larger check mostly for the first point.
  - Keep the special case for moving between windows as is.
This commit is contained in:
Björn Linse 2019-01-12 11:05:49 +01:00
parent 9c75929e7b
commit 23c71d5182
6 changed files with 36 additions and 75 deletions

View File

@ -306,10 +306,6 @@ static void insert_enter(InsertState *s)
} }
} }
// Check if the cursor line needs redrawing before changing State. If
// 'concealcursor' is "n" it needs to be redrawn without concealing.
conceal_check_cursor_line();
// When doing a paste with the middle mouse button, Insstart is set to // When doing a paste with the middle mouse button, Insstart is set to
// where the paste started. // where the paste started.
if (where_paste_started.lnum != 0) { if (where_paste_started.lnum != 0) {
@ -1381,9 +1377,7 @@ ins_redraw (
int ready /* not busy with something */ int ready /* not busy with something */
) )
{ {
linenr_T conceal_old_cursor_line = 0; bool conceal_cursor_moved = false;
linenr_T conceal_new_cursor_line = 0;
int conceal_update_lines = FALSE;
if (char_avail()) if (char_avail())
return; return;
@ -1406,11 +1400,7 @@ ins_redraw (
update_curswant(); update_curswant();
ins_apply_autocmds(EVENT_CURSORMOVEDI); ins_apply_autocmds(EVENT_CURSORMOVEDI);
} }
if (curwin->w_p_cole > 0) { conceal_cursor_moved = true;
conceal_old_cursor_line = last_cursormoved.lnum;
conceal_new_cursor_line = curwin->w_cursor.lnum;
conceal_update_lines = TRUE;
}
last_cursormoved = curwin->w_cursor; last_cursormoved = curwin->w_cursor;
} }
@ -1452,17 +1442,9 @@ ins_redraw (
} }
} }
if ((conceal_update_lines if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)
&& (conceal_old_cursor_line != conceal_new_cursor_line && conceal_cursor_moved) {
|| conceal_cursor_line(curwin))) redrawWinline(curwin, curwin->w_cursor.lnum);
|| need_cursor_line_redraw) {
if (conceal_old_cursor_line != conceal_new_cursor_line) {
redrawWinline(curwin, conceal_old_cursor_line);
}
redrawWinline(curwin, conceal_new_cursor_line == 0
? curwin->w_cursor.lnum : conceal_new_cursor_line);
curwin->w_valid &= ~VALID_CROW;
need_cursor_line_redraw = false;
} }
if (must_redraw) { if (must_redraw) {

View File

@ -918,10 +918,6 @@ EXTERN disptick_T display_tick INIT(= 0);
* cursor position in Insert mode. */ * cursor position in Insert mode. */
EXTERN linenr_T spell_redraw_lnum INIT(= 0); EXTERN linenr_T spell_redraw_lnum INIT(= 0);
/* Set when the cursor line needs to be redrawn. */
EXTERN int need_cursor_line_redraw INIT(= FALSE);
#ifdef USE_MCH_ERRMSG #ifdef USE_MCH_ERRMSG
// Grow array to collect error messages in until they can be displayed. // Grow array to collect error messages in until they can be displayed.
EXTERN garray_T error_ga INIT(= GA_EMPTY_INIT_VALUE); EXTERN garray_T error_ga INIT(= GA_EMPTY_INIT_VALUE);

View File

@ -105,14 +105,14 @@ void reset_cursorline(void)
// Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set. // Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set.
static void redraw_for_cursorline(win_T *wp) static void redraw_for_cursorline(win_T *wp)
{ {
if ((wp->w_p_rnu || wp->w_p_cul) if ((wp->w_p_rnu || win_cursorline_standout(wp))
&& (wp->w_valid & VALID_CROW) == 0 && (wp->w_valid & VALID_CROW) == 0
&& !pum_visible()) { && !pum_visible()) {
if (wp->w_p_rnu) { if (wp->w_p_rnu) {
// win_line() will redraw the number column only. // win_line() will redraw the number column only.
redraw_win_later(wp, VALID); redraw_win_later(wp, VALID);
} }
if (wp->w_p_cul) { if (win_cursorline_standout(wp)) {
if (wp->w_redr_type <= VALID && wp->w_last_cursorline != 0) { if (wp->w_redr_type <= VALID && wp->w_last_cursorline != 0) {
// "w_last_cursorline" may be outdated, worst case we redraw // "w_last_cursorline" may be outdated, worst case we redraw
// too much. This is optimized for moving the cursor around in // too much. This is optimized for moving the cursor around in
@ -2207,7 +2207,7 @@ void do_check_cursorbind(void)
int restart_edit_save = restart_edit; int restart_edit_save = restart_edit;
restart_edit = true; restart_edit = true;
check_cursor(); check_cursor();
if (curwin->w_p_cul || curwin->w_p_cuc) { if (win_cursorline_standout(curwin) || curwin->w_p_cuc) {
validate_cursor(); validate_cursor();
} }
restart_edit = restart_edit_save; restart_edit = restart_edit_save;

View File

@ -64,12 +64,9 @@
typedef struct normal_state { typedef struct normal_state {
VimState state; VimState state;
linenr_T conceal_old_cursor_line;
linenr_T conceal_new_cursor_line;
bool command_finished; bool command_finished;
bool ctrl_w; bool ctrl_w;
bool need_flushbuf; bool need_flushbuf;
bool conceal_update_lines;
bool set_prevcount; bool set_prevcount;
bool previous_got_int; // `got_int` was true bool previous_got_int; // `got_int` was true
bool cmdwin; // command-line window normal mode bool cmdwin; // command-line window normal mode
@ -1201,12 +1198,6 @@ static void normal_check_cursor_moved(NormalState *s)
apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, false, curbuf); apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, false, curbuf);
} }
if (curwin->w_p_cole > 0) {
s->conceal_old_cursor_line = last_cursormoved.lnum;
s->conceal_new_cursor_line = curwin->w_cursor.lnum;
s->conceal_update_lines = true;
}
last_cursormoved = curwin->w_cursor; last_cursormoved = curwin->w_cursor;
} }
} }
@ -1246,24 +1237,11 @@ static void normal_redraw(NormalState *s)
update_topline(); update_topline();
validate_cursor(); validate_cursor();
// TODO(bfredl): this logic is only used for 'concealcursor', not // If the cursor moves horizontally when 'concealcursor' is active, then the
// 'cursorline'. Maybe we can eliminate this check (and in edit.c) by // current line needs to be redrawn in order to calculate the correct
// checking for 'concealcursor' wherever we check for 'cursorline' // cursor position.
if (s->conceal_update_lines if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)) {
&& (s->conceal_old_cursor_line != redrawWinline(curwin, curwin->w_cursor.lnum);
s->conceal_new_cursor_line
|| conceal_cursor_line(curwin)
|| need_cursor_line_redraw)) {
if (s->conceal_old_cursor_line !=
s->conceal_new_cursor_line
&& s->conceal_old_cursor_line <=
curbuf->b_ml.ml_line_count) {
redrawWinline(curwin, s->conceal_old_cursor_line);
}
redrawWinline(curwin, s->conceal_new_cursor_line);
curwin->w_valid &= ~VALID_CROW;
need_cursor_line_redraw = false;
} }
if (VIsual_active) { if (VIsual_active) {
@ -6500,9 +6478,6 @@ void may_start_select(int c)
*/ */
static void n_start_visual_mode(int c) static void n_start_visual_mode(int c)
{ {
// Check for redraw before changing the state.
conceal_check_cursor_line();
VIsual_mode = c; VIsual_mode = c;
VIsual_active = true; VIsual_active = true;
VIsual_reselect = true; VIsual_reselect = true;
@ -7072,8 +7047,6 @@ static void nv_g_cmd(cmdarg_T *cap)
*/ */
static void n_opencmd(cmdarg_T *cap) static void n_opencmd(cmdarg_T *cap)
{ {
linenr_T oldline = curwin->w_cursor.lnum;
if (!checkclearopq(cap->oap)) { if (!checkclearopq(cap->oap)) {
if (cap->cmdchar == 'O') if (cap->cmdchar == 'O')
/* Open above the first line of a folded sequence of lines */ /* Open above the first line of a folded sequence of lines */
@ -7092,10 +7065,7 @@ static void n_opencmd(cmdarg_T *cap)
has_format_option(FO_OPEN_COMS) has_format_option(FO_OPEN_COMS)
? OPENLINE_DO_COM : 0, ? OPENLINE_DO_COM : 0,
0)) { 0)) {
if (curwin->w_p_cole > 0 && oldline != curwin->w_cursor.lnum) { if (win_cursorline_standout(curwin)) {
redrawWinline(curwin, oldline);
}
if (curwin->w_p_cul) {
// force redraw of cursorline // force redraw of cursorline
curwin->w_valid &= ~VALID_CROW; curwin->w_valid &= ~VALID_CROW;
} }

View File

@ -151,6 +151,8 @@ static bool send_grid_resize = false;
/// Highlight ids are no longer valid. Force retransmission /// Highlight ids are no longer valid. Force retransmission
static bool highlights_invalid = false; static bool highlights_invalid = false;
static bool conceal_cursor_used = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "screen.c.generated.h" # include "screen.c.generated.h"
#endif #endif
@ -505,19 +507,28 @@ int conceal_cursor_line(win_T *wp)
return vim_strchr(wp->w_p_cocu, c) != NULL; return vim_strchr(wp->w_p_cocu, c) != NULL;
} }
/* // Check if the cursor line needs to be redrawn because of 'concealcursor'.
* Check if the cursor line needs to be redrawn because of 'concealcursor'. //
*/ // When cursor is moved at the same time, both lines will be redrawn regardless.
void conceal_check_cursor_line(void) void conceal_check_cursor_line(void)
{ {
if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)) { bool should_conceal = conceal_cursor_line(curwin);
need_cursor_line_redraw = TRUE; if (curwin->w_p_cole > 0 && (conceal_cursor_used != should_conceal)) {
/* Need to recompute cursor column, e.g., when starting Visual mode redrawWinline(curwin, curwin->w_cursor.lnum);
* without concealing. */ // Need to recompute cursor column, e.g., when starting Visual mode
curs_columns(TRUE); // without concealing. */
curs_columns(true);
} }
} }
/// Whether cursorline is drawn in a special way
///
/// If true, both old and new cursorline will need
/// need to be redrawn when moving cursor within windows.
bool win_cursorline_standout(win_T *wp)
{
return wp->w_p_cul || (wp->w_p_cole > 0 && !conceal_cursor_line(wp));
}
/* /*
* Update a single window. * Update a single window.
@ -1942,6 +1953,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
curwin->w_cline_height = 1; curwin->w_cline_height = 1;
curwin->w_cline_folded = true; curwin->w_cline_folded = true;
curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
conceal_cursor_used = conceal_cursor_line(curwin);
} }
} }
@ -3960,6 +3972,7 @@ win_line (
curwin->w_cline_height = row - startrow; curwin->w_cline_height = row - startrow;
curwin->w_cline_folded = false; curwin->w_cline_folded = false;
curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
conceal_cursor_used = conceal_cursor_line(curwin);
} }
break; break;

View File

@ -3547,7 +3547,7 @@ void win_goto(win_T *wp)
redrawWinline(owp, owp->w_cursor.lnum); redrawWinline(owp, owp->w_cursor.lnum);
} }
if (curwin->w_p_cole > 0 && !msg_scrolled) { if (curwin->w_p_cole > 0 && !msg_scrolled) {
need_cursor_line_redraw = true; redrawWinline(curwin, curwin->w_cursor.lnum);
} }
} }