I pretty much agree; one of the main reasons why I always build Vim from source rather than using my OS's official Vim package is so that I can apply the breakindent patch. It's quite useful.
In fact, I actually created the 7.3.285 version of the patch that you downloaded from Eli Carter's website. There was a change made in Vim's official patch 285 that broke the breakindent functionality, and I didn't want to leave it by the wayside, so I made an updated version and Eli kindly hosted it for me. I suspect that the main reason it hasn't been included yet is simply that no one has really brought it up in a while. I think the patch is quite mature and is very much ready for inclusion in the official distribution of Vim. And it's not going to even cause any unexpected behavior for users who don't want it, since it's optional functionality that is turned off by default. I've attached the current version of the patch to this message to make it easier for others to discuss and review without having to grab it from the Web. I'm willing to fix it up if Bram or anyone else sees a problem with the way it's implemented.
diff -r 7b50afd31037 runtime/doc/eval.txt
--- a/runtime/doc/eval.txt Fri Aug 19 22:29:02 2011 +0200
+++ b/runtime/doc/eval.txt Tue Aug 23 10:20:21 2011 -0400
@@ -6208,8 +6208,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|.
diff -r 7b50afd31037 runtime/doc/options.txt
--- a/runtime/doc/options.txt Fri Aug 19 22:29:02 2011 +0200
+++ b/runtime/doc/options.txt Tue Aug 23 10:20:21 2011 -0400
@@ -1184,6 +1184,39 @@
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.
+
+ *'breakindentmin'* *'brimin'*
+'breakindentmin' 'brimin' number (default 20)
+ local to window
+ {not in Vi}
+ {not available when compiled without the |+linebreak|
+ feature}
+ Minimum text width that will be kept after applying 'breakindent',
+ even if the resulting text should normally be narrower. This prevents
+ text indented almost to the right window border oocupying lot of
+ vertical space when broken.
+
+ *'breakindentshift'*
*'brishift'*
+'breakindentshift' 'brishift' number (default 20)
+ local to window
+ {not in Vi}
+ {not available when compiled without the |+linebreak|
+ feature}
+ After applying 'breakindent', wrapped line beginning will be shift by
+ given number of characters. It permits dynamic French paragraph
+ indentation (negative) or emphasizing the line continuation
+ (positive).
+
*'browsedir'* *'bsdir'*
'browsedir' 'bsdir' string (default: "last")
global
@@ -4483,12 +4516,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.
diff -r 7b50afd31037 runtime/doc/tags
--- a/runtime/doc/tags Fri Aug 19 22:29:02 2011 +0200
+++ b/runtime/doc/tags Tue Aug 23 10:20:21 2011 -0400
@@ -90,6 +90,12 @@
'bl' options.txt /*'bl'*
'bomb' options.txt /*'bomb'*
'breakat' options.txt /*'breakat'*
+'breakindent' options.txt /*'breakindent'*
+'breakindentmin' options.txt /*'breakindentmin'*
+'breakindentshift' options.txt /*'breakindentshift'*
+'bri' options.txt /*'bri'*
+'brimin' options.txt /*'brimin'*
+'brishift' options.txt /*'brishift'*
'brk' options.txt /*'brk'*
'browsedir' options.txt /*'browsedir'*
'bs' options.txt /*'bs'*
diff -r 7b50afd31037 runtime/optwin.vim
--- a/runtime/optwin.vim Fri Aug 19 22:29:02 2011 +0200
+++ b/runtime/optwin.vim Tue Aug 23 10:20:21 2011 -0400
@@ -322,6 +322,15 @@
call append("$", "linebreak\twrap long lines at a character in 'breakat'")
call append("$", "\t(local to window)")
call <SID>BinOptionL("lbr")
+call append("$", "breakindent\tpreserve indentation in wrapped text")
+call append("$", "\t(local to window)")
+call <SID>BinOptionL("bri")
+call append("$", "breakindentmin\tminimum text width after indent in
'breakindent'")
+call append("$", "\t(local to window)")
+call <SID>OptionL("brimin")
+call append("$", "breakindentshift\tshift beginning of 'breakindent'ed line by
this number of characters (negative left)")
+call append("$", "\t(local to window)")
+call <SID>OptionL("brishift")
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")
diff -r 7b50afd31037 src/charset.c
--- a/src/charset.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/charset.c Tue Aug 23 10:20:21 2011 -0400
@@ -846,24 +846,26 @@
* taking into account the size of a tab.
*/
int
-linetabsize(s)
+linetabsize(s, lnum)
char_u *s;
+ linenr_T lnum;
{
- return linetabsize_col(0, s);
+ return linetabsize_col(0, s, lnum);
}
/*
* Like linetabsize(), but starting at column "startcol".
*/
int
-linetabsize_col(startcol, s)
+linetabsize_col(startcol, s, lnum)
int startcol;
char_u *s;
+ linenr_T lnum;
{
colnr_T col = startcol;
while (*s != NUL)
- col += lbr_chartabsize_adv(&s, col);
+ col += lbr_chartabsize_adv(&s, col, lnum);
return (int)col;
}
@@ -871,16 +873,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;
}
@@ -1009,12 +1012,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
@@ -1024,7 +1028,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
}
@@ -1032,13 +1036,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;
}
@@ -1049,13 +1054,17 @@
* 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.
*/
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 UNUSED;
+ linenr_T lnum;
{
#ifdef FEAT_LINEBREAK
int c;
@@ -1074,9 +1083,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
@@ -1151,11 +1160,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;
@@ -1168,7 +1178,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_win(wp,lnum);
+
if (tab_corr)
size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
else
@@ -1276,12 +1291,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
)
{
@@ -1343,7 +1359,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)
{
diff -r 7b50afd31037 src/edit.c
--- a/src/edit.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/edit.c Tue Aug 23 10:20:21 2011 -0400
@@ -398,7 +398,7 @@
if (startln)
Insstart.col = 0;
}
- Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
+ Insstart_textlen = (colnr_T)linetabsize(ml_get_curline(), Insstart.lnum);
Insstart_blank_vcol = MAXCOL;
if (!did_ai)
ai_col = 0;
@@ -1897,7 +1897,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;
@@ -6500,7 +6500,7 @@
ins_need_undo = FALSE;
}
Insstart = curwin->w_cursor; /* new insertion starts here */
- Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
+ Insstart_textlen = (colnr_T)linetabsize(ml_get_curline(),
curwin->w_cursor.lnum);
ai_col = 0;
#ifdef FEAT_VREPLACE
if (State & VREPLACE_FLAG)
@@ -6859,9 +6859,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
@@ -9497,11 +9498,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)
@@ -9527,7 +9528,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;
}
@@ -9783,7 +9784,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;
diff -r 7b50afd31037 src/eval.c
--- a/src/eval.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/eval.c Tue Aug 23 10:20:21 2011 -0400
@@ -16990,8 +16990,11 @@
if (argvars[1].v_type != VAR_UNKNOWN)
col = get_tv_number(&argvars[1]);
-
- rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col);
+ /*
+ * FIXME: passing 0 as 3rd argument to linetabsize_col, instead of real
line number;
+ * (can we get it from here somehow?); might give incorrect result with
breakindent!
+ */
+ rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s, 0) - col);
}
/*
diff -r 7b50afd31037 src/ex_cmds.c
--- a/src/ex_cmds.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/ex_cmds.c Tue Aug 23 10:20:21 2011 -0400
@@ -262,7 +262,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;
diff -r 7b50afd31037 src/getchar.c
--- a/src/getchar.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/getchar.c Tue Aug 23 10:20:21 2011 -0400
@@ -2609,7 +2609,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);
diff -r 7b50afd31037 src/gui_beval.c
--- a/src/gui_beval.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/gui_beval.c Tue Aug 23 10:20:21 2011 -0400
@@ -335,7 +335,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)
diff -r 7b50afd31037 src/misc1.c
--- a/src/misc1.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/misc1.c Tue Aug 23 10:20:21 2011 -0400
@@ -451,6 +451,44 @@
return (int)col;
}
+#ifdef FEAT_LINEBREAK
+/*
+ * Return appropriate space number for breakindent, taking influencing
+ * parameters into account. Window must be specified, since it is not
+ * necessarily always the current one. If lnum==0, current line is calculated,
+ * specified line otherwise.
+ */
+ int
+get_breakindent_win (wp,lnum)
+ win_T* wp;
+ linenr_T lnum;
+{
+ int bri;
+ /* window width minus barren space, i.e. what rests for text */
+ const int eff_wwidth = W_WIDTH(wp)
+ - (wp->w_p_nu && !vim_strchr(p_cpo,CPO_NUMCOL)?number_width(wp):0);
+ /* - (*p_sbr == NUL ? 0 : vim_strsize(p_sbr)); */
+
+ bri = get_indent_buf(wp->w_buffer,lnum?lnum:wp->w_cursor.lnum) +
wp->w_p_brishift;
+
+ /* 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 += number_width(wp);
+
+ /* never indent past left window margin */
+ if (bri < 0)
+ bri = 0;
+ /* always leave at least bri_min characters on the left,
+ * if text width is sufficient */
+ else if (bri > eff_wwidth - wp->w_p_brimin)
+ bri = eff_wwidth - wp->w_p_brimin < 0 ? 0 : eff_wwidth - wp->w_p_brimin;
+
+ return bri;
+}
+#endif
+
+
#if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
static int cin_is_cinword __ARGS((char_u *line));
@@ -1757,7 +1795,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
@@ -1813,7 +1851,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);
}
@@ -1825,7 +1863,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', 'relativenumber', 'foldcolumn', etc.
@@ -8503,7 +8541,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--;
}
@@ -8526,7 +8564,7 @@
while (vim_iswhite(*that))
{
- amount += lbr_chartabsize(that, (colnr_T)amount);
+ amount += lbr_chartabsize(that, (colnr_T)amount,
pos->lnum);
++that;
}
@@ -8565,14 +8603,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 == ';')
diff -r 7b50afd31037 src/misc2.c
--- a/src/misc2.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/misc2.c Tue Aug 23 10:20:21 2011 -0400
@@ -166,7 +166,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;
}
@@ -184,7 +184,7 @@
# endif
&& wcol >= (colnr_T)width)
{
- csize = linetabsize(line);
+ csize = linetabsize(line, pos->lnum);
if (csize > 0)
csize--;
@@ -205,10 +205,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;
}
diff -r 7b50afd31037 src/normal.c
--- a/src/normal.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/normal.c Tue Aug 23 10:20:21 2011 -0400
@@ -4438,7 +4438,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;
@@ -4511,7 +4511,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;
@@ -4541,7 +4541,7 @@
}
curwin->w_cursor.lnum++;
curwin->w_curswant %= width2;
- linelen = linetabsize(ml_get_curline());
+ linelen = linetabsize(ml_get_curline(), curwin->w_cursor.lnum);
}
}
}
diff -r 7b50afd31037 src/ops.c
--- a/src/ops.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/ops.c Tue Aug 23 10:20:21 2011 -0400
@@ -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;
}
@@ -488,7 +488,7 @@
while (vim_iswhite(*non_white))
{
- incr = lbr_chartabsize_adv(&non_white, non_white_col);
+ incr = lbr_chartabsize_adv(&non_white, non_white_col,
curwin->w_cursor.lnum);
non_white_col += incr;
}
@@ -513,7 +513,7 @@
verbatim_copy_width -= bd.start_char_vcols;
while (verbatim_copy_width < destination_col)
{
- incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
+ incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width,
curwin->w_cursor.lnum);
if (verbatim_copy_width + incr > destination_col)
break;
verbatim_copy_width += incr;
@@ -3565,7 +3565,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);
@@ -3599,7 +3599,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;
@@ -4961,7 +4961,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))
@@ -5030,7 +5030,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
@@ -6526,7 +6526,7 @@
validate_virtcol();
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
(int)curwin->w_virtcol + 1);
- col_print(buf2, sizeof(buf2), (int)STRLEN(p), linetabsize(p));
+ col_print(buf2, sizeof(buf2), (int)STRLEN(p), linetabsize(p,
curwin->w_cursor.lnum));
if (char_count_cursor == byte_count_cursor
&& char_count == byte_count)
diff -r 7b50afd31037 src/option.c
--- a/src/option.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/option.c Tue Aug 23 10:20:21 2011 -0400
@@ -187,6 +187,11 @@
#ifdef FEAT_ARABIC
# define PV_ARAB OPT_WIN(WV_ARAB)
#endif
+#ifdef FEAT_LINEBREAK
+# define PV_BRI OPT_WIN(WV_BRI)
+# define PV_BRIMIN OPT_WIN(WV_BRIMIN)
+# define PV_BRISHIFT OPT_WIN(WV_BRISHIFT)
+#endif
#ifdef FEAT_DIFF
# define PV_DIFF OPT_WIN(WV_DIFF)
#endif
@@ -644,6 +649,33 @@
{(char_u *)0L, (char_u *)0L}
#endif
SCRIPTID_INIT},
+ {"breakindent", "bri", P_BOOL|P_VI_DEF|P_VIM|P_RWIN,
+#ifdef FEAT_LINEBREAK
+ (char_u *)VAR_WIN, PV_BRI,
+ {(char_u *)FALSE, (char_u *)0L}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
+ {"breakindentmin", "brimin", P_NUM|P_VI_DEF|P_VIM|P_RWIN,
+#ifdef FEAT_LINEBREAK
+ (char_u *)VAR_WIN, PV_BRIMIN,
+ {(char_u *)20L, (char_u *)20L}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
+ {"breakindentshift", "brishift", P_NUM|P_VI_DEF|P_VIM|P_RWIN,
+#ifdef FEAT_LINEBREAK
+ (char_u *)VAR_WIN, PV_BRISHIFT,
+ {(char_u *)0L, (char_u *)0L}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
{"browsedir", "bsdir",P_STRING|P_VI_DEF,
#ifdef FEAT_BROWSE
(char_u *)&p_bsdir, PV_NONE,
@@ -8339,6 +8371,16 @@
}
curwin->w_nrwidth_line_count = 0;
}
+
+ /* 'breakindentmin' must be positive */
+ else if (pp == &curwin->w_p_brimin)
+ {
+ if (curwin->w_p_brimin < 1)
+ {
+ errmsg = e_positive;
+ curwin->w_p_brimin = 1;
+ }
+ }
#endif
else if (pp == &curbuf->b_p_tw)
@@ -9575,6 +9617,9 @@
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);
+ case PV_BRIMIN: return (char_u *)&(curwin->w_p_brimin);
+ case PV_BRISHIFT: return (char_u *)&(curwin->w_p_brishift);
#endif
#ifdef FEAT_SCROLLBIND
case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
@@ -9761,6 +9806,8 @@
to->wo_wrap = from->wo_wrap;
#ifdef FEAT_LINEBREAK
to->wo_lbr = from->wo_lbr;
+ to->wo_bri = from->wo_bri;
+ to->wo_brimin = from->wo_brimin;
#endif
#ifdef FEAT_SCROLLBIND
to->wo_scb = from->wo_scb;
diff -r 7b50afd31037 src/option.h
--- a/src/option.h Fri Aug 19 22:29:02 2011 +0200
+++ b/src/option.h Tue Aug 23 10:20:21 2011 -0400
@@ -1044,6 +1044,11 @@
#ifdef FEAT_CURSORBIND
, WV_CRBIND
#endif
+#ifdef FEAT_LINEBREAK
+ , WV_BRI
+ , WV_BRIMIN
+ , WV_BRISHIFT
+#endif
#ifdef FEAT_DIFF
, WV_DIFF
#endif
diff -r 7b50afd31037 src/proto/charset.pro
--- a/src/proto/charset.pro Fri Aug 19 22:29:02 2011 +0200
+++ b/src/proto/charset.pro Tue Aug 23 10:20:21 2011 -0400
@@ -14,9 +14,9 @@
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 linetabsize_col __ARGS((int startcol, 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 linetabsize_col __ARGS((int startcol, 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));
@@ -25,9 +25,9 @@
int vim_isfilec_or_wc __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));
diff -r 7b50afd31037 src/proto/misc1.pro
--- a/src/proto/misc1.pro Fri Aug 19 22:29:02 2011 +0200
+++ b/src/proto/misc1.pro Tue Aug 23 10:20:21 2011 -0400
@@ -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_win __ARGS((win_T *wp, 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));
diff -r 7b50afd31037 src/regexp.c
--- a/src/regexp.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/regexp.c Tue Aug 23 10:20:21 2011 -0400
@@ -4269,7 +4269,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;
}
@@ -4293,7 +4293,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;
diff -r 7b50afd31037 src/screen.c
--- a/src/screen.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/screen.c Tue Aug 23 10:20:21 2011 -0400
@@ -2802,10 +2802,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 */
@@ -3133,7 +3138,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;
@@ -3502,6 +3507,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_win(wp,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)
{
@@ -4208,7 +4237,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 = ' ';
diff -r 7b50afd31037 src/structs.h
--- a/src/structs.h Fri Aug 19 22:29:02 2011 +0200
+++ b/src/structs.h Tue Aug 23 10:20:21 2011 -0400
@@ -133,6 +133,14 @@
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' */
+ long wo_brimin;
+# define w_p_brimin w_onebuf_opt.wo_brimin /* 'breakindentmin' */
+ long wo_brishift;
+# define w_p_brishift w_onebuf_opt.wo_brishift /* 'breakindentshift' */
+#endif
#ifdef FEAT_DIFF
int wo_diff;
# define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */
diff -r 7b50afd31037 src/ui.c
--- a/src/ui.c Fri Aug 19 22:29:02 2011 +0200
+++ b/src/ui.c Tue Aug 23 10:20:21 2011 -0400
@@ -3086,7 +3086,7 @@
start = ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
while (count <= vcol && *ptr != NUL)
{
- count += win_lbr_chartabsize(wp, ptr, count, NULL);
+ count += win_lbr_chartabsize(wp, ptr, count, NULL, lnum);
mb_ptr_adv(ptr);
}
return (int)(ptr - start);
pgpbELTaSBcq2.pgp
Description: PGP signature
