Merge #15626 vim-patch:8.1.{2281,2283},8.2.{2903,3391,3397}

This commit is contained in:
Justin M. Keyes 2021-09-10 08:43:45 -07:00 committed by GitHub
commit 7525052270
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 131 additions and 42 deletions

View File

@ -5476,7 +5476,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'showbreak'* *'sbr'* *E595*
'showbreak' 'sbr' string (default "")
global
global or local to window |global-local|
String to put at the start of lines that have been wrapped. Useful
values are "> " or "+++ ": >
:set showbreak=>\
@ -5490,7 +5490,10 @@ A jump table for the options with a short description can be found at |Q_op|.
Note that tabs after the showbreak will be displayed differently.
If you want the 'showbreak' to appear in between line numbers, add the
"n" flag to 'cpoptions'.
A window-local value overrules a global value. If the global value is
set and you want no value in the current window use NONE: >
:setlocal showbreak=NONE
<
*'showcmd'* *'sc'* *'noshowcmd'* *'nosc'*
'showcmd' 'sc' boolean (Vim default: on, Vi default: off)
global

View File

@ -230,6 +230,8 @@ typedef struct {
# 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_sbr;
# define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak'
char_u *wo_stl;
#define w_p_stl w_onebuf_opt.wo_stl // 'statusline'
int wo_scb;

View File

@ -941,7 +941,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
// Also use this when 'list' is set but tabs take their normal size.
if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL))
&& !wp->w_p_lbr
&& (*p_sbr == NUL)
&& *get_showbreak_value(wp) == NUL
&& !wp->w_p_bri ) {
for (;;) {
head = 0;

View File

@ -788,11 +788,12 @@ void curs_columns(
wp->w_wcol -= n * width;
wp->w_wrow += n;
/* When cursor wraps to first char of next line in Insert
* mode, the 'showbreak' string isn't shown, backup to first
* column */
if (*p_sbr && *get_cursor_pos_ptr() == NUL
&& wp->w_wcol == (int)vim_strsize(p_sbr)) {
// When cursor wraps to first char of next line in Insert
// mode, the 'showbreak' string isn't shown, backup to first
// column
char_u *const sbr = get_showbreak_value(wp);
if (*sbr && *get_cursor_pos_ptr() == NUL
&& wp->w_wcol == (int)vim_strsize(sbr)) {
wp->w_wcol = 0;
}
}

View File

@ -3407,12 +3407,15 @@ void clear_showcmd(void)
lines = bot - top + 1;
if (VIsual_mode == Ctrl_V) {
char_u *saved_sbr = p_sbr;
char_u *const saved_sbr = p_sbr;
char_u *const saved_w_sbr = curwin->w_p_sbr;
// Make 'sbr' empty for a moment to get the correct size.
p_sbr = empty_option;
curwin->w_p_sbr = empty_option;
getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
p_sbr = saved_sbr;
curwin->w_p_sbr = saved_w_sbr;
snprintf((char *)showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64 "x%" PRId64,
(int64_t)lines, (int64_t)rightcol - leftcol + 1);
} else if (VIsual_mode == 'V' || VIsual.lnum != curwin->w_cursor.lnum) {
@ -4141,8 +4144,8 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
*/
validate_virtcol();
colnr_T virtcol = curwin->w_virtcol;
if (virtcol > (colnr_T)width1 && *p_sbr != NUL) {
virtcol -= vim_strsize(p_sbr);
if (virtcol > (colnr_T)width1 && *get_showbreak_value(curwin) != NUL) {
virtcol -= vim_strsize(get_showbreak_value(curwin));
}
if (virtcol > curwin->w_curswant

View File

@ -5726,16 +5726,19 @@ void cursor_pos_info(dict_T *dict)
}
if (l_VIsual_mode == Ctrl_V) {
char_u * saved_sbr = p_sbr;
char_u *const saved_sbr = p_sbr;
char_u *const saved_w_sbr = curwin->w_p_sbr;
// Make 'sbr' empty for a moment to get the correct size.
p_sbr = empty_option;
curwin->w_p_sbr = empty_option;
oparg.is_VIsual = true;
oparg.motion_type = kMTBlockWise;
oparg.op_type = OP_NOP;
getvcols(curwin, &min_pos, &max_pos,
&oparg.start_vcol, &oparg.end_vcol);
p_sbr = saved_sbr;
curwin->w_p_sbr = saved_w_sbr;
if (curwin->w_curswant == MAXCOL) {
oparg.end_vcol = MAXCOL;
}

View File

@ -2740,10 +2740,11 @@ ambw_end:
if (*p_shada && errmsg == NULL && get_shada_parameter('\'') < 0) {
errmsg = (char_u *)N_("E528: Must specify a ' value");
}
} else if (varp == &p_sbr) { // 'showbreak'
for (s = p_sbr; *s; ) {
} else if (gvarp == &p_sbr) { // 'showbreak'
for (s = *varp; *s; ) {
if (ptr2cells(s) != 1) {
errmsg = (char_u *)N_("E595: contains unprintable or wide character");
errmsg = (char_u *)N_(
"E595: 'showbreak' contains unprintable or wide character");
}
MB_PTR_ADV(s);
}
@ -5523,6 +5524,9 @@ void unset_global_local_option(char *name, void *from)
case PV_MP:
clear_string_option(&buf->b_p_mp);
break;
case PV_SBR:
clear_string_option(&((win_T *)from)->w_p_sbr);
break;
case PV_STL:
clear_string_option(&((win_T *)from)->w_p_stl);
break;
@ -5576,6 +5580,7 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
case PV_TFU: return (char_u *)&(curbuf->b_p_tfu);
case PV_SBR: return (char_u *)&(curwin->w_p_sbr);
case PV_STL: return (char_u *)&(curwin->w_p_stl);
case PV_UL: return (char_u *)&(curbuf->b_p_ul);
case PV_LW: return (char_u *)&(curbuf->b_p_lw);
@ -5635,6 +5640,8 @@ static char_u *get_varp(vimoption_T *p)
? (char_u *)&(curbuf->b_p_gp) : p->var;
case PV_MP: return *curbuf->b_p_mp != NUL
? (char_u *)&(curbuf->b_p_mp) : p->var;
case PV_SBR: return *curwin->w_p_sbr != NUL
? (char_u *)&(curwin->w_p_sbr) : p->var;
case PV_STL: return *curwin->w_p_stl != NUL
? (char_u *)&(curwin->w_p_stl) : p->var;
case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
@ -5788,6 +5795,7 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_nuw = from->wo_nuw;
to->wo_rl = from->wo_rl;
to->wo_rlc = vim_strsave(from->wo_rlc);
to->wo_sbr = vim_strsave(from->wo_sbr);
to->wo_stl = vim_strsave(from->wo_stl);
to->wo_wrap = from->wo_wrap;
to->wo_wrap_save = from->wo_wrap_save;
@ -5851,6 +5859,7 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_fmr);
check_string_option(&wop->wo_scl);
check_string_option(&wop->wo_rlc);
check_string_option(&wop->wo_sbr);
check_string_option(&wop->wo_stl);
check_string_option(&wop->wo_culopt);
check_string_option(&wop->wo_cc);
@ -5874,6 +5883,7 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_fmr);
clear_string_option(&wop->wo_scl);
clear_string_option(&wop->wo_rlc);
clear_string_option(&wop->wo_sbr);
clear_string_option(&wop->wo_stl);
clear_string_option(&wop->wo_culopt);
clear_string_option(&wop->wo_cc);
@ -7472,6 +7482,22 @@ unsigned int get_bkc_value(buf_T *buf)
return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
}
/// Get the local or global value of 'showbreak'.
///
/// @param win If not NULL, the window to get the local option from; global
/// otherwise.
char_u *get_showbreak_value(win_T *const win FUNC_ATTR_UNUSED)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (win->w_p_sbr == NULL || *win->w_p_sbr == NUL) {
return p_sbr;
}
if (STRCMP(win->w_p_sbr, "NONE") == 0) {
return empty_option;
}
return win->w_p_sbr;
}
/// Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
int get_fileformat(const buf_T *buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
@ -7672,12 +7698,6 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
return ret;
}
// Get the local or global value of 'showbreak'.
char_u *get_showbreak_value(win_T *win FUNC_ATTR_UNUSED)
{
return p_sbr;
}
/// Get window or buffer local options
dict_T *get_winbuf_options(const int bufopt)
FUNC_ATTR_WARN_UNUSED_RESULT

View File

@ -877,6 +877,7 @@ enum {
, WV_CUL
, WV_CULOPT
, WV_CC
, WV_SBR
, WV_STL
, WV_WFH
, WV_WFW

View File

@ -2175,7 +2175,7 @@ return {
{
full_name='showbreak', abbreviation='sbr',
short_desc=N_("string to use at the start of wrapped lines"),
type='string', scope={'global'},
type='string', scope={'global', 'window'},
redraw={'all_windows'},
varname='p_sbr',
defaults={if_true=""}

View File

@ -263,7 +263,8 @@ unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len)
/// @return The number of characters taken up on the screen.
int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col)
{
if (!curwin->w_p_lbr && (*p_sbr == NUL) && !curwin->w_p_bri) {
if (!curwin->w_p_lbr && *get_showbreak_value(curwin) == NUL
&& !curwin->w_p_bri) {
if (curwin->w_p_wrap) {
return win_nolbr_chartabsize(curwin, s, col, NULL);
}
@ -314,7 +315,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s,
int n;
// No 'linebreak', 'showbreak' and 'breakindent': return quickly.
if (!wp->w_p_lbr && !wp->w_p_bri && (*p_sbr == NUL)) {
if (!wp->w_p_lbr && !wp->w_p_bri && *get_showbreak_value(wp) == NUL) {
if (wp->w_p_wrap) {
return win_nolbr_chartabsize(wp, s, col, headp);
}
@ -381,7 +382,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s,
// Set *headp to the size of what we add.
added = 0;
if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && (col != 0)) {
char_u *const sbr = get_showbreak_value(wp);
if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && col != 0) {
colnr_T sbrlen = 0;
int numberwidth = win_col_off(wp);
@ -394,8 +396,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s,
if (col >= numberextra && numberextra > 0) {
col %= numberextra;
}
if (*p_sbr != NUL) {
sbrlen = (colnr_T)MB_CHARLEN(p_sbr);
if (*sbr != NUL) {
sbrlen = (colnr_T)MB_CHARLEN(sbr);
if (col >= sbrlen) {
col -= sbrlen;
}
@ -410,7 +412,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s,
}
if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) {
if (*p_sbr != NUL) {
if (*sbr != NUL) {
if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) {
// Calculate effective window width.
int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth;
@ -420,13 +422,13 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s,
if (width <= 0) {
width = 1;
}
added += ((size - prev_width) / width) * vim_strsize(p_sbr);
added += ((size - prev_width) / width) * vim_strsize(sbr);
if ((size - prev_width) % width) {
// Wrapped, add another length of 'sbr'.
added += vim_strsize(p_sbr);
added += vim_strsize(sbr);
}
} else {
added += vim_strsize(p_sbr);
added += vim_strsize(sbr);
}
}

View File

@ -2850,7 +2850,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
}
if (wp->w_briopt_sbr && draw_state == WL_BRI - 1
&& n_extra == 0 && *p_sbr != NUL) {
&& n_extra == 0 && *get_showbreak_value(wp) != NUL) {
// draw indent after showbreak value
draw_state = WL_BRI;
} else if (wp->w_briopt_sbr && draw_state == WL_SBR && n_extra == 0) {
@ -2909,19 +2909,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
}
char_attr = win_hl_attr(wp, HLF_DED);
}
if (*p_sbr != NUL && need_showbreak) {
char_u *const sbr = get_showbreak_value(wp);
if (*sbr != NUL && need_showbreak) {
// Draw 'showbreak' at the start of each broken line.
p_extra = p_sbr;
p_extra = sbr;
c_extra = NUL;
c_final = NUL;
n_extra = (int)STRLEN(p_sbr);
n_extra = (int)STRLEN(sbr);
char_attr = win_hl_attr(wp, HLF_AT);
if (wp->w_skipcol == 0 || !wp->w_p_wrap) {
need_showbreak = false;
}
vcol_sbr = vcol + MB_CHARLEN(p_sbr);
/* Correct end of highlighted area for 'showbreak',
* required when 'linebreak' is also set. */
vcol_sbr = vcol + MB_CHARLEN(sbr);
// Correct end of highlighted area for 'showbreak',
// required when 'linebreak' is also set.
if (tocol == vcol) {
tocol += n_extra;
}
@ -3553,6 +3554,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
char_u *p = ptr - (mb_off + 1);
// TODO: is passing p for start of the line OK?
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1;
// We have just drawn the showbreak value, no need to add
// space for it again.
if (vcol == vcol_sbr) {
n_extra -= MB_CHARLEN(get_showbreak_value(wp));
if (n_extra < 0) {
n_extra = 0;
}
}
if (c == TAB && n_extra + col > grid->Columns) {
n_extra = tabstop_padding(vcol, wp->w_buffer->b_p_ts,
wp->w_buffer->b_p_vts_array) - 1;
@ -3619,10 +3630,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
if (c == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
int tab_len = 0;
long vcol_adjusted = vcol; // removed showbreak length
char_u *const sbr = get_showbreak_value(wp);
// Only adjust the tab_len, when at the first column after the
// showbreak value was drawn.
if (*p_sbr != NUL && vcol == vcol_sbr && wp->w_p_wrap) {
vcol_adjusted = vcol - MB_CHARLEN(p_sbr);
if (*sbr != NUL && vcol == vcol_sbr && wp->w_p_wrap) {
vcol_adjusted = vcol - MB_CHARLEN(sbr);
}
// tab amount depends on current column
tab_len = tabstop_padding(vcol_adjusted,

View File

@ -67,7 +67,8 @@ endfunc
func Test_breakindent02()
" simple breakindent test with showbreak set
call s:test_windows('setl briopt=min:0 sbr=>>')
set sbr=>>
call s:test_windows('setl briopt=min:0 sbr=')
let lines = s:screen_lines(line('.'),8)
let expect = [
\ " abcd",
@ -127,7 +128,8 @@ endfunc
func Test_breakindent04()
" breakindent set with min width 18
call s:test_windows('setl sbr= briopt=min:18')
set sbr=<<<
call s:test_windows('setl sbr=NONE briopt=min:18')
let lines = s:screen_lines(line('.'),8)
let expect = [
\ " abcd",
@ -137,6 +139,7 @@ func Test_breakindent04()
call s:compare_lines(expect, lines)
" clean up
call s:close_windows('set sbr=')
set sbr=
endfunc
func Test_breakindent04_vartabs()
@ -868,4 +871,22 @@ func Test_breakindent20_list()
call s:close_windows('set breakindent& briopt& linebreak& list& listchars& showbreak&')
endfunc
" The following used to crash Vim. This is fixed by 8.2.3391.
" This is a regression introduced by 8.2.2903.
func Test_window_resize_with_linebreak()
new
53vnew
set linebreak
set showbreak=>>
set breakindent
set breakindentopt=shift:4
call setline(1, "\naaaaaaaaa\n\na\naaaaa\n¯aaaaaaaaaa\naaaaaaaaaaaa\naaa\n\"a:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaa\"\naaaaaaaa\n\"a")
redraw!
call assert_equal([" >>aa^@\"a: "], ScreenLines(2, 14))
vertical resize 52
redraw!
call assert_equal([" >>aaa^@\"a:"], ScreenLines(2, 14))
%bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -262,3 +262,21 @@ func Test_display_scroll_at_topline()
call StopVimInTerminal(buf)
endfunc
func Test_display_linebreak_breakat()
new
vert resize 25
let _breakat = &breakat
setl signcolumn=yes linebreak breakat=) showbreak=+\
call setline(1, repeat('x', winwidth(0) - 2) .. ')abc')
let lines = ScreenLines([1, 2], 25)
let expected = [
\ ' xxxxxxxxxxxxxxxxxxxxxxx',
\ ' + )abc '
\ ]
call assert_equal(expected, lines)
%bw!
let &breakat=_breakat
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -426,6 +426,7 @@ func Test_highlight_eol_with_cursorline_breakindent()
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
call NewWindow('topleft 5', 10)
set showbreak=xxx
setlocal breakindent breakindentopt=min:0,shift:1 showbreak=>
call setline(1, ' ' . repeat('a', 9) . 'bcd')
call matchadd('Search', '\n')
@ -483,6 +484,7 @@ func Test_highlight_eol_with_cursorline_breakindent()
call CloseWindow()
set showbreak=
setlocal showbreak=
exe hiCursorLine
endfunc