mirror of
https://github.com/vim/vim.git
synced 2025-10-01 04:54:07 -04:00
patch 8.1.2029: cannot control 'cursorline' highlighting well
Problem: Cannot control 'cursorline' highlighting well. Solution: Add "screenline". (Christian Brabandt, closes #4933)
This commit is contained in:
207
src/screen.c
207
src/screen.c
@@ -158,6 +158,9 @@ static void win_redr_custom(win_T *wp, int draw_ruler);
|
||||
#ifdef FEAT_CMDL_INFO
|
||||
static void win_redr_ruler(win_T *wp, int always, int ignore_pum);
|
||||
#endif
|
||||
#ifdef FEAT_SYN_HL
|
||||
static void margin_columns_win(win_T *wp, int *left_col, int *right_col);
|
||||
#endif
|
||||
|
||||
/* Ugly global: overrule attribute used by screen_char() */
|
||||
static int screen_char_attr = 0;
|
||||
@@ -3270,7 +3273,8 @@ win_line(
|
||||
#if defined(FEAT_SIGNS) || defined(FEAT_QUICKFIX) \
|
||||
|| defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
|
||||
# define LINE_ATTR
|
||||
int line_attr = 0; /* attribute for the whole line */
|
||||
int line_attr = 0; // attribute for the whole line
|
||||
int line_attr_save;
|
||||
#endif
|
||||
#ifdef FEAT_SIGNS
|
||||
int sign_present = FALSE;
|
||||
@@ -3286,6 +3290,17 @@ win_line(
|
||||
#ifdef FEAT_TERMINAL
|
||||
int get_term_attr = FALSE;
|
||||
#endif
|
||||
#ifdef FEAT_SYN_HL
|
||||
int cul_attr = 0; // set when 'cursorline' active
|
||||
|
||||
// 'cursorlineopt' has "screenline" and cursor is in this line
|
||||
int cul_screenline = FALSE;
|
||||
|
||||
// margin columns for the screen line, needed for when 'cursorlineopt'
|
||||
// contains "screenline"
|
||||
int left_curline_col = 0;
|
||||
int right_curline_col = 0;
|
||||
#endif
|
||||
|
||||
/* draw_state: items that are drawn in sequence: */
|
||||
#define WL_START 0 /* nothing done yet */
|
||||
@@ -3815,14 +3830,33 @@ win_line(
|
||||
// Cursor line highlighting for 'cursorline' in the current window.
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
|
||||
{
|
||||
// Do not show the cursor line when Visual mode is active, because it's
|
||||
// not clear what is selected then. Do update w_last_cursorline.
|
||||
if (!(wp == curwin && VIsual_active) && *wp->w_p_culopt != 'n')
|
||||
// Do not show the cursor line in the text when Visual mode is active,
|
||||
// because it's not clear what is selected then. Do update
|
||||
// w_last_cursorline.
|
||||
if (!(wp == curwin && VIsual_active)
|
||||
&& wp->w_p_culopt_flags != CULOPT_NBR)
|
||||
{
|
||||
line_attr = HL_ATTR(HLF_CUL);
|
||||
cul_screenline = (wp->w_p_wrap
|
||||
&& (wp->w_p_culopt_flags & CULOPT_SCRLINE));
|
||||
|
||||
// Only set line_attr here when "screenline" is not present in
|
||||
// 'cursorlineopt'. Otherwise it's done later.
|
||||
if (!cul_screenline)
|
||||
{
|
||||
cul_attr = HL_ATTR(HLF_CUL);
|
||||
line_attr = cul_attr;
|
||||
wp->w_last_cursorline = wp->w_cursor.lnum;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_attr_save = line_attr;
|
||||
wp->w_last_cursorline = 0;
|
||||
margin_columns_win(wp, &left_curline_col, &right_curline_col);
|
||||
}
|
||||
area_highlighting = TRUE;
|
||||
}
|
||||
wp->w_last_cursorline = wp->w_cursor.lnum;
|
||||
else
|
||||
wp->w_last_cursorline = wp->w_cursor.lnum;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4016,13 +4050,17 @@ win_line(
|
||||
n_extra = number_width(wp) + 1;
|
||||
char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_N));
|
||||
#ifdef FEAT_SYN_HL
|
||||
/* When 'cursorline' is set highlight the line number of
|
||||
* the current line differently.
|
||||
* TODO: Can we use CursorLine instead of CursorLineNr
|
||||
* when CursorLineNr isn't set? */
|
||||
// When 'cursorline' is set highlight the line number of
|
||||
// the current line differently.
|
||||
// When 'cursorlineopt' has "screenline" only highlight
|
||||
// the line number itself.
|
||||
// TODO: Can we use CursorLine instead of CursorLineNr
|
||||
// when CursorLineNr isn't set?
|
||||
if ((wp->w_p_cul || wp->w_p_rnu)
|
||||
&& *wp->w_p_culopt != 'l'
|
||||
&& lnum == wp->w_cursor.lnum)
|
||||
&& (wp->w_p_culopt_flags & CULOPT_NBR)
|
||||
&& (row == startrow
|
||||
|| wp->w_p_culopt_flags & CULOPT_LINE)
|
||||
&& lnum == wp->w_cursor.lnum)
|
||||
char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLN));
|
||||
#endif
|
||||
}
|
||||
@@ -4056,10 +4094,8 @@ win_line(
|
||||
{
|
||||
char_attr = HL_ATTR(diff_hlf);
|
||||
# ifdef FEAT_SYN_HL
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
|
||||
&& *wp->w_p_culopt != 'n')
|
||||
char_attr = hl_combine_attr(char_attr,
|
||||
HL_ATTR(HLF_CUL));
|
||||
if (cul_attr != 0)
|
||||
char_attr = hl_combine_attr(char_attr, cul_attr);
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
@@ -4117,13 +4153,11 @@ win_line(
|
||||
* required when 'linebreak' is also set. */
|
||||
if (tocol == vcol)
|
||||
tocol += n_extra;
|
||||
#ifdef FEAT_SYN_HL
|
||||
/* combine 'showbreak' with 'cursorline' */
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
|
||||
&& *wp->w_p_culopt != 'n')
|
||||
char_attr = hl_combine_attr(char_attr,
|
||||
HL_ATTR(HLF_CUL));
|
||||
#endif
|
||||
# ifdef FEAT_SYN_HL
|
||||
// combine 'showbreak' with 'cursorline'
|
||||
if (cul_attr != 0)
|
||||
char_attr = hl_combine_attr(char_attr, cul_attr);
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
}
|
||||
@@ -4145,6 +4179,23 @@ win_line(
|
||||
char_attr = win_attr;
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_SYN_HL
|
||||
if (cul_screenline)
|
||||
{
|
||||
if (draw_state == WL_LINE
|
||||
&& vcol >= left_curline_col
|
||||
&& vcol < right_curline_col)
|
||||
{
|
||||
cul_attr = HL_ATTR(HLF_CUL);
|
||||
line_attr = cul_attr;
|
||||
}
|
||||
else
|
||||
{
|
||||
cul_attr = 0;
|
||||
line_attr = line_attr_save;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// When still displaying '$' of change command, stop at cursor.
|
||||
// When only displaying the (relative) line number and that's done,
|
||||
@@ -4216,8 +4267,11 @@ win_line(
|
||||
diff_hlf = HLF_CHD; /* changed line */
|
||||
line_attr = HL_ATTR(diff_hlf);
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
|
||||
&& *wp->w_p_culopt != 'n')
|
||||
line_attr = hl_combine_attr(line_attr, HL_ATTR(HLF_CUL));
|
||||
&& wp->w_p_culopt_flags != CULOPT_NBR
|
||||
&& (!cul_screenline || (vcol >= left_curline_col
|
||||
&& vcol <= right_curline_col)))
|
||||
line_attr = hl_combine_attr(
|
||||
line_attr, HL_ATTR(HLF_CUL));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4301,9 +4355,12 @@ win_line(
|
||||
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|
||||
|| vcol < fromcol || vcol_prev < fromcol_prev
|
||||
|| vcol >= tocol))
|
||||
{
|
||||
// Use line_attr when not in the Visual or 'incsearch' area
|
||||
// (area_attr may be 0 when "noinvcur" is set).
|
||||
char_attr = line_attr;
|
||||
attr_pri = FALSE;
|
||||
}
|
||||
#else
|
||||
if (area_attr != 0)
|
||||
char_attr = area_attr;
|
||||
@@ -4410,6 +4467,10 @@ win_line(
|
||||
mb_l = 1;
|
||||
mb_utf8 = FALSE;
|
||||
multi_attr = HL_ATTR(HLF_AT);
|
||||
#ifdef FEAT_SYN_HL
|
||||
if (cul_attr)
|
||||
multi_attr = hl_combine_attr(multi_attr, cul_attr);
|
||||
#endif
|
||||
/* put the pointer back to output the double-width
|
||||
* character at the start of the next line. */
|
||||
++n_extra;
|
||||
@@ -4672,10 +4733,10 @@ win_line(
|
||||
if (win_attr != 0)
|
||||
syntax_attr = hl_combine_attr(win_attr, syntax_attr);
|
||||
|
||||
#ifdef SYN_TIME_LIMIT
|
||||
# ifdef SYN_TIME_LIMIT
|
||||
if (wp->w_s->b_syn_slow)
|
||||
has_syntax = FALSE;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
/* Need to get the line again, a multi-line regexp may
|
||||
* have made it invalid. */
|
||||
@@ -4692,7 +4753,15 @@ win_line(
|
||||
comb_attr = hl_combine_attr(text_prop_attr, comb_attr);
|
||||
# endif
|
||||
if (!attr_pri)
|
||||
char_attr = comb_attr;
|
||||
{
|
||||
#ifdef FEAT_SYN_HL
|
||||
if (cul_attr)
|
||||
char_attr = hl_combine_attr(
|
||||
comb_attr, cul_attr);
|
||||
else
|
||||
#endif
|
||||
char_attr = comb_attr;
|
||||
}
|
||||
else
|
||||
char_attr = hl_combine_attr(comb_attr, char_attr);
|
||||
}
|
||||
@@ -5185,9 +5254,12 @@ win_line(
|
||||
{
|
||||
char_attr = HL_ATTR(diff_hlf);
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
|
||||
&& *wp->w_p_culopt != 'n')
|
||||
char_attr = hl_combine_attr(char_attr,
|
||||
HL_ATTR(HLF_CUL));
|
||||
&& wp->w_p_culopt_flags != CULOPT_NBR
|
||||
&& (!cul_screenline
|
||||
|| (vcol >= left_curline_col
|
||||
&& vcol <= right_curline_col)))
|
||||
char_attr = hl_combine_attr(
|
||||
char_attr, HL_ATTR(HLF_CUL));
|
||||
}
|
||||
}
|
||||
# endif
|
||||
@@ -5196,8 +5268,12 @@ win_line(
|
||||
{
|
||||
char_attr = win_attr;
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
|
||||
char_attr = hl_combine_attr(char_attr,
|
||||
HL_ATTR(HLF_CUL));
|
||||
{
|
||||
if (!cul_screenline || (vcol >= left_curline_col
|
||||
&& vcol <= right_curline_col))
|
||||
char_attr = hl_combine_attr(
|
||||
char_attr, HL_ATTR(HLF_CUL));
|
||||
}
|
||||
else if (line_attr)
|
||||
char_attr = hl_combine_attr(char_attr, line_attr);
|
||||
}
|
||||
@@ -5305,7 +5381,12 @@ win_line(
|
||||
if (n_attr > 0
|
||||
&& draw_state == WL_LINE
|
||||
&& !attr_pri)
|
||||
char_attr = extra_attr;
|
||||
{
|
||||
if (line_attr)
|
||||
char_attr = hl_combine_attr(extra_attr, line_attr);
|
||||
else
|
||||
char_attr = extra_attr;
|
||||
}
|
||||
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
/* XIM don't send preedit_start and preedit_end, but they send
|
||||
@@ -5969,7 +6050,16 @@ win_line(
|
||||
saved_p_extra = p_extra;
|
||||
saved_c_extra = c_extra;
|
||||
saved_c_final = c_final;
|
||||
saved_char_attr = char_attr;
|
||||
#ifdef FEAT_SYN_HL
|
||||
if (!(cul_screenline
|
||||
# ifdef FEAT_DIFF
|
||||
&& diff_hlf == (hlf_T)0)
|
||||
# endif
|
||||
)
|
||||
saved_char_attr = char_attr;
|
||||
else
|
||||
#endif
|
||||
saved_char_attr = 0;
|
||||
n_extra = 0;
|
||||
lcs_prec_todo = lcs_prec;
|
||||
#ifdef FEAT_LINEBREAK
|
||||
@@ -11024,3 +11114,50 @@ set_chars_option(char_u **varp)
|
||||
|
||||
return NULL; // no error
|
||||
}
|
||||
|
||||
#ifdef FEAT_SYN_HL
|
||||
/*
|
||||
* Used when 'cursorlineopt' contains "screenline": compute the margins between
|
||||
* which the highlighting is used.
|
||||
*/
|
||||
static void
|
||||
margin_columns_win(win_T *wp, int *left_col, int *right_col)
|
||||
{
|
||||
// cache previous calculations depending on w_virtcol
|
||||
static int saved_w_virtcol;
|
||||
static win_T *prev_wp;
|
||||
static int prev_left_col;
|
||||
static int prev_right_col;
|
||||
static int prev_col_off;
|
||||
|
||||
int cur_col_off = win_col_off(wp);
|
||||
int width1;
|
||||
int width2;
|
||||
|
||||
if (saved_w_virtcol == wp->w_virtcol
|
||||
&& prev_wp == wp && prev_col_off == cur_col_off)
|
||||
{
|
||||
*right_col = prev_right_col;
|
||||
*left_col = prev_left_col;
|
||||
return;
|
||||
}
|
||||
|
||||
width1 = wp->w_width - cur_col_off;
|
||||
width2 = width1 + win_col_off2(wp);
|
||||
|
||||
*left_col = 0;
|
||||
*right_col = width1;
|
||||
|
||||
if (wp->w_virtcol >= (colnr_T)width1)
|
||||
*right_col = width1 + ((wp->w_virtcol - width1) / width2 + 1) * width2;
|
||||
if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0)
|
||||
*left_col = (wp->w_virtcol - width1) / width2 * width2 + width1;
|
||||
|
||||
// cache values
|
||||
prev_left_col = *left_col;
|
||||
prev_right_col = *right_col;
|
||||
prev_wp = wp;
|
||||
saved_w_virtcol = wp->w_virtcol;
|
||||
prev_col_off = cur_col_off;
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user