# HG changeset patch # User Bram Moolenaar # Date 1573338603 -3600 # Node ID 8b0114ffde2bd843aad78856308b3c5ea29d867f # Parent f18a4ae518f167b229e9788d2897188e9cf60e89 patch 8.1.2281: 'showbreak' cannot be set for one window Commit: https://github.com/vim/vim/commit/ee85702c10495041791f728e977b86005c4496e8 Author: Bram Moolenaar Date: Sat Nov 9 23:26:40 2019 +0100 patch 8.1.2281: 'showbreak' cannot be set for one window Problem: 'showbreak' cannot be set for one window. Solution: Make 'showbreak' global-local. diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -6748,7 +6748,7 @@ A jump table for the options with a shor *'showbreak'* *'sbr'* *E595* 'showbreak' 'sbr' string (default "") - global + global or local to window |global-local| {not available when compiled without the |+linebreak| feature} String to put at the start of lines that have been wrapped. Useful @@ -6765,7 +6765,10 @@ A jump table for the options with a shor 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, off for Unix, Vi default: off, set in |defaults.vim|) diff --git a/src/charset.c b/src/charset.c --- a/src/charset.c +++ b/src/charset.c @@ -936,7 +936,8 @@ lbr_chartabsize( colnr_T col) { #ifdef FEAT_LINEBREAK - 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) { #endif if (curwin->w_p_wrap) @@ -991,11 +992,12 @@ win_lbr_chartabsize( char_u *ps; int tab_corr = (*s == TAB); int n; + char_u *sbr; /* * 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) #endif { if (wp->w_p_wrap) @@ -1069,7 +1071,8 @@ win_lbr_chartabsize( * 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) + 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); @@ -1082,9 +1085,9 @@ win_lbr_chartabsize( numberextra = wp->w_width - (numberextra - win_col_off2(wp)); if (col >= numberextra && numberextra > 0) col %= numberextra; - if (*p_sbr != NUL) + if (*sbr != NUL) { - sbrlen = (colnr_T)MB_CHARLEN(p_sbr); + sbrlen = (colnr_T)MB_CHARLEN(sbr); if (col >= sbrlen) col -= sbrlen; } @@ -1098,7 +1101,7 @@ win_lbr_chartabsize( if (col == 0 || col + size + sbrlen > (colnr_T)wp->w_width) { added = 0; - if (*p_sbr != NUL) + if (*sbr != NUL) { if (size + sbrlen + numberwidth > (colnr_T)wp->w_width) { @@ -1109,13 +1112,13 @@ win_lbr_chartabsize( if (width <= 0) width = (colnr_T)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); } if (wp->w_p_bri) added += get_breakindent_win(wp, line); @@ -1242,7 +1245,7 @@ getvcol( */ if ((!wp->w_p_list || lcs_tab1 != NUL) #ifdef FEAT_LINEBREAK - && !wp->w_p_lbr && *p_sbr == NUL && !wp->w_p_bri + && !wp->w_p_lbr && *get_showbreak_value(wp) == NUL && !wp->w_p_bri #endif ) { diff --git a/src/drawline.c b/src/drawline.c --- a/src/drawline.c +++ b/src/drawline.c @@ -1141,7 +1141,7 @@ win_line( #ifdef FEAT_LINEBREAK if (wp->w_p_brisbr && 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_p_brisbr && draw_state == WL_SBR && n_extra == 0) @@ -1187,6 +1187,8 @@ win_line( #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF) if (draw_state == WL_SBR - 1 && n_extra == 0) { + char_u *sbr; + draw_state = WL_SBR; # ifdef FEAT_DIFF if (filler_todo > 0) @@ -1212,16 +1214,17 @@ win_line( } # endif # ifdef FEAT_LINEBREAK - if (*p_sbr != NUL && need_showbreak) + 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 = HL_ATTR(HLF_AT); need_showbreak = FALSE; - vcol_sbr = vcol + MB_CHARLEN(p_sbr); + vcol_sbr = vcol + MB_CHARLEN(sbr); // Correct end of highlighted area for 'showbreak', // required when 'linebreak' is also set. if (tocol == vcol) @@ -2011,10 +2014,12 @@ win_line( int tab_len = 0; long vcol_adjusted = vcol; // removed showbreak length #ifdef FEAT_LINEBREAK + char_u *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); #endif // tab amount depends on current column #ifdef FEAT_VARTABS diff --git a/src/edit.c b/src/edit.c --- a/src/edit.c +++ b/src/edit.c @@ -3238,7 +3238,7 @@ oneleft(void) /* getviscol() is slow, skip it when 'showbreak' is empty, * 'breakindent' is not set and there are no multi-byte * characters */ - if ((*p_sbr == NUL && !curwin->w_p_bri + if ((*get_showbreak_value(curwin) == NUL && !curwin->w_p_bri && !has_mbyte) || getviscol() < v) break; ++width; diff --git a/src/move.c b/src/move.c --- a/src/move.c +++ b/src/move.c @@ -988,6 +988,8 @@ curs_columns( /* long line wrapping, adjust curwin->w_wrow */ if (curwin->w_wcol >= curwin->w_width) { + char_u *sbr; + /* this same formula is used in validate_cursor_col() */ n = (curwin->w_wcol - curwin->w_width) / width + 1; curwin->w_wcol -= n * width; @@ -997,8 +999,9 @@ curs_columns( /* 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 && *ml_get_cursor() == NUL - && curwin->w_wcol == (int)vim_strsize(p_sbr)) + sbr = get_showbreak_value(curwin); + if (*sbr && *ml_get_cursor() == NUL + && curwin->w_wcol == (int)vim_strsize(sbr)) curwin->w_wcol = 0; #endif } diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -1768,13 +1768,16 @@ clear_showcmd(void) { # ifdef FEAT_LINEBREAK char_u *saved_sbr = p_sbr; + char_u *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; # endif getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol); # ifdef FEAT_LINEBREAK p_sbr = saved_sbr; + curwin->w_p_sbr = saved_w_sbr; # endif sprintf((char *)showcmd_buf, "%ldx%ld", lines, (long)(rightcol - leftcol + 1)); @@ -2577,8 +2580,8 @@ nv_screengo(oparg_T *oap, int dir, long validate_virtcol(); virtcol = curwin->w_virtcol; #if defined(FEAT_LINEBREAK) - 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)); #endif if (virtcol > curwin->w_curswant diff --git a/src/ops.c b/src/ops.c --- a/src/ops.c +++ b/src/ops.c @@ -3636,9 +3636,11 @@ cursor_pos_info(dict_T *dict) { #ifdef FEAT_LINEBREAK char_u * saved_sbr = p_sbr; + char_u * 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; #endif oparg.is_VIsual = 1; oparg.block_mode = TRUE; @@ -3647,6 +3649,7 @@ cursor_pos_info(dict_T *dict) &oparg.start_vcol, &oparg.end_vcol); #ifdef FEAT_LINEBREAK p_sbr = saved_sbr; + curwin->w_p_sbr = saved_w_sbr; #endif if (curwin->w_curswant == MAXCOL) oparg.end_vcol = MAXCOL; diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -5167,6 +5167,11 @@ unset_global_local_option(char_u *name, clear_string_option(&buf->b_p_cm); break; #endif +#ifdef FEAT_LINEBREAK + case PV_SBR: + clear_string_option(&((win_T *)from)->w_p_sbr); + break; +#endif #ifdef FEAT_STL_OPT case PV_STL: clear_string_option(&((win_T *)from)->w_p_stl); @@ -5229,6 +5234,9 @@ get_varp_scope(struct vimoption *p, int #if defined(FEAT_CRYPT) case PV_CM: return (char_u *)&(curbuf->b_p_cm); #endif +#ifdef FEAT_LINEBREAK + case PV_SBR: return (char_u *)&(curwin->w_p_sbr); +#endif #ifdef FEAT_STL_OPT case PV_STL: return (char_u *)&(curwin->w_p_stl); #endif @@ -5315,6 +5323,10 @@ get_varp(struct vimoption *p) case PV_CM: return *curbuf->b_p_cm != NUL ? (char_u *)&(curbuf->b_p_cm) : p->var; #endif +#ifdef FEAT_LINEBREAK + case PV_SBR: return *curwin->w_p_sbr != NUL + ? (char_u *)&(curwin->w_p_sbr) : p->var; +#endif #ifdef FEAT_STL_OPT case PV_STL: return *curwin->w_p_stl != NUL ? (char_u *)&(curwin->w_p_stl) : p->var; @@ -5581,6 +5593,9 @@ copy_winopt(winopt_T *from, winopt_T *to to->wo_rl = from->wo_rl; to->wo_rlc = vim_strsave(from->wo_rlc); #endif +#ifdef FEAT_LINEBREAK + to->wo_sbr = vim_strsave(from->wo_sbr); +#endif #ifdef FEAT_STL_OPT to->wo_stl = vim_strsave(from->wo_stl); #endif @@ -5682,6 +5697,9 @@ check_winopt(winopt_T *wop UNUSED) #ifdef FEAT_RIGHTLEFT check_string_option(&wop->wo_rlc); #endif +#ifdef FEAT_LINEBREAK + check_string_option(&wop->wo_sbr); +#endif #ifdef FEAT_STL_OPT check_string_option(&wop->wo_stl); #endif @@ -5728,6 +5746,9 @@ clear_winopt(winopt_T *wop UNUSED) #ifdef FEAT_RIGHTLEFT clear_string_option(&wop->wo_rlc); #endif +#ifdef FEAT_LINEBREAK + clear_string_option(&wop->wo_sbr); +#endif #ifdef FEAT_STL_OPT clear_string_option(&wop->wo_stl); #endif @@ -7257,6 +7278,21 @@ get_bkc_value(buf_T *buf) return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags; } +#if defined(FEAT_LINEBREAK) || defined(PROTO) +/* + * Get the local or global value of 'showbreak'. + */ + char_u * +get_showbreak_value(win_T *win) +{ + 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; +} +#endif + #if defined(FEAT_SIGNS) || defined(PROTO) /* * Return TRUE when window "wp" has a column to draw signs in. diff --git a/src/option.h b/src/option.h --- a/src/option.h +++ b/src/option.h @@ -1271,6 +1271,9 @@ enum , WV_CULOPT , WV_CC #endif +#ifdef FEAT_LINEBREAK + , WV_SBR +#endif #ifdef FEAT_STL_OPT , WV_STL #endif diff --git a/src/optiondefs.h b/src/optiondefs.h --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -209,6 +209,9 @@ # define PV_CULOPT OPT_WIN(WV_CULOPT) # define PV_CC OPT_WIN(WV_CC) #endif +#ifdef FEAT_LINEBREAK +# define PV_SBR OPT_BOTH(OPT_WIN(WV_SBR)) +#endif #ifdef FEAT_STL_OPT # define PV_STL OPT_BOTH(OPT_WIN(WV_STL)) #endif @@ -2282,7 +2285,7 @@ static struct vimoption options[] = {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"showbreak", "sbr", P_STRING|P_VI_DEF|P_RALL, #ifdef FEAT_LINEBREAK - (char_u *)&p_sbr, PV_NONE, + (char_u *)&p_sbr, PV_SBR, #else (char_u *)NULL, PV_NONE, #endif diff --git a/src/optionstr.c b/src/optionstr.c --- a/src/optionstr.c +++ b/src/optionstr.c @@ -1440,12 +1440,12 @@ did_set_string_option( #ifdef FEAT_LINEBREAK // 'showbreak' - else if (varp == &p_sbr) + else if (gvarp == &p_sbr) { - for (s = p_sbr; *s; ) + for (s = *varp; *s; ) { if (ptr2cells(s) != 1) - errmsg = N_("E595: contains unprintable or wide character"); + errmsg = N_("E595: 'showbreak' contains unprintable or wide character"); MB_PTR_ADV(s); } } diff --git a/src/proto/option.pro b/src/proto/option.pro --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -80,6 +80,7 @@ long get_sidescrolloff_value(void); void find_mps_values(int *initc, int *findc, int *backwards, int switchit); int briopt_check(win_T *wp); unsigned int get_bkc_value(buf_T *buf); +char_u *get_showbreak_value(win_T *win); int signcolumn_on(win_T *wp); dict_T *get_winbuf_options(int bufopt); int fill_culopt_flags(char_u *val, win_T *wp); diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -254,6 +254,10 @@ typedef struct char_u *wo_cc; # define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn' #endif +#ifdef FEAT_LINEBREAK + char_u *wo_sbr; +#define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak' +#endif #ifdef FEAT_STL_OPT char_u *wo_stl; #define w_p_stl w_onebuf_opt.wo_stl // 'statusline' diff --git a/src/testdir/test_breakindent.vim b/src/testdir/test_breakindent.vim --- a/src/testdir/test_breakindent.vim +++ b/src/testdir/test_breakindent.vim @@ -62,7 +62,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", @@ -122,7 +123,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", @@ -132,6 +134,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() diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim --- a/src/testdir/test_highlight.vim +++ b/src/testdir/test_highlight.vim @@ -425,6 +425,7 @@ func Test_highlight_eol_with_cursorline_ 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') @@ -482,6 +483,7 @@ func Test_highlight_eol_with_cursorline_ call CloseWindow() set showbreak= + setlocal showbreak= exe hiCursorLine endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2281, +/**/ 2280, /**/ 2279,