summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2014-06-25 14:39:50 +0200
committerBram Moolenaar <Bram@vim.org>2014-06-25 14:39:50 +0200
commit597a422416f37f8e22ed8f561667d6bab8814958 (patch)
tree8bada5798d608ac2a37b7f0ddbf7a24e8da4bd25 /src
parent15a35c4f4a1670dd6ca228068a451f78d2bf75e0 (diff)
updated for version 7.4.338v7.4.338
Problem: Cannot wrap lines taking indent into account. Solution: Add the 'breakindent' option. (many authors, final improvements by Christian Brabandt)
Diffstat (limited to 'src')
-rw-r--r--src/charset.c53
-rw-r--r--src/edit.c23
-rw-r--r--src/ex_getln.c8
-rw-r--r--src/getchar.c2
-rw-r--r--src/misc1.c99
-rw-r--r--src/misc2.c7
-rw-r--r--src/ops.c26
-rw-r--r--src/option.c89
-rw-r--r--src/option.h4
-rw-r--r--src/proto/charset.pro8
-rw-r--r--src/proto/misc1.pro3
-rw-r--r--src/proto/option.pro1
-rw-r--r--src/screen.c60
-rw-r--r--src/structs.h11
-rw-r--r--src/testdir/Make_amiga.mak2
-rw-r--r--src/testdir/Make_dos.mak1
-rw-r--r--src/testdir/Make_ming.mak1
-rw-r--r--src/testdir/Make_os2.mak1
-rw-r--r--src/testdir/Make_vms.mms1
-rw-r--r--src/testdir/Makefile1
-rw-r--r--src/testdir/test_breakindent.in79
-rw-r--r--src/testdir/test_breakindent.ok55
-rw-r--r--src/ui.c8
-rw-r--r--src/version.c2
24 files changed, 465 insertions, 80 deletions
diff --git a/src/charset.c b/src/charset.c
index 61a56f6533..1ffaf467be 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -867,9 +867,10 @@ linetabsize_col(startcol, s)
char_u *s;
{
colnr_T col = startcol;
+ char_u *line = s; /* pointer to start of line, for breakindent */
while (*s != NUL)
- col += lbr_chartabsize_adv(&s, col);
+ col += lbr_chartabsize_adv(line, &s, col);
return (int)col;
}
@@ -877,16 +878,17 @@ linetabsize_col(startcol, s)
* Like linetabsize(), but for a given window instead of the current one.
*/
int
-win_linetabsize(wp, p, len)
+win_linetabsize(wp, line, len)
win_T *wp;
- char_u *p;
+ char_u *line;
colnr_T len;
{
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);
+ for (s = line; *s != NUL && (len == MAXCOL || s < line + len);
+ mb_ptr_adv(s))
+ col += win_lbr_chartabsize(wp, line, s, col, NULL);
return (int)col;
}
@@ -1021,12 +1023,13 @@ vim_isprintc_strict(c)
* like chartabsize(), but also check for line breaks on the screen
*/
int
-lbr_chartabsize(s, col)
+lbr_chartabsize(line, s, col)
+ char_u *line; /* start of the line */
unsigned char *s;
colnr_T col;
{
#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
@@ -1036,7 +1039,7 @@ lbr_chartabsize(s, col)
RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
#ifdef FEAT_LINEBREAK
}
- return win_lbr_chartabsize(curwin, s, col, NULL);
+ return win_lbr_chartabsize(curwin, line == NULL ? s : line, s, col, NULL);
#endif
}
@@ -1044,13 +1047,14 @@ lbr_chartabsize(s, col)
* Call lbr_chartabsize() and advance the pointer.
*/
int
-lbr_chartabsize_adv(s, col)
+lbr_chartabsize_adv(line, s, col)
+ char_u *line; /* start of the line */
char_u **s;
colnr_T col;
{
int retval;
- retval = lbr_chartabsize(*s, col);
+ retval = lbr_chartabsize(line, *s, col);
mb_ptr_adv(*s);
return retval;
}
@@ -1063,8 +1067,9 @@ lbr_chartabsize_adv(s, col)
* value, init to 0 before calling.
*/
int
-win_lbr_chartabsize(wp, s, col, headp)
+win_lbr_chartabsize(wp, line, s, col, headp)
win_T *wp;
+ char_u *line; /* start of the line */
char_u *s;
colnr_T col;
int *headp UNUSED;
@@ -1086,9 +1091,9 @@ win_lbr_chartabsize(wp, s, col, headp)
int n;
/*
- * No 'linebreak' and 'showbreak': return quickly.
+ * No 'linebreak', '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
@@ -1163,11 +1168,12 @@ win_lbr_chartabsize(wp, s, col, headp)
# 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;
@@ -1180,7 +1186,12 @@ win_lbr_chartabsize(wp, s, col, headp)
}
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, line);
+
if (tab_corr)
size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
else
@@ -1274,13 +1285,14 @@ getvcol(wp, pos, start, cursor, end)
colnr_T vcol;
char_u *ptr; /* points to current char */
char_u *posptr; /* points to char at pos->col */
+ char_u *line; /* start of the line */
int incr;
int head;
int ts = wp->w_buffer->b_p_ts;
int c;
vcol = 0;
- ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
+ line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
if (pos->col == MAXCOL)
posptr = NULL; /* continue until the NUL */
else
@@ -1288,12 +1300,13 @@ getvcol(wp, pos, start, cursor, end)
/*
* 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
)
{
@@ -1355,7 +1368,7 @@ getvcol(wp, pos, start, cursor, end)
{
/* A tab gets expanded, depending on the current column */
head = 0;
- incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
+ incr = win_lbr_chartabsize(wp, line, ptr, vcol, &head);
/* make sure we don't go past the end of the line */
if (*ptr == NUL)
{
diff --git a/src/edit.c b/src/edit.c
index 94ec789769..a43d0d7b85 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1956,7 +1956,7 @@ change_indent(type, amount, round, replaced, call_changed_bytes)
else
#endif
++new_cursor_col;
- vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_T)vcol);
+ vcol += lbr_chartabsize(ptr, ptr + new_cursor_col, (colnr_T)vcol);
}
vcol = last_vcol;
@@ -7126,9 +7126,10 @@ oneleft()
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
@@ -9758,11 +9759,11 @@ ins_tab()
getvcol(curwin, &fpos, &vcol, NULL, NULL);
getvcol(curwin, cursor, &want_vcol, NULL, NULL);
- /* Use as many TABs as possible. Beware of 'showbreak' and
- * 'linebreak' adding extra virtual columns. */
+ /* 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(NULL, (char_u *)"\t", vcol);
if (vcol + i > want_vcol)
break;
if (*ptr != TAB)
@@ -9784,11 +9785,12 @@ ins_tab()
if (change_col >= 0)
{
int repl_off = 0;
+ char_u *line = ptr;
/* Skip over the spaces we need. */
while (vcol < want_vcol && *ptr == ' ')
{
- vcol += lbr_chartabsize(ptr, vcol);
+ vcol += lbr_chartabsize(line, ptr, vcol);
++ptr;
++repl_off;
}
@@ -10029,6 +10031,7 @@ ins_copychar(lnum)
int c;
int temp;
char_u *ptr, *prev_ptr;
+ char_u *line;
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
{
@@ -10038,13 +10041,13 @@ ins_copychar(lnum)
/* try to advance to the cursor column */
temp = 0;
- ptr = ml_get(lnum);
+ line = ptr = ml_get(lnum);
prev_ptr = ptr;
validate_virtcol();
while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL)
{
prev_ptr = ptr;
- temp += lbr_chartabsize_adv(&ptr, (colnr_T)temp);
+ temp += lbr_chartabsize_adv(line, &ptr, (colnr_T)temp);
}
if ((colnr_T)temp > curwin->w_virtcol)
ptr = prev_ptr;
diff --git a/src/ex_getln.c b/src/ex_getln.c
index d000112e62..fcc1d600a6 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -2302,10 +2302,10 @@ getexmodeline(promptc, cookie, indent)
p = (char_u *)line_ga.ga_data;
p[line_ga.ga_len] = NUL;
- indent = get_indent_str(p, 8);
+ indent = get_indent_str(p, 8, FALSE);
indent += sw - indent % sw;
add_indent:
- while (get_indent_str(p, 8) < indent)
+ while (get_indent_str(p, 8, FALSE) < indent)
{
char_u *s = skipwhite(p);
@@ -2357,11 +2357,11 @@ redraw:
else
{
p[line_ga.ga_len] = NUL;
- indent = get_indent_str(p, 8);
+ indent = get_indent_str(p, 8, FALSE);
--indent;
indent -= indent % get_sw_value(curbuf);
}
- while (get_indent_str(p, 8) > indent)
+ while (get_indent_str(p, 8, FALSE) > indent)
{
char_u *s = skipwhite(p);
diff --git a/src/getchar.c b/src/getchar.c
index c4ffb4b163..55fdd31122 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -2675,7 +2675,7 @@ vgetorpeek(advance)
{
if (!vim_iswhite(ptr[col]))
curwin->w_wcol = vcol;
- vcol += lbr_chartabsize(ptr + col,
+ vcol += lbr_chartabsize(ptr, ptr + col,
(colnr_T)vcol);
#ifdef FEAT_MBYTE
if (has_mbyte)
diff --git a/src/misc1.c b/src/misc1.c
index 95d18a571f..1c2f8f274d 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -32,7 +32,7 @@ static garray_T ga_users;
int
get_indent()
{
- return get_indent_str(ml_get_curline(), (int)curbuf->b_p_ts);
+ return get_indent_str(ml_get_curline(), (int)curbuf->b_p_ts, FALSE);
}
/*
@@ -42,7 +42,7 @@ get_indent()
get_indent_lnum(lnum)
linenr_T lnum;
{
- return get_indent_str(ml_get(lnum), (int)curbuf->b_p_ts);
+ return get_indent_str(ml_get(lnum), (int)curbuf->b_p_ts, FALSE);
}
#if defined(FEAT_FOLDING) || defined(PROTO)
@@ -55,7 +55,7 @@ get_indent_buf(buf, lnum)
buf_T *buf;
linenr_T lnum;
{
- return get_indent_str(ml_get_buf(buf, lnum, FALSE), (int)buf->b_p_ts);
+ return get_indent_str(ml_get_buf(buf, lnum, FALSE), (int)buf->b_p_ts, FALSE);
}
#endif
@@ -64,16 +64,23 @@ get_indent_buf(buf, lnum)
* 'tabstop' at "ts"
*/
int
-get_indent_str(ptr, ts)
+get_indent_str(ptr, ts, list)
char_u *ptr;
int ts;
+ int list; /* if TRUE, count only screen size for tabs */
{
int count = 0;
for ( ; *ptr; ++ptr)
{
- if (*ptr == TAB) /* count a tab for what it is worth */
- count += ts - (count % ts);
+ if (*ptr == TAB)
+ {
+ if (!list || lcs_tab1) /* count a tab for what it is worth */
+ count += ts - (count % ts);
+ else
+ /* in list mode, when tab is not set, count screen char width for Tab: ^I */
+ count += ptr2cells(ptr);
+ }
else if (*ptr == ' ')
++count; /* count a space for one */
else
@@ -476,6 +483,58 @@ get_number_indent(lnum)
return (int)col;
}
+#if defined(FEAT_LINEBREAK) || defined(PROTO)
+/*
+ * Return appropriate space number for breakindent, taking influencing
+ * parameters into account. Window must be specified, since it is not
+ * necessarily always the current one.
+ */
+ int
+get_breakindent_win(wp, line)
+ win_T *wp;
+ char_u *line; /* start of the line */
+{
+ static int prev_indent = 0; /* cached indent value */
+ static long prev_ts = 0L; /* cached tabstop value */
+ static char_u *prev_line = NULL; /* cached pointer to line */
+ int bri = 0;
+ /* window width minus window margin space, i.e. what rests for text */
+ const int eff_wwidth = W_WIDTH(wp)
+ - ((wp->w_p_nu || wp->w_p_rnu)
+ && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
+ ? number_width(wp) + 1 : 0);
+
+ /* used cached indent, unless pointer or 'tabstop' changed */
+ if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts)
+ {
+ prev_line = line;
+ prev_ts = wp->w_buffer->b_p_ts;
+ prev_indent = get_indent_str(line,
+ (int)wp->w_buffer->b_p_ts, wp->w_p_list) + wp->w_p_brishift;
+ }
+
+ /* indent minus the length of the showbreak string */
+ bri = prev_indent;
+ if (wp->w_p_brisbr)
+ bri -= vim_strsize(p_sbr);
+
+ /* Add offset for number column, if 'n' is in 'cpoptions' */
+ bri += win_col_off2(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));
@@ -678,7 +737,7 @@ open_line(dir, flags, second_line_indent)
/*
* count white space on current line
*/
- newindent = get_indent_str(saved_line, (int)curbuf->b_p_ts);
+ newindent = get_indent_str(saved_line, (int)curbuf->b_p_ts, FALSE);
if (newindent == 0 && !(flags & OPENLINE_COM_LIST))
newindent = second_line_indent; /* for ^^D command in insert mode */
@@ -1201,7 +1260,7 @@ open_line(dir, flags, second_line_indent)
|| do_si
#endif
)
- newindent = get_indent_str(leader, (int)curbuf->b_p_ts);
+ newindent = get_indent_str(leader, (int)curbuf->b_p_ts, FALSE);
/* Add the indent offset */
if (newindent + off < 0)
@@ -1994,6 +2053,7 @@ plines_win_col(wp, lnum, column)
char_u *s;
int lines = 0;
int width;
+ char_u *line;
#ifdef FEAT_DIFF
/* Check for filler lines above this buffer line. When folded the result
@@ -2009,12 +2069,12 @@ plines_win_col(wp, lnum, column)
return lines + 1;
#endif
- s = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ line = s = ml_get_buf(wp->w_buffer, lnum, FALSE);
col = 0;
while (*s != NUL && --column >= 0)
{
- col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL);
+ col += win_lbr_chartabsize(wp, line, s, (colnr_T)col, NULL);
mb_ptr_adv(s);
}
@@ -2026,7 +2086,7 @@ plines_win_col(wp, lnum, column)
* '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, line, s, (colnr_T)col, NULL) - 1;
/*
* Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
@@ -9002,10 +9062,12 @@ get_lisp_indent()
amount = 2;
else
{
+ char_u *line = that;
+
amount = 0;
while (*that && col)
{
- amount += lbr_chartabsize_adv(&that, (colnr_T)amount);
+ amount += lbr_chartabsize_adv(line, &that, (colnr_T)amount);
col--;
}
@@ -9028,7 +9090,7 @@ get_lisp_indent()
while (vim_iswhite(*that))
{
- amount += lbr_chartabsize(that, (colnr_T)amount);
+ amount += lbr_chartabsize(line, that, (colnr_T)amount);
++that;
}
@@ -9066,15 +9128,16 @@ get_lisp_indent()
&& !quotecount)
--parencount;
if (*that == '\\' && *(that+1) != NUL)
- amount += lbr_chartabsize_adv(&that,
- (colnr_T)amount);
- amount += lbr_chartabsize_adv(&that,
- (colnr_T)amount);
+ amount += lbr_chartabsize_adv(
+ line, &that, (colnr_T)amount);
+ amount += lbr_chartabsize_adv(
+ line, &that, (colnr_T)amount);
}
}
while (vim_iswhite(*that))
{
- amount += lbr_chartabsize(that, (colnr_T)amount);
+ amount += lbr_chartabsize(
+ line, that, (colnr_T)amount);
that++;
}
if (!*that || *that == ';')
diff --git a/src/misc2.c b/src/misc2.c
index b0673d4434..1a5b370ba8 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -201,10 +201,10 @@ coladvance2(pos, addspaces, finetune, wcol)
{
/* 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, line, ptr, col, &head);
mb_ptr_adv(ptr);
#else
- csize = lbr_chartabsize_adv(&ptr, col);
+ csize = lbr_chartabsize_adv(line, &ptr, col);
#endif
col += csize;
}
@@ -2156,7 +2156,8 @@ ga_append(gap, c)
}
}
-#if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264)
+#if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264) \
+ || defined(PROTO)
/*
* Append the text in "gap" below the cursor line and clear "gap".
*/
diff --git a/src/ops.c b/src/ops.c
index f5bf0f8f30..265cf3a854 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -420,7 +420,9 @@ shift_block(oap, amount)
}
for ( ; vim_iswhite(*bd.textstart); )
{
- incr = lbr_chartabsize_adv(&bd.textstart, (colnr_T)(bd.start_vcol));
+ /* TODO: is passing bd.textstart for start of the line OK? */
+ incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart,
+ (colnr_T)(bd.start_vcol));
total += incr;
bd.start_vcol += incr;
}
@@ -480,7 +482,7 @@ shift_block(oap, amount)
while (vim_iswhite(*non_white))
{
- incr = lbr_chartabsize_adv(&non_white, non_white_col);
+ incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col);
non_white_col += incr;
}
@@ -505,7 +507,11 @@ shift_block(oap, amount)
verbatim_copy_width -= bd.start_char_vcols;
while (verbatim_copy_width < destination_col)
{
- incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
+ char_u *line = verbatim_copy_end;
+
+ /* TODO: is passing verbatim_copy_end for start of the line OK? */
+ incr = lbr_chartabsize(line, verbatim_copy_end,
+ verbatim_copy_width);
if (verbatim_copy_width + incr > destination_col)
break;
verbatim_copy_width += incr;
@@ -3617,7 +3623,7 @@ do_put(regname, dir, count, flags)
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(oldp, &ptr, (colnr_T)vcol);
vcol += incr;
}
bd.textcol = (colnr_T)(ptr - oldp);
@@ -3651,7 +3657,7 @@ do_put(regname, dir, count, flags)
/* 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(NULL, &y_array[i][j], 0);
if (spaces < 0)
spaces = 0;
@@ -5203,7 +5209,7 @@ block_prep(oap, bdp, lnum, is_del)
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(line, pstart, (colnr_T)bdp->start_vcol);
bdp->start_vcol += incr;
#ifdef FEAT_VISUALEXTRA
if (vim_iswhite(*pstart))
@@ -5272,7 +5278,10 @@ block_prep(oap, bdp, lnum, is_del)
{
/* 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);
+ /* TODO: is passing prev_pend for start of the line OK?
+ * perhaps it should be "line". */
+ incr = lbr_chartabsize_adv(prev_pend, &pend,
+ (colnr_T)bdp->end_vcol);
bdp->end_vcol += incr;
}
if (bdp->end_vcol <= oap->end_vcol
@@ -6882,7 +6891,8 @@ cursor_pos_info()
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));
if (char_count_cursor == byte_count_cursor
&& char_count == byte_count)
diff --git a/src/option.c b/src/option.c
index f2f232e357..05dc992d96 100644
--- a/src/option.c
+++ b/src/option.c
@@ -188,6 +188,10 @@
#ifdef FEAT_ARABIC
# define PV_ARAB OPT_WIN(WV_ARAB)
#endif
+#ifdef FEAT_LINEBREAK
+# define PV_BRI OPT_WIN(WV_BRI)
+# define PV_BRIOPT OPT_WIN(WV_BRIOPT)
+#endif
#ifdef FEAT_DIFF
# define PV_DIFF OPT_WIN(WV_DIFF)
#endif
@@ -648,6 +652,24 @@ static struct vimoption
{(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},
+ {"breakindentopt", "briopt", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_COMMA|P_NODUP,
+#ifdef FEAT_LINEBREAK
+ (char_u *)VAR_WIN, PV_BRIOPT,
+ {(char_u *)"", (char_u *)NULL}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)"", (char_u *)NULL}
+#endif
+ SCRIPTID_INIT},
{"browsedir", "bsdir",P_STRING|P_VI_DEF,
#ifdef FEAT_BROWSE
(char_u *)&p_bsdir, PV_NONE,
@@ -5256,6 +5278,9 @@ didset_options()
/* set cedit_key */
(void)check_cedit();
#endif
+#ifdef FEAT_LINEBREAK
+ briopt_check();
+#endif
}
/*
@@ -5709,6 +5734,14 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
*p_pm == '.' ? p_pm + 1 : p_pm) == 0)
errmsg = (char_u *)N_("E589: 'backupext' and 'patchmode' are equal");
}
+#ifdef FEAT_LINEBREAK
+ /* 'breakindentopt' */
+ else if (varp == &curwin->w_p_briopt)
+ {
+ if (briopt_check() == FAIL)
+ errmsg = e_invarg;
+ }
+#endif
/*
* 'isident', 'iskeyword', 'isprint or 'isfname' option: refill chartab[]
@@ -10018,6 +10051,8 @@ get_varp(p)
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_BRIOPT: return (char_u *)&(curwin->w_p_briopt);
#endif
#ifdef FEAT_SCROLLBIND
case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
@@ -10207,6 +10242,8 @@ copy_winopt(from, to)
#endif
#ifdef FEAT_LINEBREAK
to->wo_lbr = from->wo_lbr;
+ to->wo_bri = from->wo_bri;
+ to->wo_briopt = vim_strsave(from->wo_briopt);
#endif
#ifdef FEAT_SCROLLBIND
to->wo_scb = from->wo_scb;
@@ -10294,6 +10331,9 @@ check_winopt(wop)
#ifdef FEAT_CONCEAL
check_string_option(&wop->wo_cocu);
#endif
+#ifdef FEAT_LINEBREAK
+ check_string_option(&wop->wo_briopt);
+#endif
}
/*
@@ -10313,6 +10353,9 @@ clear_winopt(wop)
# endif
clear_string_option(&wop->wo_fmr);
#endif
+#ifdef FEAT_LINEBREAK
+ clear_string_option(&wop->wo_briopt);
+#endif
#ifdef FEAT_RIGHTLEFT
clear_string_option(&wop->wo_rlc);
#endif
@@ -11927,3 +11970,49 @@ find_mps_values(initc, findc, backwards, switchit)
++ptr;
}
}
+
+#if defined(FEAT_LINEBREAK) || defined(PROTO)
+/*
+ * This is called when 'breakindentopt' is changed and when a window is
+ * initialized.
+ */
+ int
+briopt_check()
+{
+ char_u *p;
+ int bri_shift = 0;
+ long bri_min = 20;
+ int bri_sbr = FALSE;
+
+ p = curwin->w_p_briopt;
+ while (*p != NUL)
+ {
+ if (STRNCMP(p, "shift:", 6) == 0
+ && ((p[6] == '-' && VIM_ISDIGIT(p[7])) || VIM_ISDIGIT(p[6])))
+ {
+ p += 6;
+ bri_shift = getdigits(&p);
+ }
+ else if (STRNCMP(p, "min:", 4) == 0 && VIM_ISDIGIT(p[4]))
+ {
+ p += 4;
+ bri_min = getdigits(&p);
+ }
+ else if (STRNCMP(p, "sbr", 3) == 0)
+ {
+ p += 3;
+ bri_sbr = TRUE;
+ }
+ if (*p != ',' && *p != NUL)
+ return FAIL;
+ if (*p == ',')
+ ++p;
+ }
+
+ curwin->w_p_brishift = bri_shift;
+ curwin->w_p_brimin = bri_min;
+ curwin->w_p_brisbr = bri_sbr;
+
+ return OK;
+}
+#endif
diff --git a/src/option.h b/src/option.h
index dc56629484..edf9058440 100644
--- a/src/option.h
+++ b/src/option.h
@@ -1052,6 +1052,10 @@ enum
#ifdef FEAT_CURSORBIND
, WV_CRBIND
#endif
+#ifdef FEAT_LINEBREAK
+ , WV_BRI
+ , WV_BRIOPT
+#endif
#ifdef FEAT_DIFF
, WV_DIFF
#endif
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
index 72eed4b071..fc7769ce36 100644
--- a/src/proto/charset.pro
+++ b/src/proto/charset.pro
@@ -16,7 +16,7 @@ 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 win_linetabsize __ARGS((win_T *wp, char_u *line, colnr_T len));
int vim_isIDc __ARGS((int c));
int vim_iswordc __ARGS((int c));
int vim_iswordc_buf __ARGS((int c, buf_T *buf));
@@ -26,9 +26,9 @@ int vim_isfilec __ARGS((int c));
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((char_u *line, unsigned char *s, colnr_T col));
+int lbr_chartabsize_adv __ARGS((char_u *line, char_u **s, colnr_T col));
+int win_lbr_chartabsize __ARGS((win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp));
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 --git a/src/proto/misc1.pro b/src/proto/misc1.pro
index 496d2e45a9..274c7af46f 100644
--- a/src/proto/misc1.pro
+++ b/src/proto/misc1.pro
@@ -2,9 +2,10 @@
int get_indent __ARGS((void));
int get_indent_lnum __ARGS((linenr_T lnum));
int get_indent_buf __ARGS((buf_T *buf, linenr_T lnum));
-int get_indent_str __ARGS((char_u *ptr, int ts));
+int get_indent_str __ARGS((char_u *ptr, int ts, int list));
int set_indent __ARGS((int size, int flags));
int get_number_indent __ARGS((linenr_T lnum));
+int get_breakindent_win __ARGS((win_T *wp, char_u *ptr));
int open_line __ARGS((int dir, int flags, int second_line_indent));
int get_leader_len __ARGS((char_u *line, char_u **flags, int backward, int include_space));
int get_last_leader_offset __ARGS((char_u *line, char_u **flags));
diff --git a/src/proto/option.pro b/src/proto/option.pro
index 4347d65919..4729c47842 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -63,4 +63,5 @@ int check_ff_value __ARGS((char_u *p));
long get_sw_value __ARGS((buf_T *buf));
long get_sts_value __ARGS((void));
void find_mps_values __ARGS((int *initc, int *findc, int *backwards, int switchit));
+int briopt_check __ARGS((void));
/* vim: set ft=c : */
diff --git a/src/screen.c b/src/screen.c
index 872ef08a5a..388a29832e 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2962,10 +2962,15 @@ win_line(wp, lnum, startrow, endrow, nochange)
# 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 */
@@ -3301,7 +3306,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
#endif
while (vcol < v && *ptr != NUL)
{
- c = win_lbr_chartabsize(wp, ptr, (colnr_T)vcol, NULL);
+ c = win_lbr_chartabsize(wp, line, ptr, (colnr_T)vcol, NULL);
vcol += c;
#ifdef FEAT_MBYTE
prev_ptr = ptr;
@@ -3670,6 +3675,44 @@ win_line(wp, lnum, startrow, endrow, nochange)
}
}
+#ifdef FEAT_LINEBREAK
+ if (wp->w_p_brisbr && draw_state == WL_BRI - 1
+ && n_extra == 0 && *p_sbr != NUL)
+ /* draw indent after showbreak value */
+ draw_state = WL_BRI;
+ else if (wp->w_p_brisbr && draw_state == WL_SBR &&am