vim-patch:8.1.2019: 'cursorline' always highlights the whole line (#15161)

Problem:    'cursorline' always highlights the whole line.
Solution:   Add 'cursorlineopt' to specify what is highlighted.
            (closes vim/vim#4693)
410e98a70b
This commit is contained in:
zeertzjq 2021-07-31 09:51:26 +08:00 committed by GitHub
parent 15698eb5a1
commit 5f01714b25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 160 additions and 9 deletions

View File

@ -1802,13 +1802,23 @@ A jump table for the options with a short description can be found at |Q_op|.
*'cursorline'* *'cul'* *'nocursorline'* *'nocul'*
'cursorline' 'cul' boolean (default off)
local to window
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
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

@ -659,6 +659,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

@ -5065,7 +5065,8 @@ Substitute |:substitute| replacement text highlighting
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

@ -440,6 +440,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

@ -226,6 +226,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'
char_u *wo_stl;

View File

@ -322,6 +322,7 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2",
static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2",
"auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
static char *(p_culopt_values[]) = { "line", "number", "both", NULL };
/// All possible flags for 'shm'.
static char_u SHM_ALL[] = {
@ -2411,6 +2412,12 @@ did_set_string_option(
os_setenv("VIMRUNTIME", "", 1);
didset_vimruntime = false;
}
} else if (varp == &curwin->w_p_culopt
|| gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt'
if (**varp == NUL
|| check_opt_strings(*varp, p_culopt_values, false) != OK) {
errmsg = e_invarg;
}
} else if (varp == &curwin->w_p_cc) { // 'colorcolumn'
errmsg = check_colorcolumn(curwin);
} else if (varp == &p_hlg) { // 'helplang'
@ -5652,6 +5659,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
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);
case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
@ -5799,6 +5807,7 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_spell = from->wo_spell;
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);
to->wo_diff = from->wo_diff;
to->wo_diff_saved = from->wo_diff_saved;
@ -5849,6 +5858,7 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_scl);
check_string_option(&wop->wo_rlc);
check_string_option(&wop->wo_stl);
check_string_option(&wop->wo_culopt);
check_string_option(&wop->wo_cc);
check_string_option(&wop->wo_cocu);
check_string_option(&wop->wo_briopt);
@ -5871,6 +5881,7 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_scl);
clear_string_option(&wop->wo_rlc);
clear_string_option(&wop->wo_stl);
clear_string_option(&wop->wo_culopt);
clear_string_option(&wop->wo_cc);
clear_string_option(&wop->wo_cocu);
clear_string_option(&wop->wo_briopt);

View File

@ -870,6 +870,7 @@ enum {
, WV_SPELL
, WV_CUC
, WV_CUL
, WV_CULOPT
, WV_CC
, WV_STL
, WV_WFH

View File

@ -555,6 +555,13 @@ return {
redraw={'current_window_only'},
defaults={if_true={vi=false}}
},
{
full_name='cursorlineopt', abbreviation='culopt',
short_desc=N_("settings for 'cursorline'"),
type='string', scope={'window'},
redraw={'current_window_only'},
defaults={if_true={vi="both"}}
},
{
full_name='debug',
short_desc=N_("to \"msg\" to see all error messages"),

View File

@ -2362,7 +2362,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (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.
if (wp->w_p_cul && !(wp == curwin && VIsual_active)) {
if (wp->w_p_cul && !(wp == curwin && VIsual_active)
&& *wp->w_p_culopt != 'n') {
int cul_attr = win_hl_attr(wp, HLF_CUL);
HlAttrs ae = syn_attr2entry(cul_attr);
@ -2786,6 +2787,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
// :sign defined with "numhl" highlight.
char_attr = num_sattr->sat_numhl;
} else if ((wp->w_p_cul || wp->w_p_rnu)
&& *wp->w_p_culopt != 'l'
&& lnum == wp->w_cursor.lnum
&& filler_todo == 0) {
// When 'cursorline' is set highlight the line number of
@ -2821,7 +2823,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (diff_hlf != (hlf_T)0) {
char_attr = win_hl_attr(wp, 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, win_hl_attr(wp, HLF_CUL));
}
}
@ -2881,7 +2884,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (tocol == vcol)
tocol += n_extra;
// Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
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(win_hl_attr(wp, HLF_CUL), char_attr);
}
}
@ -3116,7 +3120,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
line_attr = win_hl_attr(wp, diff_hlf);
// Overlay CursorLine onto diff-mode highlight.
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 = 0 != line_attr_lowprio // Low-priority CursorLine
? hl_combine_attr(hl_combine_attr(win_hl_attr(wp, HLF_CUL),
line_attr),
@ -3924,7 +3929,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
int eol_attr = char_attr;
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') {
eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr);
}
linebuf_attr[off] = eol_attr;

View File

@ -7,6 +7,7 @@ source test_cd.vim
source test_changedtick.vim
source test_compiler.vim
source test_cursor_func.vim
source test_cursorline.vim
source test_ex_equal.vim
source test_ex_undo.vim
source test_ex_z.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