changeset 18574:8b0114ffde2b v8.1.2281

patch 8.1.2281: 'showbreak' cannot be set for one window Commit: https://github.com/vim/vim/commit/ee85702c10495041791f728e977b86005c4496e8 Author: Bram Moolenaar <Bram@vim.org> 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.
author Bram Moolenaar <Bram@vim.org>
date Sat, 09 Nov 2019 23:30:03 +0100
parents f18a4ae518f1
children a5f35d5b839f
files runtime/doc/options.txt src/charset.c src/drawline.c src/edit.c src/move.c src/normal.c src/ops.c src/option.c src/option.h src/optiondefs.h src/optionstr.c src/proto/option.pro src/structs.h src/testdir/test_breakindent.vim src/testdir/test_highlight.vim src/version.c
diffstat 16 files changed, 104 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- 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|)
--- 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
        )
     {
--- 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
--- 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;
--- 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
 	}
--- 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
--- 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;
--- 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.
--- 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
--- 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
--- 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);
 	}
     }
--- 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);
--- 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'
--- 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()
--- 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
 
--- 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,