mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 11:58:17 +00:00
Merge pull request #15226 from zeertzjq/vim-8.1.2029
vim-patch:8.1.2029,8.1.2117,8.1.2214,8.2.3204
This commit is contained in:
@@ -1809,14 +1809,21 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
|
|
||||||
|
|
||||||
*'cursorlineopt'* *'culopt'*
|
*'cursorlineopt'* *'culopt'*
|
||||||
'cursorlineopt' 'culopt' string (default: "both")
|
'cursorlineopt' 'culopt' string (default: "number,line")
|
||||||
local to window
|
local to window
|
||||||
Settings for how 'cursorline' is displayed. Valid values:
|
Comma separated list of settings for how 'cursorline' is displayed.
|
||||||
"line" Highlight the text line of the cursor with
|
Valid values:
|
||||||
|
"line" Highlight the text line of the cursor with
|
||||||
CursorLine |hl-CursorLine|.
|
CursorLine |hl-CursorLine|.
|
||||||
"number" Highlight the line number of the cursor with
|
"screenline" Highlight only the screen line of the cursor with
|
||||||
|
CursorLine |hl-CursorLine|.
|
||||||
|
"number" Highlight the line number of the cursor with
|
||||||
CursorLineNr |hl-CursorLineNr|.
|
CursorLineNr |hl-CursorLineNr|.
|
||||||
"both" Highlight as both "line" and "number" are set.
|
|
||||||
|
Special value:
|
||||||
|
"both" Alias for the values "line,number".
|
||||||
|
|
||||||
|
"line" and "screenline" cannot be used together.
|
||||||
|
|
||||||
|
|
||||||
*'debug'*
|
*'debug'*
|
||||||
|
@@ -1388,6 +1388,7 @@ struct window_S {
|
|||||||
uint32_t w_p_fde_flags; // flags for 'foldexpr'
|
uint32_t w_p_fde_flags; // flags for 'foldexpr'
|
||||||
uint32_t w_p_fdt_flags; // flags for 'foldtext'
|
uint32_t w_p_fdt_flags; // flags for 'foldtext'
|
||||||
int *w_p_cc_cols; // array of columns to highlight or NULL
|
int *w_p_cc_cols; // array of columns to highlight or NULL
|
||||||
|
char_u w_p_culopt_flags; // flags for cursorline highlighting
|
||||||
long w_p_siso; // 'sidescrolloff' local value
|
long w_p_siso; // 'sidescrolloff' local value
|
||||||
long w_p_so; // 'scrolloff' local value
|
long w_p_so; // 'scrolloff' local value
|
||||||
|
|
||||||
|
@@ -290,13 +290,21 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume,
|
|||||||
set_topline(wp, wp->w_topline);
|
set_topline(wp, wp->w_topline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relative numbering may require updating more. Cursor line
|
// Relative numbering may require updating more.
|
||||||
// highlighting probably needs to be updated if it's below the
|
if (wp->w_p_rnu) {
|
||||||
// change.
|
|
||||||
if (wp->w_p_rnu
|
|
||||||
|| (wp->w_p_cul && lnum <= wp->w_last_cursorline)) {
|
|
||||||
redraw_later(wp, SOME_VALID);
|
redraw_later(wp, SOME_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cursor line highlighting probably need to be updated with
|
||||||
|
// "VALID" if it's below the change.
|
||||||
|
// If the cursor line is inside the change we need to redraw more.
|
||||||
|
if (wp->w_p_cul) {
|
||||||
|
if (xtra == 0) {
|
||||||
|
redraw_later(wp, VALID);
|
||||||
|
} else if (lnum <= wp->w_last_cursorline) {
|
||||||
|
redraw_later(wp, SOME_VALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1275,6 +1275,15 @@ static void normal_redraw(NormalState *s)
|
|||||||
redrawWinline(curwin, curwin->w_cursor.lnum);
|
redrawWinline(curwin, curwin->w_cursor.lnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Might need to update for 'cursorline'.
|
||||||
|
// When 'cursorlineopt' is "screenline" need to redraw always.
|
||||||
|
if (curwin->w_p_cul
|
||||||
|
&& (curwin->w_last_cursorline != curwin->w_cursor.lnum
|
||||||
|
|| (curwin->w_p_culopt_flags & CULOPT_SCRLINE))
|
||||||
|
&& !char_avail()) {
|
||||||
|
redraw_later(curwin, VALID);
|
||||||
|
}
|
||||||
|
|
||||||
if (VIsual_active) {
|
if (VIsual_active) {
|
||||||
update_curbuf(INVERTED); // update inverted part
|
update_curbuf(INVERTED); // update inverted part
|
||||||
} else if (must_redraw) {
|
} else if (must_redraw) {
|
||||||
|
@@ -322,7 +322,6 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2",
|
|||||||
static char *(p_fdc_values[]) = { "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",
|
"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 };
|
"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'.
|
/// All possible flags for 'shm'.
|
||||||
static char_u SHM_ALL[] = {
|
static char_u SHM_ALL[] = {
|
||||||
@@ -1963,6 +1962,7 @@ static void didset_options(void)
|
|||||||
briopt_check(curwin);
|
briopt_check(curwin);
|
||||||
// initialize the table for 'breakat'.
|
// initialize the table for 'breakat'.
|
||||||
fill_breakat_flags();
|
fill_breakat_flags();
|
||||||
|
fill_culopt_flags(NULL, curwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// More side effects of setting options.
|
// More side effects of setting options.
|
||||||
@@ -2414,8 +2414,7 @@ did_set_string_option(
|
|||||||
}
|
}
|
||||||
} else if (varp == &curwin->w_p_culopt
|
} else if (varp == &curwin->w_p_culopt
|
||||||
|| gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt'
|
|| gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt'
|
||||||
if (**varp == NUL
|
if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK) {
|
||||||
|| check_opt_strings(*varp, p_culopt_values, false) != OK) {
|
|
||||||
errmsg = e_invarg;
|
errmsg = e_invarg;
|
||||||
}
|
}
|
||||||
} else if (varp == &curwin->w_p_cc) { // 'colorcolumn'
|
} else if (varp == &curwin->w_p_cc) { // 'colorcolumn'
|
||||||
@@ -5894,6 +5893,7 @@ void didset_window_options(win_T *wp)
|
|||||||
{
|
{
|
||||||
check_colorcolumn(wp);
|
check_colorcolumn(wp);
|
||||||
briopt_check(wp);
|
briopt_check(wp);
|
||||||
|
fill_culopt_flags(NULL, wp);
|
||||||
set_chars_option(wp, &wp->w_p_fcs, true);
|
set_chars_option(wp, &wp->w_p_fcs, true);
|
||||||
set_chars_option(wp, &wp->w_p_lcs, true);
|
set_chars_option(wp, &wp->w_p_lcs, true);
|
||||||
parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl
|
parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl
|
||||||
@@ -6901,6 +6901,49 @@ static void fill_breakat_flags(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// fill_culopt_flags() -- called when 'culopt' changes value
|
||||||
|
static int fill_culopt_flags(char_u *val, win_T *wp)
|
||||||
|
{
|
||||||
|
char_u *p;
|
||||||
|
char_u culopt_flags_new = 0;
|
||||||
|
|
||||||
|
if (val == NULL) {
|
||||||
|
p = wp->w_p_culopt;
|
||||||
|
} else {
|
||||||
|
p = val;
|
||||||
|
}
|
||||||
|
while (*p != NUL) {
|
||||||
|
if (STRNCMP(p, "line", 4) == 0) {
|
||||||
|
p += 4;
|
||||||
|
culopt_flags_new |= CULOPT_LINE;
|
||||||
|
} else if (STRNCMP(p, "both", 4) == 0) {
|
||||||
|
p += 4;
|
||||||
|
culopt_flags_new |= CULOPT_LINE | CULOPT_NBR;
|
||||||
|
} else if (STRNCMP(p, "number", 6) == 0) {
|
||||||
|
p += 6;
|
||||||
|
culopt_flags_new |= CULOPT_NBR;
|
||||||
|
} else if (STRNCMP(p, "screenline", 10) == 0) {
|
||||||
|
p += 10;
|
||||||
|
culopt_flags_new |= CULOPT_SCRLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p != ',' && *p != NUL) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
if (*p == ',') {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't have both "line" and "screenline".
|
||||||
|
if ((culopt_flags_new & CULOPT_LINE) && (culopt_flags_new & CULOPT_SCRLINE)) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
wp->w_p_culopt_flags = culopt_flags_new;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/// Check an option that can be a range of string values.
|
/// Check an option that can be a range of string values.
|
||||||
///
|
///
|
||||||
/// Return OK for correct value, FAIL otherwise.
|
/// Return OK for correct value, FAIL otherwise.
|
||||||
|
@@ -276,10 +276,10 @@ enum {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// flags used for parsed 'wildmode'
|
// flags used for parsed 'wildmode'
|
||||||
#define WIM_FULL 1
|
#define WIM_FULL 0x01
|
||||||
#define WIM_LONGEST 2
|
#define WIM_LONGEST 0x02
|
||||||
#define WIM_LIST 4
|
#define WIM_LIST 0x04
|
||||||
#define WIM_BUFLASTUSED 8
|
#define WIM_BUFLASTUSED 0x08
|
||||||
|
|
||||||
// arguments for can_bs()
|
// arguments for can_bs()
|
||||||
// each defined char should be unique over all values
|
// each defined char should be unique over all values
|
||||||
@@ -291,6 +291,11 @@ enum {
|
|||||||
#define BS_START 's' // "Start"
|
#define BS_START 's' // "Start"
|
||||||
#define BS_NOSTOP 'p' // "nostoP
|
#define BS_NOSTOP 'p' // "nostoP
|
||||||
|
|
||||||
|
// flags for the 'culopt' option
|
||||||
|
#define CULOPT_LINE 0x01 // Highlight complete line
|
||||||
|
#define CULOPT_SCRLINE 0x02 // Highlight screen line
|
||||||
|
#define CULOPT_NBR 0x04 // Highlight Number column
|
||||||
|
|
||||||
#define LISPWORD_VALUE \
|
#define LISPWORD_VALUE \
|
||||||
"defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
|
"defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
|
||||||
|
|
||||||
|
@@ -558,7 +558,8 @@ return {
|
|||||||
{
|
{
|
||||||
full_name='cursorlineopt', abbreviation='culopt',
|
full_name='cursorlineopt', abbreviation='culopt',
|
||||||
short_desc=N_("settings for 'cursorline'"),
|
short_desc=N_("settings for 'cursorline'"),
|
||||||
type='string', scope={'window'},
|
type='string', list='onecomma', scope={'window'},
|
||||||
|
deny_duplicates=true,
|
||||||
redraw={'current_window_only'},
|
redraw={'current_window_only'},
|
||||||
defaults={if_true={vi="both"}}
|
defaults={if_true={vi="both"}}
|
||||||
},
|
},
|
||||||
|
@@ -1371,7 +1371,9 @@ static void win_update(win_T *wp, Providers *providers)
|
|||||||
// match in fixed position might need redraw
|
// match in fixed position might need redraw
|
||||||
// if lines were inserted or deleted
|
// if lines were inserted or deleted
|
||||||
|| (wp->w_match_head != NULL
|
|| (wp->w_match_head != NULL
|
||||||
&& buf->b_mod_xlines != 0)))))) {
|
&& buf->b_mod_xlines != 0)))))
|
||||||
|
|| (wp->w_p_cul && (lnum == wp->w_cursor.lnum
|
||||||
|
|| lnum == wp->w_last_cursorline))) {
|
||||||
if (lnum == mod_top) {
|
if (lnum == mod_top) {
|
||||||
top_to_mod = false;
|
top_to_mod = false;
|
||||||
}
|
}
|
||||||
@@ -1381,10 +1383,12 @@ static void win_update(win_T *wp, Providers *providers)
|
|||||||
* up or down to minimize redrawing.
|
* up or down to minimize redrawing.
|
||||||
* Don't do this when the change continues until the end.
|
* Don't do this when the change continues until the end.
|
||||||
* Don't scroll when dollar_vcol >= 0, keep the "$".
|
* Don't scroll when dollar_vcol >= 0, keep the "$".
|
||||||
|
* Don't scroll when redrawing the top, scrolled already above.
|
||||||
*/
|
*/
|
||||||
if (lnum == mod_top
|
if (lnum == mod_top
|
||||||
&& mod_bot != MAXLNUM
|
&& mod_bot != MAXLNUM
|
||||||
&& !(dollar_vcol >= 0 && mod_bot == mod_top + 1)) {
|
&& !(dollar_vcol >= 0 && mod_bot == mod_top + 1)
|
||||||
|
&& row >= top_end) {
|
||||||
int old_rows = 0;
|
int old_rows = 0;
|
||||||
int new_rows = 0;
|
int new_rows = 0;
|
||||||
int xtra_rows;
|
int xtra_rows;
|
||||||
@@ -2090,7 +2094,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
sign_attrs_T sattrs[SIGN_SHOW_MAX]; // attributes for signs
|
sign_attrs_T sattrs[SIGN_SHOW_MAX]; // attributes for signs
|
||||||
int num_signs; // number of signs for line
|
int num_signs; // number of signs for line
|
||||||
int line_attr = 0; // attribute for the whole line
|
int line_attr = 0; // attribute for the whole line
|
||||||
|
int line_attr_save;
|
||||||
int line_attr_lowprio = 0; // low-priority attribute for the line
|
int line_attr_lowprio = 0; // low-priority attribute for the line
|
||||||
|
int line_attr_lowprio_save;
|
||||||
matchitem_T *cur; // points to the match list
|
matchitem_T *cur; // points to the match list
|
||||||
match_T *shl; // points to search_hl or a match
|
match_T *shl; // points to search_hl or a match
|
||||||
bool shl_flag; // flag to indicate whether search_hl
|
bool shl_flag; // flag to indicate whether search_hl
|
||||||
@@ -2109,6 +2115,14 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
|
|
||||||
bool area_active = false;
|
bool area_active = false;
|
||||||
|
|
||||||
|
int cul_attr = 0; // set when 'cursorline' active
|
||||||
|
// 'cursorlineopt' has "screenline" and cursor is in this line
|
||||||
|
bool 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;
|
||||||
|
|
||||||
/* draw_state: items that are drawn in sequence: */
|
/* draw_state: items that are drawn in sequence: */
|
||||||
#define WL_START 0 /* nothing done yet */
|
#define WL_START 0 /* nothing done yet */
|
||||||
# define WL_CMDLINE WL_START + 1 /* cmdline window column */
|
# define WL_CMDLINE WL_START + 1 /* cmdline window column */
|
||||||
@@ -2360,26 +2374,34 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
|
|
||||||
// Cursor line highlighting for 'cursorline' in the current window.
|
// Cursor line highlighting for 'cursorline' in the current window.
|
||||||
if (lnum == wp->w_cursor.lnum) {
|
if (lnum == wp->w_cursor.lnum) {
|
||||||
// Do not show the cursor line when Visual mode is active, because it's
|
// Do not show the cursor line in the text when Visual mode is active,
|
||||||
// not clear what is selected then.
|
// 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') {
|
&& wp->w_p_culopt_flags != CULOPT_NBR) {
|
||||||
int cul_attr = win_hl_attr(wp, HLF_CUL);
|
cul_screenline = (wp->w_p_wrap
|
||||||
|
&& (wp->w_p_culopt_flags & CULOPT_SCRLINE));
|
||||||
|
cul_attr = win_hl_attr(wp, HLF_CUL);
|
||||||
HlAttrs ae = syn_attr2entry(cul_attr);
|
HlAttrs ae = syn_attr2entry(cul_attr);
|
||||||
|
|
||||||
// We make a compromise here (#7383):
|
// We make a compromise here (#7383):
|
||||||
// * low-priority CursorLine if fg is not set
|
// * low-priority CursorLine if fg is not set
|
||||||
// * high-priority ("same as Vim" priority) CursorLine if fg is set
|
// * high-priority ("same as Vim" priority) CursorLine if fg is set
|
||||||
if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) {
|
if (!cul_screenline) {
|
||||||
line_attr_lowprio = cul_attr;
|
if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) {
|
||||||
} else {
|
line_attr_lowprio = cul_attr;
|
||||||
if (!(State & INSERT) && bt_quickfix(wp->w_buffer)
|
|
||||||
&& qf_current_entry(wp) == lnum) {
|
|
||||||
line_attr = hl_combine_attr(cul_attr, line_attr);
|
|
||||||
} else {
|
} else {
|
||||||
line_attr = cul_attr;
|
if (!(State & INSERT) && bt_quickfix(wp->w_buffer)
|
||||||
|
&& qf_current_entry(wp) == lnum) {
|
||||||
|
line_attr = hl_combine_attr(cul_attr, line_attr);
|
||||||
|
} else {
|
||||||
|
line_attr = cul_attr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cul_attr = 0;
|
||||||
|
margin_columns_win(wp, &left_curline_col, &right_curline_col);
|
||||||
}
|
}
|
||||||
|
area_highlighting = true;
|
||||||
}
|
}
|
||||||
// Update w_last_cursorline even if Visual mode is active.
|
// Update w_last_cursorline even if Visual mode is active.
|
||||||
wp->w_last_cursorline = wp->w_cursor.lnum;
|
wp->w_last_cursorline = wp->w_cursor.lnum;
|
||||||
@@ -2404,6 +2426,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
area_highlighting = true;
|
area_highlighting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cul_screenline) {
|
||||||
|
line_attr_save = line_attr;
|
||||||
|
line_attr_lowprio_save = line_attr_lowprio;
|
||||||
|
}
|
||||||
|
|
||||||
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
|
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
|
||||||
ptr = line;
|
ptr = line;
|
||||||
|
|
||||||
@@ -2786,12 +2813,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
if (num_sattr != NULL) {
|
if (num_sattr != NULL) {
|
||||||
// :sign defined with "numhl" highlight.
|
// :sign defined with "numhl" highlight.
|
||||||
char_attr = num_sattr->sat_numhl;
|
char_attr = num_sattr->sat_numhl;
|
||||||
} else if ((wp->w_p_cul || wp->w_p_rnu)
|
} else if (wp->w_p_cul
|
||||||
&& *wp->w_p_culopt != 'l'
|
|
||||||
&& lnum == wp->w_cursor.lnum
|
&& lnum == wp->w_cursor.lnum
|
||||||
|
&& (wp->w_p_culopt_flags & CULOPT_NBR)
|
||||||
|
&& (row == startrow
|
||||||
|
|| wp->w_p_culopt_flags & CULOPT_LINE)
|
||||||
&& filler_todo == 0) {
|
&& filler_todo == 0) {
|
||||||
// When 'cursorline' is set highlight the line number of
|
// When 'cursorline' is set highlight the line number of
|
||||||
// the current line differently.
|
// the current line differently.
|
||||||
|
// When 'cursorlineopt' has "screenline" only highlight
|
||||||
|
// the line number itself.
|
||||||
// TODO(vim): Can we use CursorLine instead of CursorLineNr
|
// TODO(vim): Can we use CursorLine instead of CursorLineNr
|
||||||
// when CursorLineNr isn't set?
|
// when CursorLineNr isn't set?
|
||||||
char_attr = win_hl_attr(wp, HLF_CLN);
|
char_attr = win_hl_attr(wp, HLF_CLN);
|
||||||
@@ -2823,9 +2854,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
|
|
||||||
if (diff_hlf != (hlf_T)0) {
|
if (diff_hlf != (hlf_T)0) {
|
||||||
char_attr = win_hl_attr(wp, diff_hlf);
|
char_attr = win_hl_attr(wp, diff_hlf);
|
||||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
|
if (cul_attr) {
|
||||||
&& *wp->w_p_culopt != 'n') {
|
char_attr = hl_combine_attr(char_attr, cul_attr);
|
||||||
char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p_extra = NULL;
|
p_extra = NULL;
|
||||||
@@ -2884,9 +2914,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
if (tocol == vcol)
|
if (tocol == vcol)
|
||||||
tocol += n_extra;
|
tocol += n_extra;
|
||||||
// Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
|
// Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
|
||||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
|
if (cul_attr) {
|
||||||
&& *wp->w_p_culopt != 'n') {
|
char_attr = hl_combine_attr(cul_attr, char_attr);
|
||||||
char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), char_attr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2913,6 +2942,24 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cul_screenline) {
|
||||||
|
if (draw_state == WL_LINE
|
||||||
|
&& vcol >= left_curline_col
|
||||||
|
&& vcol < right_curline_col) {
|
||||||
|
cul_attr = win_hl_attr(wp, HLF_CUL);
|
||||||
|
HlAttrs ae = syn_attr2entry(cul_attr);
|
||||||
|
if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) {
|
||||||
|
line_attr_lowprio = cul_attr;
|
||||||
|
} else {
|
||||||
|
line_attr = cul_attr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cul_attr = 0;
|
||||||
|
line_attr = line_attr_save;
|
||||||
|
line_attr_lowprio = line_attr_lowprio_save;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// When still displaying '$' of change command, stop at cursor
|
// When still displaying '$' of change command, stop at cursor
|
||||||
if (((dollar_vcol >= 0
|
if (((dollar_vcol >= 0
|
||||||
&& wp == curwin
|
&& wp == curwin
|
||||||
@@ -3120,13 +3167,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
}
|
}
|
||||||
line_attr = win_hl_attr(wp, diff_hlf);
|
line_attr = win_hl_attr(wp, diff_hlf);
|
||||||
// Overlay CursorLine onto diff-mode highlight.
|
// Overlay CursorLine onto diff-mode highlight.
|
||||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
|
if (cul_attr) {
|
||||||
&& *wp->w_p_culopt != 'n') {
|
|
||||||
line_attr = 0 != line_attr_lowprio // Low-priority CursorLine
|
line_attr = 0 != line_attr_lowprio // Low-priority CursorLine
|
||||||
? hl_combine_attr(hl_combine_attr(win_hl_attr(wp, HLF_CUL),
|
? hl_combine_attr(hl_combine_attr(cul_attr, line_attr),
|
||||||
line_attr),
|
|
||||||
hl_get_underline())
|
hl_get_underline())
|
||||||
: hl_combine_attr(line_attr, win_hl_attr(wp, HLF_CUL));
|
: hl_combine_attr(line_attr, cul_attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3202,6 +3247,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
(void)mb_l;
|
(void)mb_l;
|
||||||
multi_attr = win_hl_attr(wp, HLF_AT);
|
multi_attr = win_hl_attr(wp, HLF_AT);
|
||||||
|
|
||||||
|
if (cul_attr) {
|
||||||
|
multi_attr = 0 != line_attr_lowprio
|
||||||
|
? hl_combine_attr(cul_attr, multi_attr)
|
||||||
|
: hl_combine_attr(multi_attr, cul_attr);
|
||||||
|
}
|
||||||
|
|
||||||
// put the pointer back to output the double-width
|
// put the pointer back to output the double-width
|
||||||
// character at the start of the next line.
|
// character at the start of the next line.
|
||||||
n_extra++;
|
n_extra++;
|
||||||
@@ -3362,7 +3413,13 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
ptr = line + v;
|
ptr = line + v;
|
||||||
|
|
||||||
if (!attr_pri) {
|
if (!attr_pri) {
|
||||||
char_attr = syntax_attr;
|
if (cul_attr) {
|
||||||
|
char_attr = 0 != line_attr_lowprio
|
||||||
|
? hl_combine_attr(cul_attr, syntax_attr)
|
||||||
|
: hl_combine_attr(syntax_attr, cul_attr);
|
||||||
|
} else {
|
||||||
|
char_attr = syntax_attr;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
char_attr = hl_combine_attr(syntax_attr, char_attr);
|
char_attr = hl_combine_attr(syntax_attr, char_attr);
|
||||||
}
|
}
|
||||||
@@ -3929,9 +3986,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int eol_attr = char_attr;
|
int eol_attr = char_attr;
|
||||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
|
if (cul_attr) {
|
||||||
&& *wp->w_p_culopt != 'n') {
|
eol_attr = hl_combine_attr(cul_attr, eol_attr);
|
||||||
eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr);
|
|
||||||
}
|
}
|
||||||
linebuf_attr[off] = eol_attr;
|
linebuf_attr[off] = eol_attr;
|
||||||
if (wp->w_p_rl) {
|
if (wp->w_p_rl) {
|
||||||
@@ -7516,6 +7572,49 @@ int number_width(win_T *wp)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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;
|
||||||
|
}
|
||||||
|
|
||||||
/// Set dimensions of the Nvim application "shell".
|
/// Set dimensions of the Nvim application "shell".
|
||||||
void screen_resize(int width, int height)
|
void screen_resize(int width, int height)
|
||||||
{
|
{
|
||||||
|
@@ -6081,7 +6081,7 @@ static const char *highlight_init_light[] = {
|
|||||||
"ColorColumn ctermbg=LightRed guibg=LightRed",
|
"ColorColumn ctermbg=LightRed guibg=LightRed",
|
||||||
"CursorColumn ctermbg=LightGrey guibg=Grey90",
|
"CursorColumn ctermbg=LightGrey guibg=Grey90",
|
||||||
"CursorLine cterm=underline guibg=Grey90",
|
"CursorLine cterm=underline guibg=Grey90",
|
||||||
"CursorLineNr ctermfg=Brown gui=bold guifg=Brown",
|
"CursorLineNr cterm=underline ctermfg=Brown gui=bold guifg=Brown",
|
||||||
"DiffAdd ctermbg=LightBlue guibg=LightBlue",
|
"DiffAdd ctermbg=LightBlue guibg=LightBlue",
|
||||||
"DiffChange ctermbg=LightMagenta guibg=LightMagenta",
|
"DiffChange ctermbg=LightMagenta guibg=LightMagenta",
|
||||||
"DiffDelete ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan",
|
"DiffDelete ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan",
|
||||||
@@ -6132,7 +6132,7 @@ static const char *highlight_init_dark[] = {
|
|||||||
"ColorColumn ctermbg=DarkRed guibg=DarkRed",
|
"ColorColumn ctermbg=DarkRed guibg=DarkRed",
|
||||||
"CursorColumn ctermbg=DarkGrey guibg=Grey40",
|
"CursorColumn ctermbg=DarkGrey guibg=Grey40",
|
||||||
"CursorLine cterm=underline guibg=Grey40",
|
"CursorLine cterm=underline guibg=Grey40",
|
||||||
"CursorLineNr ctermfg=Yellow gui=bold guifg=Yellow",
|
"CursorLineNr cterm=underline ctermfg=Yellow gui=bold guifg=Yellow",
|
||||||
"DiffAdd ctermbg=DarkBlue guibg=DarkBlue",
|
"DiffAdd ctermbg=DarkBlue guibg=DarkBlue",
|
||||||
"DiffChange ctermbg=DarkMagenta guibg=DarkMagenta",
|
"DiffChange ctermbg=DarkMagenta guibg=DarkMagenta",
|
||||||
"DiffDelete ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan",
|
"DiffDelete ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan",
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
" Test for cursorline and cursorlineopt
|
" Test for cursorline and cursorlineopt
|
||||||
"
|
|
||||||
source view_util.vim
|
|
||||||
source check.vim
|
source check.vim
|
||||||
|
source screendump.vim
|
||||||
|
|
||||||
function! s:screen_attr(lnum) abort
|
function! s:screen_attr(lnum) abort
|
||||||
return map(range(1, 8), 'screenattr(a:lnum, v:val)')
|
return map(range(1, 8), 'screenattr(a:lnum, v:val)')
|
||||||
@@ -52,7 +52,7 @@ func Test_cursorline_highlight1()
|
|||||||
setl nocursorline relativenumber
|
setl nocursorline relativenumber
|
||||||
redraw
|
redraw
|
||||||
let attr31 = s:screen_attr(1)
|
let attr31 = s:screen_attr(1)
|
||||||
call assert_equal(attr21[0:3], attr31[0:3])
|
call assert_equal(attr22[0:3], attr31[0:3])
|
||||||
call assert_equal(attr11[4:7], attr31[4:7])
|
call assert_equal(attr11[4:7], attr31[4:7])
|
||||||
|
|
||||||
call s:close_windows()
|
call s:close_windows()
|
||||||
@@ -106,3 +106,144 @@ func Test_cursorline_highlight2()
|
|||||||
exe 'hi' save_hi
|
exe 'hi' save_hi
|
||||||
endtry
|
endtry
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_cursorline_screenline()
|
||||||
|
CheckScreendump
|
||||||
|
CheckOption cursorlineopt
|
||||||
|
|
||||||
|
let filename='Xcursorline'
|
||||||
|
let lines = []
|
||||||
|
|
||||||
|
let file_content =<< trim END
|
||||||
|
1 foooooooo ar einszwei drei vier fünf sechs sieben acht un zehn elf zwöfl dreizehn v ierzehn fünfzehn
|
||||||
|
2 foooooooo bar eins zwei drei vier fünf sechs sieben
|
||||||
|
3 foooooooo bar eins zwei drei vier fünf sechs sieben
|
||||||
|
4 foooooooo bar eins zwei drei vier fünf sechs sieben
|
||||||
|
END
|
||||||
|
let lines1 =<< trim END1
|
||||||
|
set nocp
|
||||||
|
set display=lastline
|
||||||
|
set cursorlineopt=screenline cursorline nu wrap sbr=>
|
||||||
|
hi CursorLineNr ctermfg=blue
|
||||||
|
25vsp
|
||||||
|
END1
|
||||||
|
let lines2 =<< trim END2
|
||||||
|
call cursor(1,1)
|
||||||
|
END2
|
||||||
|
call extend(lines, lines1)
|
||||||
|
call extend(lines, ["call append(0, ".. string(file_content).. ')'])
|
||||||
|
call extend(lines, lines2)
|
||||||
|
call writefile(lines, filename)
|
||||||
|
" basic test
|
||||||
|
let buf = RunVimInTerminal('-S '. filename, #{rows: 20})
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_1', {})
|
||||||
|
call term_sendkeys(buf, "fagj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_2', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_3', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_4', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_5', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_6', {})
|
||||||
|
" test with set list and cursorlineopt containing number
|
||||||
|
call term_sendkeys(buf, "gg0")
|
||||||
|
call term_sendkeys(buf, ":set list cursorlineopt+=number listchars=space:-\<cr>")
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_7', {})
|
||||||
|
call term_sendkeys(buf, "fagj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_8', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_9', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_10', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_11', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_12', {})
|
||||||
|
if exists("+foldcolumn") && exists("+signcolumn") && exists("+breakindent")
|
||||||
|
" test with set foldcolumn signcoloumn and breakindent
|
||||||
|
call term_sendkeys(buf, "gg0")
|
||||||
|
call term_sendkeys(buf, ":set breakindent foldcolumn=2 signcolumn=yes\<cr>")
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_13', {})
|
||||||
|
call term_sendkeys(buf, "fagj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_14', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_15', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_16', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_17', {})
|
||||||
|
call term_sendkeys(buf, "gj")
|
||||||
|
call term_wait(buf)
|
||||||
|
call VerifyScreenDump(buf, 'Test_'. filename. '_18', {})
|
||||||
|
endif
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete(filename)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_cursorline_redraw()
|
||||||
|
CheckScreendump
|
||||||
|
CheckOption cursorlineopt
|
||||||
|
|
||||||
|
let textlines =<< END
|
||||||
|
When the option is a list of flags, {value} must be
|
||||||
|
exactly as they appear in the option. Remove flags
|
||||||
|
one by one to avoid problems.
|
||||||
|
Also see |:set-args| above.
|
||||||
|
|
||||||
|
The {option} arguments to ":set" may be repeated. For example: >
|
||||||
|
:set ai nosi sw=3 ts=3
|
||||||
|
If you make an error in one of the arguments, an error message will be given
|
||||||
|
and the following arguments will be ignored.
|
||||||
|
|
||||||
|
*:set-verbose*
|
||||||
|
When 'verbose' is non-zero, displaying an option value will also tell where it
|
||||||
|
was last set. Example: >
|
||||||
|
:verbose set shiftwidth cindent?
|
||||||
|
< shiftwidth=4 ~
|
||||||
|
Last set from modeline line 1 ~
|
||||||
|
cindent ~
|
||||||
|
Last set from /usr/local/share/vim/vim60/ftplugin/c.vim line 30 ~
|
||||||
|
This is only done when specific option values are requested, not for ":verbose
|
||||||
|
set all" or ":verbose set" without an argument.
|
||||||
|
When the option was set by hand there is no "Last set" message.
|
||||||
|
When the option was set while executing a function, user command or
|
||||||
|
END
|
||||||
|
call writefile(textlines, 'Xtextfile')
|
||||||
|
|
||||||
|
let script =<< trim END
|
||||||
|
set cursorline scrolloff=2
|
||||||
|
normal 12G
|
||||||
|
END
|
||||||
|
call writefile(script, 'Xscript')
|
||||||
|
|
||||||
|
let buf = RunVimInTerminal('-S Xscript Xtextfile', #{rows: 20, cols: 40})
|
||||||
|
call VerifyScreenDump(buf, 'Test_cursorline_redraw_1', {})
|
||||||
|
call term_sendkeys(buf, "zt")
|
||||||
|
call TermWait(buf)
|
||||||
|
call term_sendkeys(buf, "\<C-U>")
|
||||||
|
call VerifyScreenDump(buf, 'Test_cursorline_redraw_2', {})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
call delete('Xtextfile')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -1057,7 +1057,7 @@ it('diff updates line numbers below filler lines', function()
|
|||||||
vnew
|
vnew
|
||||||
call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b'])
|
call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b'])
|
||||||
windo diffthis
|
windo diffthis
|
||||||
setlocal number rnu foldcolumn=0
|
setlocal number rnu cursorline cursorlineopt=number foldcolumn=0
|
||||||
]])
|
]])
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{1: }a {3:│}{10:1 }^a |
|
{1: }a {3:│}{10:1 }^a |
|
||||||
@@ -1109,7 +1109,7 @@ it('diff updates line numbers below filler lines', function()
|
|||||||
{3:[No Name] [+] }{7:[No Name] [+] }|
|
{3:[No Name] [+] }{7:[No Name] [+] }|
|
||||||
|
|
|
|
||||||
]])
|
]])
|
||||||
command("set signcolumn number tgc cursorline")
|
command("set signcolumn number tgc cursorline cursorlineopt=number,line")
|
||||||
command("hi CursorLineNr guibg=red")
|
command("hi CursorLineNr guibg=red")
|
||||||
screen:expect{grid=[[
|
screen:expect{grid=[[
|
||||||
{1: }a {3:│}{11: 2 }a |
|
{1: }a {3:│}{11: 2 }a |
|
||||||
|
@@ -85,7 +85,7 @@ describe("folded lines", function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it("highlighting with relative line numbers", function()
|
it("highlighting with relative line numbers", function()
|
||||||
command("set relativenumber foldmethod=marker")
|
command("set relativenumber cursorline cursorlineopt=number foldmethod=marker")
|
||||||
feed_command("set foldcolumn=2")
|
feed_command("set foldcolumn=2")
|
||||||
funcs.setline(1, '{{{1')
|
funcs.setline(1, '{{{1')
|
||||||
funcs.setline(2, 'line 1')
|
funcs.setline(2, 'line 1')
|
||||||
|
Reference in New Issue
Block a user