Now the patch... sorry.
Index: runtime/doc/eval.txt
===================================================================
--- runtime/doc/eval.txt	(revision 288)
+++ runtime/doc/eval.txt	(working copy)
@@ -5262,8 +5262,8 @@
 keymap			Compiled with 'keymap' support.
 langmap			Compiled with 'langmap' support.
 libcall			Compiled with |libcall()| support.
-linebreak		Compiled with 'linebreak', 'breakat' and 'showbreak'
-			support.
+linebreak		Compiled with 'linebreak', 'breakat', 'showbreak' and
+			'breakindent' support.
 lispindent		Compiled with support for lisp indenting.
 listcmds		Compiled with commands for the buffer list |:files|
 			and the argument list |arglist|.
Index: runtime/doc/options.txt
===================================================================
--- runtime/doc/options.txt	(revision 288)
+++ runtime/doc/options.txt	(working copy)
@@ -1145,6 +1145,18 @@
 	break if 'linebreak' is on.  Only works for ASCII and also for 8-bit
 	characters when 'encoding' is an 8-bit encoding.
 
+	
+						*'breakindent'* *'bri'*
+'breakindent' 'bri'	boolean (default off)
+			local to window
+			{not in Vi}
+			{not available when compiled without the |+linebreak|
+			feature}
+	Every wrapped line will continue visually indented (same amount of
+	space as the beginning of that line), thus preserving horizontal blocks
+	of text.
+
+
 						*'browsedir'* *'bsdir'*
 'browsedir' 'bsdir'	string	(default: "last")
 			global
@@ -4227,12 +4239,13 @@
 			{not in Vi}
 			{not available when compiled without the  |+linebreak|
 			feature}
-	If on Vim will wrap long lines at a character in 'breakat' rather
+	If on, Vim will wrap long lines at a character in 'breakat' rather
 	than at the last character that fits on the screen.  Unlike
 	'wrapmargin' and 'textwidth', this does not insert <EOL>s in the file,
-	it only affects the way the file is displayed, not its contents.  The
-	value of 'showbreak' is used to put in front of wrapped lines.
-	This option is not used when the 'wrap' option is off or 'list' is on.
+	it only affects the way the file is displayed, not its contents.
+	If 'breakindent' is set, line is visually indented. Then, the value
+	of 'showbreak' is used to put in front of wrapped lines. This option
+	is not used when the 'wrap' option is off or 'list' is on.
 	Note that <Tab> characters after an <EOL> are mostly not displayed
 	with the right amount of white space.
 
Index: runtime/optwin.vim
===================================================================
--- runtime/optwin.vim	(revision 288)
+++ runtime/optwin.vim	(working copy)
@@ -329,6 +329,9 @@
 call append("$", "linebreak\twrap long lines at a character in 'breakat'")
 call append("$", "\t(local to window)")
 call <SID>BinOptionL("lbr")
+call append("$", "showbreak\tpreserve indentation in wrapped text")
+call append("$", "\t(local to window)")
+call <SID>BinOptionL("bri")
 call append("$", "breakat\twhich characters might cause a line break")
 call <SID>OptionG("brk", &brk)
 call append("$", "showbreak\tstring to put before wrapped screen lines")
Index: src/ex_cmds.c
===================================================================
--- src/ex_cmds.c	(revision 288)
+++ src/ex_cmds.c	(working copy)
@@ -260,7 +260,7 @@
 	;
     save = *last;
     *last = NUL;
-    len = linetabsize(line);		/* get line length */
+    len = linetabsize(line, curwin->w_cursor.lnum); /* get line length */
     if (has_tab != NULL)		/* check for embedded TAB */
 	*has_tab = (vim_strrchr(first, TAB) != NULL);
     *last = save;
Index: src/option.c
===================================================================
--- src/option.c	(revision 288)
+++ src/option.c	(working copy)
@@ -186,6 +186,9 @@
 #ifdef FEAT_ARABIC
 # define PV_ARAB	OPT_WIN(WV_ARAB)
 #endif
+#ifdef FEAT_LINEBREAK
+# define PV_BRI		OPT_WIN(WV_BRI)
+#endif
 #ifdef FEAT_DIFF
 # define PV_DIFF	OPT_WIN(WV_DIFF)
 #endif
@@ -627,6 +630,13 @@
 			    {(char_u *)0L, (char_u *)0L}
 #endif
 			    },
+    {"breakindent",   "bri",  P_BOOL|P_VI_DEF|P_VIM|P_RWIN,
+#ifdef FEAT_LINEBREAK
+			    (char_u *)VAR_WIN, PV_BRI,
+#else
+			    (char_u *)NULL, PV_NONE,
+#endif
+			    {(char_u *)FALSE, (char_u *)0L}},
     {"browsedir",   "bsdir",P_STRING|P_VI_DEF,
 #ifdef FEAT_BROWSE
 			    (char_u *)&p_bsdir, PV_NONE,
@@ -9012,6 +9022,7 @@
 	case PV_WRAP:	return (char_u *)&(curwin->w_p_wrap);
 #ifdef FEAT_LINEBREAK
 	case PV_LBR:	return (char_u *)&(curwin->w_p_lbr);
+	case PV_BRI:	return (char_u *)&(curwin->w_p_bri);
 #endif
 #ifdef FEAT_SCROLLBIND
 	case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
@@ -9190,6 +9201,7 @@
     to->wo_wrap = from->wo_wrap;
 #ifdef FEAT_LINEBREAK
     to->wo_lbr = from->wo_lbr;
+    to->wo_bri = from->wo_bri;
 #endif
 #ifdef FEAT_SCROLLBIND
     to->wo_scb = from->wo_scb;
Index: src/option.h
===================================================================
--- src/option.h	(revision 288)
+++ src/option.h	(working copy)
@@ -1007,6 +1007,9 @@
 #ifdef FEAT_ARABIC
     , WV_ARAB
 #endif
+#ifdef FEAT_LINEBREAK
+    , WV_BRI
+#endif
 #ifdef FEAT_DIFF
     , WV_DIFF
 #endif
Index: src/proto/charset.pro
===================================================================
--- src/proto/charset.pro	(revision 288)
+++ src/proto/charset.pro	(working copy)
@@ -14,8 +14,8 @@
 int vim_strsize __ARGS((char_u *s));
 int vim_strnsize __ARGS((char_u *s, int len));
 int chartabsize __ARGS((char_u *p, colnr_T col));
-int linetabsize __ARGS((char_u *s));
-int win_linetabsize __ARGS((win_T *wp, char_u *p, colnr_T len));
+int linetabsize __ARGS((char_u *s, linenr_T lnum));
+int win_linetabsize __ARGS((win_T *wp, char_u *p, colnr_T len, linenr_T lnum));
 int vim_isIDc __ARGS((int c));
 int vim_iswordc __ARGS((int c));
 int vim_iswordp __ARGS((char_u *p));
@@ -23,9 +23,9 @@
 int vim_isfilec __ARGS((int c));
 int vim_isprintc __ARGS((int c));
 int vim_isprintc_strict __ARGS((int c));
-int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col));
-int lbr_chartabsize_adv __ARGS((char_u **s, colnr_T col));
-int win_lbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp));
+int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col, linenr_T lnum));
+int lbr_chartabsize_adv __ARGS((char_u **s, colnr_T col, linenr_T lnum));
+int win_lbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp, linenr_T lnum));
 int in_win_border __ARGS((win_T *wp, colnr_T vcol));
 void getvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end));
 colnr_T getvcol_nolist __ARGS((pos_T *posp));
Index: src/proto/misc1.pro
===================================================================
--- src/proto/misc1.pro	(revision 288)
+++ src/proto/misc1.pro	(working copy)
@@ -5,6 +5,7 @@
 int get_indent_str __ARGS((char_u *ptr, int ts));
 int set_indent __ARGS((int size, int flags));
 int get_number_indent __ARGS((linenr_T lnum));
+int get_breakindent_lnum __ARGS((linenr_T lnum));
 int open_line __ARGS((int dir, int flags, int old_indent));
 int get_leader_len __ARGS((char_u *line, char_u **flags, int backward));
 int plines __ARGS((linenr_T lnum));
Index: src/regexp.c
===================================================================
--- src/regexp.c	(revision 288)
+++ src/regexp.c	(working copy)
@@ -3923,7 +3923,7 @@
 		    if (top.col == MAXCOL || bot.col == MAXCOL)
 			end = MAXCOL;
 		    cols = win_linetabsize(wp,
-				      regline, (colnr_T)(reginput - regline));
+				      regline, (colnr_T)(reginput - regline), reglnum + reg_firstlnum);
 		    if (cols < start || cols > end - (*p_sel == 'e'))
 			status = RA_NOMATCH;
 		}
@@ -3947,7 +3947,7 @@
 	  case RE_VCOL:
 	    if (!re_num_cmp((long_u)win_linetabsize(
 			    reg_win == NULL ? curwin : reg_win,
-			    regline, (colnr_T)(reginput - regline)) + 1, scan))
+			    regline, (colnr_T)(reginput - regline), reglnum + reg_firstlnum ) + 1, scan))
 		status = RA_NOMATCH;
 	    break;
 
Index: src/structs.h
===================================================================
--- src/structs.h	(revision 288)
+++ src/structs.h	(working copy)
@@ -133,6 +133,10 @@
     int		wo_arab;
 # define w_p_arab w_onebuf_opt.wo_arab	/* 'arabic' */
 #endif
+#ifdef FEAT_LINEBREAK
+    int		wo_bri;
+# define w_p_bri w_onebuf_opt.wo_bri	/* 'breakindent' */
+#endif
 #ifdef FEAT_DIFF
     int		wo_diff;
 # define w_p_diff w_onebuf_opt.wo_diff	/* 'diff' */
Index: src/ui.c
===================================================================
--- src/ui.c	(revision 288)
+++ src/ui.c	(working copy)
@@ -3002,7 +3002,7 @@
     while (count <= vcol && *ptr != NUL)
     {
 	++col;
-	count += win_lbr_chartabsize(wp, ptr, count, NULL);
+	count += win_lbr_chartabsize(wp, ptr, count, NULL, lnum);
 	mb_ptr_adv(ptr);
     }
     return col;
Index: src/getchar.c
===================================================================
--- src/getchar.c	(revision 288)
+++ src/getchar.c	(working copy)
@@ -2511,7 +2511,7 @@
 				    if (!vim_iswhite(ptr[col]))
 					curwin->w_wcol = vcol;
 				    vcol += lbr_chartabsize(ptr + col,
-							       (colnr_T)vcol);
+							       (colnr_T)vcol, curwin->w_cursor.lnum);
 #ifdef FEAT_MBYTE
 				    if (has_mbyte)
 					col += (*mb_ptr2len)(ptr + col);
Index: src/misc1.c
===================================================================
--- src/misc1.c	(revision 288)
+++ src/misc1.c	(working copy)
@@ -415,6 +415,41 @@
     return (int)col;
 }
 
+/* 
+ * Return appropriate space number for breakindent, taking influencing 
+ * parameters into account
+ * If lnum==0, current line is taken into account, current line otherwise
+ */
+    int
+get_breakindent_lnum (lnum)
+    linenr_T	lnum;
+{
+    int bri;
+    const int bri_min = 20;
+    /* window width minus barren space, i.e. what rests for text */
+    const int eff_wwidth = W_WIDTH(curwin)
+	- (curwin->w_p_nu && !vim_strchr(p_cpo,CPO_NUMCOL)?8:0);
+
+    if (lnum)
+	bri = get_indent_lnum(lnum);
+    else
+	bri = get_indent();
+
+    /* if numbering and 'c' in 'cpoptions', cancel it out effectively */
+    /* (this could be replaced by an equivalent call to win_col_off2()) */
+    if (curwin->w_p_nu && vim_strchr(p_cpo, CPO_NUMCOL))
+	bri += 8;
+    
+    /* always leave at least bri_min characters on the left,
+     * if text width is sufficient */
+    if (bri > eff_wwidth - bri_min)
+	bri = eff_wwidth - bri_min < 0 ? 0 : eff_wwidth - bri_min;
+
+    return bri;
+}
+
+
+
 #if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
 
 static int cin_is_cinword __ARGS((char_u *line));
@@ -1687,7 +1722,7 @@
     s = ml_get_buf(wp->w_buffer, lnum, FALSE);
     if (*s == NUL)		/* empty line */
 	return 1;
-    col = win_linetabsize(wp, s, (colnr_T)MAXCOL);
+    col = win_linetabsize(wp, s, (colnr_T)MAXCOL, lnum);
 
     /*
      * If list mode is on, then the '$' at the end of the line may take up one
@@ -1743,7 +1778,7 @@
     col = 0;
     while (*s != NUL && --column >= 0)
     {
-	col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL);
+	col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL, lnum);
 	mb_ptr_adv(s);
     }
 
@@ -1755,7 +1790,7 @@
      * 'ts') -- webb.
      */
     if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1))
-	col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL) - 1;
+	col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL, lnum) - 1;
 
     /*
      * Add column offset for 'number', 'foldcolumn', etc.
@@ -8129,7 +8164,7 @@
 		amount = 0;
 		while (*that && col)
 		{
-		    amount += lbr_chartabsize_adv(&that, (colnr_T)amount);
+		    amount += lbr_chartabsize_adv(&that, (colnr_T)amount, pos->lnum);
 		    col--;
 		}
 
@@ -8152,7 +8187,7 @@
 
 		    while (vim_iswhite(*that))
 		    {
-			amount += lbr_chartabsize(that, (colnr_T)amount);
+			amount += lbr_chartabsize(that, (colnr_T)amount, pos->lnum);
 			++that;
 		    }
 
@@ -8191,14 +8226,14 @@
 				    --parencount;
 				if (*that == '\\' && *(that+1) != NUL)
 				    amount += lbr_chartabsize_adv(&that,
-							     (colnr_T)amount);
+							     (colnr_T)amount, pos->lnum);
 				amount += lbr_chartabsize_adv(&that,
-							     (colnr_T)amount);
+							     (colnr_T)amount, pos->lnum);
 			    }
 			}
 			while (vim_iswhite(*that))
 			{
-			    amount += lbr_chartabsize(that, (colnr_T)amount);
+			    amount += lbr_chartabsize(that, (colnr_T)amount, pos->lnum);
 			    that++;
 			}
 			if (!*that || *that == ';')
Index: src/edit.c
===================================================================
--- src/edit.c	(revision 288)
+++ src/edit.c	(working copy)
@@ -384,7 +384,7 @@
 	if (startln)
 	    Insstart.col = 0;
     }
-    Insstart_textlen = linetabsize(ml_get_curline());
+    Insstart_textlen = linetabsize(ml_get_curline(), Insstart.lnum);
     Insstart_blank_vcol = MAXCOL;
     if (!did_ai)
 	ai_col = 0;
@@ -1774,7 +1774,7 @@
 	    else
 #endif
 		++new_cursor_col;
-	    vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_T)vcol);
+	    vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_T)vcol, curwin->w_cursor.lnum);
 	}
 	vcol = last_vcol;
 
@@ -6121,7 +6121,7 @@
 	    ins_need_undo = FALSE;
 	}
 	Insstart = curwin->w_cursor;	/* new insertion starts here */
-	Insstart_textlen = linetabsize(ml_get_curline());
+	Insstart_textlen = linetabsize(ml_get_curline(),curwin->w_cursor.lnum);
 	ai_col = 0;
 #ifdef FEAT_VREPLACE
 	if (State & VREPLACE_FLAG)
@@ -6472,9 +6472,10 @@
 	for (;;)
 	{
 	    coladvance(v - width);
-	    /* getviscol() is slow, skip it when 'showbreak' is empty and
-	     * there are no multi-byte characters */
-	    if ((*p_sbr == NUL
+	    /* 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
 #  ifdef FEAT_MBYTE
 			&& !has_mbyte
 #  endif
@@ -9058,11 +9059,11 @@
 	getvcol(curwin, &fpos, &vcol, NULL, NULL);
 	getvcol(curwin, cursor, &want_vcol, NULL, NULL);
 
-	/* Use as many TABs as possible.  Beware of 'showbreak' and
+	/* Use as many TABs as possible.  Beware of 'breakindent', 'showbreak' and
 	 * 'linebreak' adding extra virtual columns. */
 	while (vim_iswhite(*ptr))
 	{
-	    i = lbr_chartabsize((char_u *)"\t", vcol);
+	    i = lbr_chartabsize((char_u *)"\t", vcol, cursor->lnum);
 	    if (vcol + i > want_vcol)
 		break;
 	    if (*ptr != TAB)
@@ -9088,7 +9089,7 @@
 	    /* Skip over the spaces we need. */
 	    while (vcol < want_vcol && *ptr == ' ')
 	    {
-		vcol += lbr_chartabsize(ptr, vcol);
+		vcol += lbr_chartabsize(ptr, vcol, cursor->lnum);
 		++ptr;
 		++repl_off;
 	    }
@@ -9336,7 +9337,7 @@
     while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL)
     {
 	prev_ptr = ptr;
-	temp += lbr_chartabsize_adv(&ptr, (colnr_T)temp);
+	temp += lbr_chartabsize_adv(&ptr, (colnr_T)temp, lnum);
     }
     if ((colnr_T)temp > curwin->w_virtcol)
 	ptr = prev_ptr;
Index: src/normal.c
===================================================================
--- src/normal.c	(revision 288)
+++ src/normal.c	(working copy)
@@ -4261,7 +4261,7 @@
     int		dir;
     long	dist;
 {
-    int		linelen = linetabsize(ml_get_curline());
+    int		linelen = linetabsize(ml_get_curline(), curwin->w_cursor.lnum);
     int		retval = OK;
     int		atend = FALSE;
     int		n;
@@ -4334,7 +4334,7 @@
 		    (void)hasFolding(curwin->w_cursor.lnum,
 						&curwin->w_cursor.lnum, NULL);
 #endif
-		linelen = linetabsize(ml_get_curline());
+		linelen = linetabsize(ml_get_curline(), curwin->w_cursor.lnum);
 		if (linelen > width1)
 		    curwin->w_curswant += (((linelen - width1 - 1) / width2)
 								+ 1) * width2;
Index: src/gui_beval.c
===================================================================
--- src/gui_beval.c	(revision 288)
+++ src/gui_beval.c	(working copy)
@@ -337,7 +337,7 @@
 	{
 	    /* Not past end of the file. */
 	    lbuf = ml_get_buf(wp->w_buffer, lnum, FALSE);
-	    if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL))
+	    if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL, lnum))
 	    {
 		/* Not past end of line. */
 		if (getword)
Index: src/charset.c
===================================================================
--- src/charset.c	(revision 288)
+++ src/charset.c	(working copy)
@@ -830,13 +830,14 @@
  * taking into account the size of a tab
  */
     int
-linetabsize(s)
+linetabsize(s, lnum)
     char_u	*s;
+    linenr_T	lnum;
 {
     colnr_T	col = 0;
 
     while (*s != NUL)
-	col += lbr_chartabsize_adv(&s, col);
+	col += lbr_chartabsize_adv(&s, col, lnum);
     return (int)col;
 }
 
@@ -844,16 +845,17 @@
  * Like linetabsize(), but for a given window instead of the current one.
  */
     int
-win_linetabsize(wp, p, len)
+win_linetabsize(wp, p, len, lnum)
     win_T	*wp;
     char_u	*p;
     colnr_T	len;
+    linenr_T	lnum;
 {
     colnr_T	col = 0;
     char_u	*s;
 
     for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s))
-	col += win_lbr_chartabsize(wp, s, col, NULL);
+	col += win_lbr_chartabsize(wp, s, col, NULL, lnum);
     return (int)col;
 }
 
@@ -965,12 +967,13 @@
  * like chartabsize(), but also check for line breaks on the screen
  */
     int
-lbr_chartabsize(s, col)
+lbr_chartabsize(s, col, lnum)
     unsigned char	*s;
     colnr_T		col;
+    linenr_T		lnum;
 {
 #ifdef FEAT_LINEBREAK
-    if (!curwin->w_p_lbr && *p_sbr == NUL)
+    if (!curwin->w_p_lbr && *p_sbr == NUL && !curwin->w_p_bri)
     {
 #endif
 #ifdef FEAT_MBYTE
@@ -980,7 +983,7 @@
 	RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
 #ifdef FEAT_LINEBREAK
     }
-    return win_lbr_chartabsize(curwin, s, col, NULL);
+    return win_lbr_chartabsize(curwin, s, col, NULL, lnum);
 #endif
 }
 
@@ -988,13 +991,14 @@
  * Call lbr_chartabsize() and advance the pointer.
  */
     int
-lbr_chartabsize_adv(s, col)
+lbr_chartabsize_adv(s, col, lnum)
     char_u	**s;
     colnr_T	col;
+    linenr_T	lnum;
 {
     int		retval;
 
-    retval = lbr_chartabsize(*s, col);
+    retval = lbr_chartabsize(*s, col, lnum);
     mb_ptr_adv(*s);
     return retval;
 }
@@ -1005,14 +1009,18 @@
  * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
  * string at start of line.  Warning: *headp is only set if it's a non-zero
  * value, init to 0 before calling.
+ *
+ * linenr argument needed if in visual highlighting and breakindent=on, then
+ * the line calculated is not current; if 0, normal functionality is preserved.
  */
 /*ARGSUSED*/
     int
-win_lbr_chartabsize(wp, s, col, headp)
+win_lbr_chartabsize(wp, s, col, headp, lnum)
     win_T	*wp;
     char_u	*s;
     colnr_T	col;
     int		*headp;
+    linenr_T	lnum;
 {
 #ifdef FEAT_LINEBREAK
     int		c;
@@ -1031,9 +1039,9 @@
     int		n;
 
     /*
-     * No 'linebreak' and 'showbreak': return quickly.
+     * No 'linebreak' and 'showbreak' and 'breakindent': return quickly.
      */
-    if (!wp->w_p_lbr && *p_sbr == NUL)
+    if (!wp->w_p_lbr && !wp->w_p_bri && *p_sbr == NUL)
 #endif
     {
 #ifdef FEAT_MBYTE
@@ -1108,11 +1116,12 @@
 # endif
 
     /*
-     * May have to add something for 'showbreak' string at start of line
+     * May have to add something for 'breakindent' and/or 'showbreak'
+     * string at start of line.
      * Set *headp to the size of what we add.
      */
     added = 0;
-    if (*p_sbr != NUL && wp->w_p_wrap && col != 0)
+    if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && col != 0)
     {
 	numberextra = win_col_off(wp);
 	col += numberextra + mb_added;
@@ -1125,7 +1134,12 @@
 	}
 	if (col == 0 || col + size > (colnr_T)W_WIDTH(wp))
 	{
-	    added = vim_strsize(p_sbr);
+	    added = 0;
+	    if (*p_sbr != NUL)
+		added += vim_strsize(p_sbr);
+	    if (wp->w_p_bri)
+		added += get_breakindent_lnum(lnum);
+
 	    if (tab_corr)
 		size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
 	    else
@@ -1228,12 +1242,13 @@
 
     /*
      * This function is used very often, do some speed optimizations.
-     * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
+     * When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set
+     * use a simple loop.
      * Also use this when 'list' is set but tabs take their normal size.
      */
     if ((!wp->w_p_list || lcs_tab1 != NUL)
 #ifdef FEAT_LINEBREAK
-	    && !wp->w_p_lbr && *p_sbr == NUL
+	    && !wp->w_p_lbr && *p_sbr == NUL && !wp->w_p_bri
 #endif
        )
     {
@@ -1294,7 +1309,7 @@
 	{
 	    /* A tab gets expanded, depending on the current column */
 	    head = 0;
-	    incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
+	    incr = win_lbr_chartabsize(wp, ptr, vcol, &head, pos->lnum);
 	    /* make sure we don't go past the end of the line */
 	    if (*ptr == NUL)
 	    {
Index: src/misc2.c
===================================================================
--- src/misc2.c	(revision 288)
+++ src/misc2.c	(working copy)
@@ -170,7 +170,7 @@
 #ifdef FEAT_VIRTUALEDIT
 	    if ((addspaces || finetune) && !VIsual_active)
 	    {
-		curwin->w_curswant = linetabsize(line) + one_more;
+		curwin->w_curswant = linetabsize(line, pos->lnum) + one_more;
 		if (curwin->w_curswant > 0)
 		    --curwin->w_curswant;
 	    }
@@ -188,7 +188,7 @@
 # endif
 		&& wcol >= (colnr_T)width)
 	{
-	    csize = linetabsize(line);
+	    csize = linetabsize(line, pos->lnum);
 	    if (csize > 0)
 		csize--;
 
@@ -210,10 +210,10 @@
 	{
 	    /* Count a tab for what it's worth (if list mode not on) */
 #ifdef FEAT_LINEBREAK
-	    csize = win_lbr_chartabsize(curwin, ptr, col, &head);
+	    csize = win_lbr_chartabsize(curwin, ptr, col, &head, pos->lnum);
 	    mb_ptr_adv(ptr);
 #else
-	    csize = lbr_chartabsize_adv(&ptr, col);
+	    csize = lbr_chartabsize_adv(&ptr, col, pos->lnum);
 #endif
 	    col += csize;
 	}
Index: src/screen.c
===================================================================
--- src/screen.c	(revision 288)
+++ src/screen.c	(working copy)
@@ -2657,10 +2657,15 @@
 # define WL_SIGN	WL_FOLD		/* column for signs */
 #endif
 #define WL_NR		WL_SIGN + 1	/* line number */
+#ifdef FEAT_LINEBREAK
+# define WL_BRI		WL_NR + 1	/* 'breakindent' */
+#else
+# define WL_BRI		WL_NR
+#endif
 #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
-# define WL_SBR		WL_NR + 1	/* 'showbreak' or 'diff' */
+# define WL_SBR		WL_BRI + 1	/* 'showbreak' or 'diff' */
 #else
-# define WL_SBR		WL_NR
+# define WL_SBR		WL_BRI
 #endif
 #define WL_LINE		WL_SBR + 1	/* text in the line */
     int		draw_state = WL_START;	/* what to draw next */
@@ -2968,7 +2973,7 @@
 #endif
 	while (vcol < v && *ptr != NUL)
 	{
-	    c = win_lbr_chartabsize(wp, ptr, (colnr_T)vcol, NULL);
+	    c = win_lbr_chartabsize(wp, ptr, (colnr_T)vcol, NULL, lnum);
 	    vcol += c;
 #ifdef FEAT_MBYTE
 	    prev_ptr = ptr;
@@ -3288,6 +3293,30 @@
 		}
 	    }
 
+#ifdef FEAT_LINEBREAK 
+	    /* draw 'breakindent': indent wrapped text accordingly */
+	    if (draw_state == WL_BRI -1 && n_extra == 0){
+		draw_state = WL_BRI;
+# ifdef FEAT_DIFF
+		/* FIXME: handle (filler_todo > 0): or modify showbreak so that ---- lines are shorter by the amount needed? */
+# endif
+		if (wp->w_p_bri && row != startrow){ /* FIXME: what is startrow? Don't we need it as well?? */
+		    p_extra = NUL;
+		    c_extra = ' ';
+		    n_extra = get_breakindent_lnum(lnum);
+		    char_attr = 0; /* was: hl_attr(HLF_AT); */
+		    /* FIXME: why do we need to adjust vcol if showbreak does not?? */
+		    vcol += n_extra;
+		    /* FIXME: is this relevant here? copied shamelessly from showbreak */
+		    /* Correct end of highlighted area for 'breakindent',
+		     * required when 'linebreak' is also set. */
+		    if (tocol == vcol)
+			tocol += n_extra;
+		}
+	    }
+#endif
+	    
+
 #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
 	    if (draw_state == WL_SBR - 1 && n_extra == 0)
 	    {
@@ -3946,7 +3975,7 @@
 # ifdef FEAT_MBYTE
 				has_mbyte ? mb_l :
 # endif
-				1), (colnr_T)vcol, NULL) - 1;
+				1), (colnr_T)vcol, NULL, lnum) - 1;
 		    c_extra = ' ';
 		    if (vim_iswhite(c))
 			c = ' ';
Index: src/ops.c
===================================================================
--- src/ops.c	(revision 288)
+++ src/ops.c	(working copy)
@@ -428,7 +428,7 @@
 	}
 	for ( ; vim_iswhite(*bd.textstart); )
 	{
-	    incr = lbr_chartabsize_adv(&bd.textstart, (colnr_T)(bd.start_vcol));
+	    incr = lbr_chartabsize_adv(&bd.textstart, (colnr_T)(bd.start_vcol), curwin->w_cursor.lnum);
 	    total += incr;
 	    bd.start_vcol += incr;
 	}
@@ -460,7 +460,7 @@
 	for (midp = oldp + bd.textcol;
 	      vcol < (oap->start_vcol + total) && vim_iswhite(*midp); )
 	{
-	    incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol);
+	    incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol, curwin->w_cursor.lnum);
 	    vcol += incr;
 	}
 	/* internal is the block-internal ws replacing a split TAB */
@@ -477,7 +477,7 @@
 	    if (!curbuf->b_p_et)
 	    {
 		for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; )
-		    col += lbr_chartabsize_adv(&ptr, (colnr_T)col);
+		    col += lbr_chartabsize_adv(&ptr, (colnr_T)col, curwin->w_cursor.lnum);
 
 		/* col+1 now equals the start col of the first char of the
 		 * block (may be < oap.start_vcol if we're splitting a TAB) */
@@ -3445,7 +3445,7 @@
 	    for (ptr = oldp; vcol < col && *ptr; )
 	    {
 		/* Count a tab for what it's worth (if list mode not on) */
-		incr = lbr_chartabsize_adv(&ptr, (colnr_T)vcol);
+		incr = lbr_chartabsize_adv(&ptr, (colnr_T)vcol, lnum);
 		vcol += incr;
 	    }
 	    bd.textcol = (colnr_T)(ptr - oldp);
@@ -3479,7 +3479,7 @@
 	    /* calculate number of spaces required to fill right side of block*/
 	    spaces = y_width + 1;
 	    for (j = 0; j < yanklen; j++)
-		spaces -= lbr_chartabsize(&y_array[i][j], 0);
+		spaces -= lbr_chartabsize(&y_array[i][j], 0, lnum);
 	    if (spaces < 0)
 		spaces = 0;
 
@@ -4837,7 +4837,7 @@
     while (bdp->start_vcol < oap->start_vcol && *pstart)
     {
 	/* Count a tab for what it's worth (if list mode not on) */
-	incr = lbr_chartabsize(pstart, (colnr_T)bdp->start_vcol);
+	incr = lbr_chartabsize(pstart, (colnr_T)bdp->start_vcol, lnum);
 	bdp->start_vcol += incr;
 #ifdef FEAT_VISUALEXTRA
 	if (vim_iswhite(*pstart))
@@ -4906,7 +4906,7 @@
 	    {
 		/* Count a tab for what it's worth (if list mode not on) */
 		prev_pend = pend;
-		incr = lbr_chartabsize_adv(&pend, (colnr_T)bdp->end_vcol);
+		incr = lbr_chartabsize_adv(&pend, (colnr_T)bdp->end_vcol, lnum);
 		bdp->end_vcol += incr;
 	    }
 	    if (bdp->end_vcol <= oap->end_vcol
@@ -6344,7 +6344,7 @@
 	    validate_virtcol();
 	    col_print(buf1, (int)curwin->w_cursor.col + 1,
 		    (int)curwin->w_virtcol + 1);
-	    col_print(buf2, (int)STRLEN(p), linetabsize(p));
+	    col_print(buf2, (int)STRLEN(p), linetabsize(p, curwin->w_cursor.lnum));
 
 	    if (char_count_cursor == byte_count_cursor
 		    && char_count == byte_count)

Reply via email to