patch 8.1.2019: 'cursorline' always highlights the whole line

Problem:    'cursorline' always highlights the whole line.
Solution:   Add 'cursorlineopt' to specify what is highlighted.
            (closes #4693)
This commit is contained in:
Bram Moolenaar
2019-09-09 22:05:49 +02:00
parent e5fbd73930
commit 410e98a70b
13 changed files with 172 additions and 9 deletions

View File

@ -2461,13 +2461,26 @@ A jump table for the options with a short description can be found at |Q_op|.
local to window
{not available when compiled without the |+syntax|
feature}
Highlight the screen line of the cursor with CursorLine
|hl-CursorLine|. Useful to easily spot the cursor. Will make screen
redrawing slower.
Highlight the text line of the cursor with CursorLine |hl-CursorLine|.
Useful to easily spot the cursor. Will make screen redrawing slower.
When Visual mode is active the highlighting isn't used to make it
easier to see the selected text.
*'cursorlineopt'* *'culopt'*
'cursorlineopt' 'culopt' string (default: "both")
local to window
{not in Vi}
{not available when compiled without the |+syntax|
feature}
Settings for how 'cursorline' is displayed. Valid values:
"line" Highlight the text line of the cursor with
CursorLine |hl-CursorLine|.
"number" Highlight the line number of the cursor with
CursorLineNr |hl-CursorLineNr|.
"both" Highlight as both "line" and "number" are set.
*'debug'*
'debug' string (default "")
global

View File

@ -670,6 +670,7 @@ Short explanation of each option: *option-list*
'cursorbind' 'crb' move cursor in window as it moves in other windows
'cursorcolumn' 'cuc' highlight the screen column of the cursor
'cursorline' 'cul' highlight the screen line of the cursor
'cursorlineopt' 'culopt' settings for 'cursorline'
'debug' set to "msg" to see all error messages
'define' 'def' pattern to be used to find a macro definition
'delcombine' 'deco' delete combining characters on their own

View File

@ -5042,7 +5042,8 @@ IncSearch 'incsearch' highlighting; also used for the text replaced with
LineNr Line number for ":number" and ":#" commands, and when 'number'
or 'relativenumber' option is set.
*hl-CursorLineNr*
CursorLineNr Like LineNr when 'cursorline' or 'relativenumber' is set for
CursorLineNr Like LineNr when 'cursorline' is set and 'cursorlineopt' is
set to "number" or "both", or 'relativenumber' is set, for
the cursor line.
*hl-MatchParen*
MatchParen The character under the cursor or just before it, if it

View File

@ -429,6 +429,9 @@ if has("syntax")
call append("$", "cursorline\thighlight the screen line of the cursor")
call append("$", "\t(local to window)")
call <SID>BinOptionL("cul")
call append("$", "cursorlineopt\tspecifies which area 'cursorline' highlights")
call append("$", "\t(local to window)")
call <SID>OptionL("culopt")
call append("$", "colorcolumn\tcolumns to highlight")
call append("$", "\t(local to window)")
call <SID>OptionL("cc")

View File

@ -238,6 +238,7 @@
#ifdef FEAT_SYN_HL
# define PV_CUC OPT_WIN(WV_CUC)
# define PV_CUL OPT_WIN(WV_CUL)
# define PV_CULOPT OPT_WIN(WV_CULOPT)
# define PV_CC OPT_WIN(WV_CC)
#endif
#ifdef FEAT_STL_OPT
@ -993,6 +994,13 @@ static struct vimoption options[] =
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"cursorlineopt", "culopt", P_STRING|P_VI_DEF|P_RWIN,
#ifdef FEAT_SYN_HL
(char_u *)VAR_WIN, PV_CULOPT,
#else
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)"both", (char_u *)0L} SCTX_INIT},
{"debug", NULL, P_STRING|P_VI_DEF,
(char_u *)&p_debug, PV_NONE,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
@ -3228,6 +3236,9 @@ static char *(p_scl_values[]) = {"yes", "no", "auto", "number", NULL};
#if defined(MSWIN) && defined(FEAT_TERMINAL)
static char *(p_twt_values[]) = {"winpty", "conpty", "", NULL};
#endif
#ifdef FEAT_SYN_HL
static char *(p_culopt_values[]) = {"line", "number", "both", NULL};
#endif
static void set_options_default(int opt_flags);
static void set_string_default_esc(char *name, char_u *val, int escape);
@ -6326,6 +6337,15 @@ did_set_string_option(
}
#ifdef FEAT_SYN_HL
/* 'cursorlineopt' */
else if (varp == &curwin->w_p_culopt
|| gvarp == &curwin->w_allbuf_opt.wo_culopt)
{
if (**varp == NUL
|| check_opt_strings(*varp, p_culopt_values, FALSE) != OK)
errmsg = e_invarg;
}
/* 'colorcolumn' */
else if (varp == &curwin->w_p_cc)
errmsg = check_colorcolumn(curwin);
@ -10775,6 +10795,7 @@ get_varp(struct vimoption *p)
#ifdef FEAT_SYN_HL
case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
case PV_CUL: return (char_u *)&(curwin->w_p_cul);
case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt);
case PV_CC: return (char_u *)&(curwin->w_p_cc);
#endif
#ifdef FEAT_DIFF
@ -11012,6 +11033,7 @@ copy_winopt(winopt_T *from, winopt_T *to)
#ifdef FEAT_SYN_HL
to->wo_cuc = from->wo_cuc;
to->wo_cul = from->wo_cul;
to->wo_culopt = vim_strsave(from->wo_culopt);
to->wo_cc = vim_strsave(from->wo_cc);
#endif
#ifdef FEAT_DIFF
@ -11087,6 +11109,7 @@ check_winopt(winopt_T *wop UNUSED)
check_string_option(&wop->wo_stl);
#endif
#ifdef FEAT_SYN_HL
check_string_option(&wop->wo_culopt);
check_string_option(&wop->wo_cc);
#endif
#ifdef FEAT_CONCEAL
@ -11132,6 +11155,7 @@ clear_winopt(winopt_T *wop UNUSED)
clear_string_option(&wop->wo_stl);
#endif
#ifdef FEAT_SYN_HL
clear_string_option(&wop->wo_culopt);
clear_string_option(&wop->wo_cc);
#endif
#ifdef FEAT_CONCEAL

View File

@ -1161,6 +1161,7 @@ enum
#ifdef FEAT_SYN_HL
, WV_CUC
, WV_CUL
, WV_CULOPT
, WV_CC
#endif
#ifdef FEAT_STL_OPT

View File

@ -3817,7 +3817,7 @@ win_line(
{
// 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))
if (!(wp == curwin && VIsual_active) && *wp->w_p_culopt != 'n')
{
line_attr = HL_ATTR(HLF_CUL);
area_highlighting = TRUE;
@ -4021,6 +4021,7 @@ win_line(
* 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)
char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLN));
#endif
@ -4055,7 +4056,8 @@ win_line(
{
char_attr = HL_ATTR(diff_hlf);
# ifdef FEAT_SYN_HL
if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
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
@ -4117,7 +4119,8 @@ win_line(
tocol += n_extra;
#ifdef FEAT_SYN_HL
/* combine 'showbreak' with 'cursorline' */
if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
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
@ -4212,7 +4215,8 @@ win_line(
&& n_extra == 0)
diff_hlf = HLF_CHD; /* changed line */
line_attr = HL_ATTR(diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
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));
}
#endif
@ -5180,7 +5184,8 @@ win_line(
if (vi_attr == 0 || char_attr != vi_attr)
{
char_attr = HL_ATTR(diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
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));
}

View File

@ -249,6 +249,8 @@ typedef struct
# define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn'
int wo_cul;
# define w_p_cul w_onebuf_opt.wo_cul // 'cursorline'
char_u *wo_culopt;
# define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt'
char_u *wo_cc;
# define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn'
#endif

View File

@ -92,6 +92,7 @@ NEW_TESTS = \
test_crypt \
test_cscope \
test_cursor_func \
test_cursorline \
test_curswant \
test_debugger \
test_delete \

View File

@ -82,6 +82,7 @@ let test_values = {
\ 'completeslash': [['', 'slash', 'backslash'], ['xxx']],
\ 'cryptmethod': [['', 'zip'], ['xxx']],
\ 'cscopequickfix': [['', 's-', 's-,c+,e0'], ['xxx', 's,g,d']],
\ 'cursorlineopt': [['both', 'line', 'number'], ['', 'xxx', 'line,number']],
\ 'debug': [['', 'msg', 'msg', 'beep'], ['xxx']],
\ 'diffopt': [['', 'filler', 'icase,iwhite'], ['xxx', 'algorithm:xxx', 'algorithm:']],
\ 'display': [['', 'lastline', 'lastline,uhex'], ['xxx']],

View File

@ -9,6 +9,7 @@ source test_cd.vim
source test_changedtick.vim
source test_compiler.vim
source test_cursor_func.vim
source test_cursorline.vim
source test_delete.vim
source test_ex_equal.vim
source test_ex_undo.vim

View File

@ -0,0 +1,108 @@
" Test for cursorline and cursorlineopt
"
source view_util.vim
source check.vim
function! s:screen_attr(lnum) abort
return map(range(1, 8), 'screenattr(a:lnum, v:val)')
endfunction
function! s:test_windows(h, w) abort
call NewWindow(a:h, a:w)
endfunction
function! s:close_windows() abort
call CloseWindow()
endfunction
function! s:new_hi() abort
redir => save_hi
silent! hi CursorLineNr
redir END
let save_hi = join(split(substitute(save_hi, '\s*xxx\s*', ' ', ''), "\n"), '')
exe 'hi' save_hi 'ctermbg=0 guibg=Black'
return save_hi
endfunction
func Test_cursorline_highlight1()
let save_hi = s:new_hi()
try
call s:test_windows(10, 20)
call setline(1, repeat(['aaaa'], 10))
redraw
let attr01 = s:screen_attr(1)
call assert_equal(repeat([attr01[0]], 8), attr01)
setl number numberwidth=4
redraw
let attr11 = s:screen_attr(1)
call assert_equal(repeat([attr11[0]], 4), attr11[0:3])
call assert_equal(repeat([attr11[4]], 4), attr11[4:7])
call assert_notequal(attr11[0], attr11[4])
setl cursorline
redraw
let attr21 = s:screen_attr(1)
let attr22 = s:screen_attr(2)
call assert_equal(repeat([attr21[0]], 4), attr21[0:3])
call assert_equal(repeat([attr21[4]], 4), attr21[4:7])
call assert_equal(attr11, attr22)
call assert_notequal(attr22, attr21)
setl nocursorline relativenumber
redraw
let attr31 = s:screen_attr(1)
call assert_equal(attr21[0:3], attr31[0:3])
call assert_equal(attr11[4:7], attr31[4:7])
call s:close_windows()
finally
exe 'hi' save_hi
endtry
endfunc
func Test_cursorline_highlight2()
CheckOption cursorlineopt
let save_hi = s:new_hi()
try
call s:test_windows(10, 20)
call setline(1, repeat(['aaaa'], 10))
redraw
let attr0 = s:screen_attr(1)
call assert_equal(repeat([attr0[0]], 8), attr0)
setl number
redraw
let attr1 = s:screen_attr(1)
call assert_notequal(attr0[0:3], attr1[0:3])
call assert_equal(attr0[0:3], attr1[4:7])
setl cursorline cursorlineopt=both
redraw
let attr2 = s:screen_attr(1)
call assert_notequal(attr1[0:3], attr2[0:3])
call assert_notequal(attr1[4:7], attr2[4:7])
setl cursorlineopt=line
redraw
let attr3 = s:screen_attr(1)
call assert_equal(attr1[0:3], attr3[0:3])
call assert_equal(attr2[4:7], attr3[4:7])
setl cursorlineopt=number
redraw
let attr4 = s:screen_attr(1)
call assert_equal(attr2[0:3], attr4[0:3])
call assert_equal(attr1[4:7], attr4[4:7])
setl nonumber
redraw
let attr5 = s:screen_attr(1)
call assert_equal(attr0, attr5)
call s:close_windows()
finally
exe 'hi' save_hi
endtry
endfunc

View File

@ -757,6 +757,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2019,
/**/
2018,
/**/