mirror of
https://github.com/vim/vim
synced 2025-07-16 01:01:58 +00:00
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:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
24
src/option.c
24
src/option.c
@ -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
|
||||
|
@ -1161,6 +1161,7 @@ enum
|
||||
#ifdef FEAT_SYN_HL
|
||||
, WV_CUC
|
||||
, WV_CUL
|
||||
, WV_CULOPT
|
||||
, WV_CC
|
||||
#endif
|
||||
#ifdef FEAT_STL_OPT
|
||||
|
15
src/screen.c
15
src/screen.c
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -92,6 +92,7 @@ NEW_TESTS = \
|
||||
test_crypt \
|
||||
test_cscope \
|
||||
test_cursor_func \
|
||||
test_cursorline \
|
||||
test_curswant \
|
||||
test_debugger \
|
||||
test_delete \
|
||||
|
@ -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']],
|
||||
|
@ -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
|
||||
|
108
src/testdir/test_cursorline.vim
Normal file
108
src/testdir/test_cursorline.vim
Normal 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
|
@ -757,6 +757,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2019,
|
||||
/**/
|
||||
2018,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user