updated for version 7.4.338

Problem:    Cannot wrap lines taking indent into account.
Solution:   Add the 'breakindent' option. (many authors, final improvements by
            Christian Brabandt)
This commit is contained in:
Bram Moolenaar
2014-06-25 14:39:50 +02:00
parent 15a35c4f4a
commit 597a422416
26 changed files with 474 additions and 83 deletions

View File

@@ -6651,8 +6651,8 @@ jumplist Compiled with |jumplist| support.
keymap Compiled with 'keymap' support. keymap Compiled with 'keymap' support.
langmap Compiled with 'langmap' support. langmap Compiled with 'langmap' support.
libcall Compiled with |libcall()| support. libcall Compiled with |libcall()| support.
linebreak Compiled with 'linebreak', 'breakat' and 'showbreak' linebreak Compiled with 'linebreak', 'breakat', 'showbreak' and
support. 'breakindent' support.
lispindent Compiled with support for lisp indenting. lispindent Compiled with support for lisp indenting.
listcmds Compiled with commands for the buffer list |:files| listcmds Compiled with commands for the buffer list |:files|
and the argument list |arglist|. and the argument list |arglist|.

View File

@@ -324,6 +324,12 @@ call <SID>BinOptionG("wrap", &wrap)
call append("$", "linebreak\twrap long lines at a character in 'breakat'") call append("$", "linebreak\twrap long lines at a character in 'breakat'")
call append("$", "\t(local to window)") call append("$", "\t(local to window)")
call <SID>BinOptionL("lbr") call <SID>BinOptionL("lbr")
call append("$", "breakindent\tpreserve indentation in wrapped text")
call append("$", "\t(local to window)")
call <SID>BinOptionL("bri")
call append("$", "breakindentopt\tadjust breakindent behaviour")
call append("$", "\t(local to window)")
call <SID>OptionL("briopt")
call append("$", "breakat\twhich characters might cause a line break") call append("$", "breakat\twhich characters might cause a line break")
call <SID>OptionG("brk", &brk) call <SID>OptionG("brk", &brk)
call append("$", "showbreak\tstring to put before wrapped screen lines") call append("$", "showbreak\tstring to put before wrapped screen lines")

View File

@@ -867,9 +867,10 @@ linetabsize_col(startcol, s)
char_u *s; char_u *s;
{ {
colnr_T col = startcol; colnr_T col = startcol;
char_u *line = s; /* pointer to start of line, for breakindent */
while (*s != NUL) while (*s != NUL)
col += lbr_chartabsize_adv(&s, col); col += lbr_chartabsize_adv(line, &s, col);
return (int)col; return (int)col;
} }
@@ -877,16 +878,17 @@ linetabsize_col(startcol, s)
* Like linetabsize(), but for a given window instead of the current one. * Like linetabsize(), but for a given window instead of the current one.
*/ */
int int
win_linetabsize(wp, p, len) win_linetabsize(wp, line, len)
win_T *wp; win_T *wp;
char_u *p; char_u *line;
colnr_T len; colnr_T len;
{ {
colnr_T col = 0; colnr_T col = 0;
char_u *s; char_u *s;
for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s)) for (s = line; *s != NUL && (len == MAXCOL || s < line + len);
col += win_lbr_chartabsize(wp, s, col, NULL); mb_ptr_adv(s))
col += win_lbr_chartabsize(wp, line, s, col, NULL);
return (int)col; return (int)col;
} }
@@ -1021,12 +1023,13 @@ vim_isprintc_strict(c)
* like chartabsize(), but also check for line breaks on the screen * like chartabsize(), but also check for line breaks on the screen
*/ */
int int
lbr_chartabsize(s, col) lbr_chartabsize(line, s, col)
char_u *line; /* start of the line */
unsigned char *s; unsigned char *s;
colnr_T col; colnr_T col;
{ {
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
if (!curwin->w_p_lbr && *p_sbr == NUL) if (!curwin->w_p_lbr && *p_sbr == NUL && !curwin->w_p_bri)
{ {
#endif #endif
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
@@ -1036,7 +1039,7 @@ lbr_chartabsize(s, col)
RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col) RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
} }
return win_lbr_chartabsize(curwin, s, col, NULL); return win_lbr_chartabsize(curwin, line == NULL ? s : line, s, col, NULL);
#endif #endif
} }
@@ -1044,13 +1047,14 @@ lbr_chartabsize(s, col)
* Call lbr_chartabsize() and advance the pointer. * Call lbr_chartabsize() and advance the pointer.
*/ */
int int
lbr_chartabsize_adv(s, col) lbr_chartabsize_adv(line, s, col)
char_u *line; /* start of the line */
char_u **s; char_u **s;
colnr_T col; colnr_T col;
{ {
int retval; int retval;
retval = lbr_chartabsize(*s, col); retval = lbr_chartabsize(line, *s, col);
mb_ptr_adv(*s); mb_ptr_adv(*s);
return retval; return retval;
} }
@@ -1063,8 +1067,9 @@ lbr_chartabsize_adv(s, col)
* value, init to 0 before calling. * value, init to 0 before calling.
*/ */
int int
win_lbr_chartabsize(wp, s, col, headp) win_lbr_chartabsize(wp, line, s, col, headp)
win_T *wp; win_T *wp;
char_u *line; /* start of the line */
char_u *s; char_u *s;
colnr_T col; colnr_T col;
int *headp UNUSED; int *headp UNUSED;
@@ -1086,9 +1091,9 @@ win_lbr_chartabsize(wp, s, col, headp)
int n; 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 #endif
{ {
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
@@ -1163,11 +1168,12 @@ win_lbr_chartabsize(wp, s, col, headp)
# endif # 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. * Set *headp to the size of what we add.
*/ */
added = 0; 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); numberextra = win_col_off(wp);
col += numberextra + mb_added; 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)) 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) if (tab_corr)
size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts; size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
else else
@@ -1274,13 +1285,14 @@ getvcol(wp, pos, start, cursor, end)
colnr_T vcol; colnr_T vcol;
char_u *ptr; /* points to current char */ char_u *ptr; /* points to current char */
char_u *posptr; /* points to char at pos->col */ char_u *posptr; /* points to char at pos->col */
char_u *line; /* start of the line */
int incr; int incr;
int head; int head;
int ts = wp->w_buffer->b_p_ts; int ts = wp->w_buffer->b_p_ts;
int c; int c;
vcol = 0; 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) if (pos->col == MAXCOL)
posptr = NULL; /* continue until the NUL */ posptr = NULL; /* continue until the NUL */
else else
@@ -1288,12 +1300,13 @@ getvcol(wp, pos, start, cursor, end)
/* /*
* This function is used very often, do some speed optimizations. * 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. * Also use this when 'list' is set but tabs take their normal size.
*/ */
if ((!wp->w_p_list || lcs_tab1 != NUL) if ((!wp->w_p_list || lcs_tab1 != NUL)
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
&& !wp->w_p_lbr && *p_sbr == NUL && !wp->w_p_lbr && *p_sbr == NUL && !wp->w_p_bri
#endif #endif
) )
{ {
@@ -1355,7 +1368,7 @@ getvcol(wp, pos, start, cursor, end)
{ {
/* A tab gets expanded, depending on the current column */ /* A tab gets expanded, depending on the current column */
head = 0; 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 */ /* make sure we don't go past the end of the line */
if (*ptr == NUL) if (*ptr == NUL)
{ {

View File

@@ -1956,7 +1956,7 @@ change_indent(type, amount, round, replaced, call_changed_bytes)
else else
#endif #endif
++new_cursor_col; ++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; vcol = last_vcol;
@@ -7126,9 +7126,10 @@ oneleft()
for (;;) for (;;)
{ {
coladvance(v - width); coladvance(v - width);
/* getviscol() is slow, skip it when 'showbreak' is empty and /* getviscol() is slow, skip it when 'showbreak' is empty,
* there are no multi-byte characters */ * 'breakindent' is not set and there are no multi-byte
if ((*p_sbr == NUL * characters */
if ((*p_sbr == NUL && !curwin->w_p_bri
# ifdef FEAT_MBYTE # ifdef FEAT_MBYTE
&& !has_mbyte && !has_mbyte
# endif # endif
@@ -9758,11 +9759,11 @@ ins_tab()
getvcol(curwin, &fpos, &vcol, NULL, NULL); getvcol(curwin, &fpos, &vcol, NULL, NULL);
getvcol(curwin, cursor, &want_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'
* 'linebreak' adding extra virtual columns. */ * and 'linebreak' adding extra virtual columns. */
while (vim_iswhite(*ptr)) while (vim_iswhite(*ptr))
{ {
i = lbr_chartabsize((char_u *)"\t", vcol); i = lbr_chartabsize(NULL, (char_u *)"\t", vcol);
if (vcol + i > want_vcol) if (vcol + i > want_vcol)
break; break;
if (*ptr != TAB) if (*ptr != TAB)
@@ -9784,11 +9785,12 @@ ins_tab()
if (change_col >= 0) if (change_col >= 0)
{ {
int repl_off = 0; int repl_off = 0;
char_u *line = ptr;
/* Skip over the spaces we need. */ /* Skip over the spaces we need. */
while (vcol < want_vcol && *ptr == ' ') while (vcol < want_vcol && *ptr == ' ')
{ {
vcol += lbr_chartabsize(ptr, vcol); vcol += lbr_chartabsize(line, ptr, vcol);
++ptr; ++ptr;
++repl_off; ++repl_off;
} }
@@ -10029,6 +10031,7 @@ ins_copychar(lnum)
int c; int c;
int temp; int temp;
char_u *ptr, *prev_ptr; char_u *ptr, *prev_ptr;
char_u *line;
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
{ {
@@ -10038,13 +10041,13 @@ ins_copychar(lnum)
/* try to advance to the cursor column */ /* try to advance to the cursor column */
temp = 0; temp = 0;
ptr = ml_get(lnum); line = ptr = ml_get(lnum);
prev_ptr = ptr; prev_ptr = ptr;
validate_virtcol(); validate_virtcol();
while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL) while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL)
{ {
prev_ptr = ptr; 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) if ((colnr_T)temp > curwin->w_virtcol)
ptr = prev_ptr; ptr = prev_ptr;

View File

@@ -2302,10 +2302,10 @@ getexmodeline(promptc, cookie, indent)
p = (char_u *)line_ga.ga_data; p = (char_u *)line_ga.ga_data;
p[line_ga.ga_len] = NUL; p[line_ga.ga_len] = NUL;
indent = get_indent_str(p, 8); indent = get_indent_str(p, 8, FALSE);
indent += sw - indent % sw; indent += sw - indent % sw;
add_indent: add_indent:
while (get_indent_str(p, 8) < indent) while (get_indent_str(p, 8, FALSE) < indent)
{ {
char_u *s = skipwhite(p); char_u *s = skipwhite(p);
@@ -2357,11 +2357,11 @@ redraw:
else else
{ {
p[line_ga.ga_len] = NUL; p[line_ga.ga_len] = NUL;
indent = get_indent_str(p, 8); indent = get_indent_str(p, 8, FALSE);
--indent; --indent;
indent -= indent % get_sw_value(curbuf); 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); char_u *s = skipwhite(p);

View File

@@ -2675,7 +2675,7 @@ vgetorpeek(advance)
{ {
if (!vim_iswhite(ptr[col])) if (!vim_iswhite(ptr[col]))
curwin->w_wcol = vcol; curwin->w_wcol = vcol;
vcol += lbr_chartabsize(ptr + col, vcol += lbr_chartabsize(ptr, ptr + col,
(colnr_T)vcol); (colnr_T)vcol);
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
if (has_mbyte) if (has_mbyte)

View File

@@ -32,7 +32,7 @@ static garray_T ga_users;
int int
get_indent() 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) get_indent_lnum(lnum)
linenr_T 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) #if defined(FEAT_FOLDING) || defined(PROTO)
@@ -55,7 +55,7 @@ get_indent_buf(buf, lnum)
buf_T *buf; buf_T *buf;
linenr_T lnum; 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 #endif
@@ -64,16 +64,23 @@ get_indent_buf(buf, lnum)
* 'tabstop' at "ts" * 'tabstop' at "ts"
*/ */
int int
get_indent_str(ptr, ts) get_indent_str(ptr, ts, list)
char_u *ptr; char_u *ptr;
int ts; int ts;
int list; /* if TRUE, count only screen size for tabs */
{ {
int count = 0; int count = 0;
for ( ; *ptr; ++ptr) for ( ; *ptr; ++ptr)
{ {
if (*ptr == TAB) /* count a tab for what it is worth */ if (*ptr == TAB)
count += ts - (count % ts); {
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 == ' ') else if (*ptr == ' ')
++count; /* count a space for one */ ++count; /* count a space for one */
else else
@@ -476,6 +483,58 @@ get_number_indent(lnum)
return (int)col; 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) #if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
static int cin_is_cinword __ARGS((char_u *line)); 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 * 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)) if (newindent == 0 && !(flags & OPENLINE_COM_LIST))
newindent = second_line_indent; /* for ^^D command in insert mode */ newindent = second_line_indent; /* for ^^D command in insert mode */
@@ -1201,7 +1260,7 @@ open_line(dir, flags, second_line_indent)
|| do_si || do_si
#endif #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 */ /* Add the indent offset */
if (newindent + off < 0) if (newindent + off < 0)
@@ -1994,6 +2053,7 @@ plines_win_col(wp, lnum, column)
char_u *s; char_u *s;
int lines = 0; int lines = 0;
int width; int width;
char_u *line;
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
/* Check for filler lines above this buffer line. When folded the result /* 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; return lines + 1;
#endif #endif
s = ml_get_buf(wp->w_buffer, lnum, FALSE); line = s = ml_get_buf(wp->w_buffer, lnum, FALSE);
col = 0; col = 0;
while (*s != NUL && --column >= 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); mb_ptr_adv(s);
} }
@@ -2026,7 +2086,7 @@ plines_win_col(wp, lnum, column)
* 'ts') -- webb. * 'ts') -- webb.
*/ */
if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1)) 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. * Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
@@ -9002,10 +9062,12 @@ get_lisp_indent()
amount = 2; amount = 2;
else else
{ {
char_u *line = that;
amount = 0; amount = 0;
while (*that && col) while (*that && col)
{ {
amount += lbr_chartabsize_adv(&that, (colnr_T)amount); amount += lbr_chartabsize_adv(line, &that, (colnr_T)amount);
col--; col--;
} }
@@ -9028,7 +9090,7 @@ get_lisp_indent()
while (vim_iswhite(*that)) while (vim_iswhite(*that))
{ {
amount += lbr_chartabsize(that, (colnr_T)amount); amount += lbr_chartabsize(line, that, (colnr_T)amount);
++that; ++that;
} }
@@ -9066,15 +9128,16 @@ get_lisp_indent()
&& !quotecount) && !quotecount)
--parencount; --parencount;
if (*that == '\\' && *(that+1) != NUL) if (*that == '\\' && *(that+1) != NUL)
amount += lbr_chartabsize_adv(&that, amount += lbr_chartabsize_adv(
(colnr_T)amount); line, &that, (colnr_T)amount);
amount += lbr_chartabsize_adv(&that, amount += lbr_chartabsize_adv(
(colnr_T)amount); line, &that, (colnr_T)amount);
} }
} }
while (vim_iswhite(*that)) while (vim_iswhite(*that))
{ {
amount += lbr_chartabsize(that, (colnr_T)amount); amount += lbr_chartabsize(
line, that, (colnr_T)amount);
that++; that++;
} }
if (!*that || *that == ';') if (!*that || *that == ';')

View File

@@ -201,10 +201,10 @@ coladvance2(pos, addspaces, finetune, wcol)
{ {
/* Count a tab for what it's worth (if list mode not on) */ /* Count a tab for what it's worth (if list mode not on) */
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
csize = win_lbr_chartabsize(curwin, ptr, col, &head); csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
mb_ptr_adv(ptr); mb_ptr_adv(ptr);
#else #else
csize = lbr_chartabsize_adv(&ptr, col); csize = lbr_chartabsize_adv(line, &ptr, col);
#endif #endif
col += csize; 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". * Append the text in "gap" below the cursor line and clear "gap".
*/ */

View File

@@ -420,7 +420,9 @@ shift_block(oap, amount)
} }
for ( ; vim_iswhite(*bd.textstart); ) 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; total += incr;
bd.start_vcol += incr; bd.start_vcol += incr;
} }
@@ -480,7 +482,7 @@ shift_block(oap, amount)
while (vim_iswhite(*non_white)) 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; non_white_col += incr;
} }
@@ -505,7 +507,11 @@ shift_block(oap, amount)
verbatim_copy_width -= bd.start_char_vcols; verbatim_copy_width -= bd.start_char_vcols;
while (verbatim_copy_width < destination_col) 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) if (verbatim_copy_width + incr > destination_col)
break; break;
verbatim_copy_width += incr; verbatim_copy_width += incr;
@@ -3617,7 +3623,7 @@ do_put(regname, dir, count, flags)
for (ptr = oldp; vcol < col && *ptr; ) for (ptr = oldp; vcol < col && *ptr; )
{ {
/* Count a tab for what it's worth (if list mode not on) */ /* 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; vcol += incr;
} }
bd.textcol = (colnr_T)(ptr - oldp); 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*/ /* calculate number of spaces required to fill right side of block*/
spaces = y_width + 1; spaces = y_width + 1;
for (j = 0; j < yanklen; j++) 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) if (spaces < 0)
spaces = 0; spaces = 0;
@@ -5203,7 +5209,7 @@ block_prep(oap, bdp, lnum, is_del)
while (bdp->start_vcol < oap->start_vcol && *pstart) while (bdp->start_vcol < oap->start_vcol && *pstart)
{ {
/* Count a tab for what it's worth (if list mode not on) */ /* 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; bdp->start_vcol += incr;
#ifdef FEAT_VISUALEXTRA #ifdef FEAT_VISUALEXTRA
if (vim_iswhite(*pstart)) 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) */ /* Count a tab for what it's worth (if list mode not on) */
prev_pend = pend; 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; bdp->end_vcol += incr;
} }
if (bdp->end_vcol <= oap->end_vcol if (bdp->end_vcol <= oap->end_vcol
@@ -6882,7 +6891,8 @@ cursor_pos_info()
validate_virtcol(); validate_virtcol();
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1, col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
(int)curwin->w_virtcol + 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 if (char_count_cursor == byte_count_cursor
&& char_count == byte_count) && char_count == byte_count)

View File

@@ -188,6 +188,10 @@
#ifdef FEAT_ARABIC #ifdef FEAT_ARABIC
# define PV_ARAB OPT_WIN(WV_ARAB) # define PV_ARAB OPT_WIN(WV_ARAB)
#endif #endif
#ifdef FEAT_LINEBREAK
# define PV_BRI OPT_WIN(WV_BRI)
# define PV_BRIOPT OPT_WIN(WV_BRIOPT)
#endif
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
# define PV_DIFF OPT_WIN(WV_DIFF) # define PV_DIFF OPT_WIN(WV_DIFF)
#endif #endif
@@ -646,6 +650,24 @@ static struct vimoption
#else #else
(char_u *)NULL, PV_NONE, (char_u *)NULL, PV_NONE,
{(char_u *)0L, (char_u *)0L} {(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 #endif
SCRIPTID_INIT}, SCRIPTID_INIT},
{"browsedir", "bsdir",P_STRING|P_VI_DEF, {"browsedir", "bsdir",P_STRING|P_VI_DEF,
@@ -5256,6 +5278,9 @@ didset_options()
/* set cedit_key */ /* set cedit_key */
(void)check_cedit(); (void)check_cedit();
#endif #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) *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
errmsg = (char_u *)N_("E589: 'backupext' and 'patchmode' are equal"); 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[] * '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); case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
case PV_LBR: return (char_u *)&(curwin->w_p_lbr); 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 #endif
#ifdef FEAT_SCROLLBIND #ifdef FEAT_SCROLLBIND
case PV_SCBIND: return (char_u *)&(curwin->w_p_scb); case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
@@ -10207,6 +10242,8 @@ copy_winopt(from, to)
#endif #endif
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
to->wo_lbr = from->wo_lbr; to->wo_lbr = from->wo_lbr;
to->wo_bri = from->wo_bri;
to->wo_briopt = vim_strsave(from->wo_briopt);
#endif #endif
#ifdef FEAT_SCROLLBIND #ifdef FEAT_SCROLLBIND
to->wo_scb = from->wo_scb; to->wo_scb = from->wo_scb;
@@ -10294,6 +10331,9 @@ check_winopt(wop)
#ifdef FEAT_CONCEAL #ifdef FEAT_CONCEAL
check_string_option(&wop->wo_cocu); check_string_option(&wop->wo_cocu);
#endif #endif
#ifdef FEAT_LINEBREAK
check_string_option(&wop->wo_briopt);
#endif
} }
/* /*
@@ -10313,6 +10353,9 @@ clear_winopt(wop)
# endif # endif
clear_string_option(&wop->wo_fmr); clear_string_option(&wop->wo_fmr);
#endif #endif
#ifdef FEAT_LINEBREAK
clear_string_option(&wop->wo_briopt);
#endif
#ifdef FEAT_RIGHTLEFT #ifdef FEAT_RIGHTLEFT
clear_string_option(&wop->wo_rlc); clear_string_option(&wop->wo_rlc);
#endif #endif
@@ -11927,3 +11970,49 @@ find_mps_values(initc, findc, backwards, switchit)
++ptr; ++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

View File

@@ -1052,6 +1052,10 @@ enum
#ifdef FEAT_CURSORBIND #ifdef FEAT_CURSORBIND
, WV_CRBIND , WV_CRBIND
#endif #endif
#ifdef FEAT_LINEBREAK
, WV_BRI
, WV_BRIOPT
#endif
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
, WV_DIFF , WV_DIFF
#endif #endif

View File

@@ -16,7 +16,7 @@ int vim_strnsize __ARGS((char_u *s, int len));
int chartabsize __ARGS((char_u *p, colnr_T col)); int chartabsize __ARGS((char_u *p, colnr_T col));
int linetabsize __ARGS((char_u *s)); int linetabsize __ARGS((char_u *s));
int linetabsize_col __ARGS((int startcol, 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_isIDc __ARGS((int c));
int vim_iswordc __ARGS((int c)); int vim_iswordc __ARGS((int c));
int vim_iswordc_buf __ARGS((int c, buf_T *buf)); 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_isfilec_or_wc __ARGS((int c));
int vim_isprintc __ARGS((int c)); int vim_isprintc __ARGS((int c));
int vim_isprintc_strict __ARGS((int c)); int vim_isprintc_strict __ARGS((int c));
int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col)); int lbr_chartabsize __ARGS((char_u *line, unsigned char *s, colnr_T col));
int lbr_chartabsize_adv __ARGS((char_u **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 *s, colnr_T col, int *headp)); 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)); 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)); 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)); colnr_T getvcol_nolist __ARGS((pos_T *posp));

View File

@@ -2,9 +2,10 @@
int get_indent __ARGS((void)); int get_indent __ARGS((void));
int get_indent_lnum __ARGS((linenr_T lnum)); int get_indent_lnum __ARGS((linenr_T lnum));
int get_indent_buf __ARGS((buf_T *buf, 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 set_indent __ARGS((int size, int flags));
int get_number_indent __ARGS((linenr_T lnum)); 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 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_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)); int get_last_leader_offset __ARGS((char_u *line, char_u **flags));

View File

@@ -63,4 +63,5 @@ int check_ff_value __ARGS((char_u *p));
long get_sw_value __ARGS((buf_T *buf)); long get_sw_value __ARGS((buf_T *buf));
long get_sts_value __ARGS((void)); long get_sts_value __ARGS((void));
void find_mps_values __ARGS((int *initc, int *findc, int *backwards, int switchit)); void find_mps_values __ARGS((int *initc, int *findc, int *backwards, int switchit));
int briopt_check __ARGS((void));
/* vim: set ft=c : */ /* vim: set ft=c : */

View File

@@ -2962,10 +2962,15 @@ win_line(wp, lnum, startrow, endrow, nochange)
# define WL_SIGN WL_FOLD /* column for signs */ # define WL_SIGN WL_FOLD /* column for signs */
#endif #endif
#define WL_NR WL_SIGN + 1 /* line number */ #define WL_NR WL_SIGN + 1 /* line number */
#if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF) #ifdef FEAT_LINEBREAK
# define WL_SBR WL_NR + 1 /* 'showbreak' or 'diff' */ # define WL_BRI WL_NR + 1 /* 'breakindent' */
#else #else
# define WL_SBR WL_NR # define WL_BRI WL_NR
#endif
#if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
# define WL_SBR WL_BRI + 1 /* 'showbreak' or 'diff' */
#else
# define WL_SBR WL_BRI
#endif #endif
#define WL_LINE WL_SBR + 1 /* text in the line */ #define WL_LINE WL_SBR + 1 /* text in the line */
int draw_state = WL_START; /* what to draw next */ int draw_state = WL_START; /* what to draw next */
@@ -3301,7 +3306,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
#endif #endif
while (vcol < v && *ptr != NUL) 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; vcol += c;
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
prev_ptr = ptr; 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 && n_extra == 0)
/* After the showbreak, draw the breakindent */
draw_state = WL_BRI - 1;
/* draw 'breakindent': indent wrapped text accordingly */
if (draw_state == WL_BRI - 1 && n_extra == 0)
{
draw_state = WL_BRI;
# ifdef FEAT_DIFF
# endif
if (wp->w_p_bri && n_extra == 0 && row != startrow
#ifdef FEAT_DIFF
&& filler_lines == 0
#endif
)
{
char_attr = 0; /* was: hl_attr(HLF_AT); */
#ifdef FEAT_DIFF
if (diff_hlf != (hlf_T)0)
char_attr = hl_attr(diff_hlf);
#endif
p_extra = NUL;
c_extra = ' ';
n_extra = get_breakindent_win(wp,
ml_get_buf(wp->w_buffer, lnum, FALSE));
/* 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 defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
if (draw_state == WL_SBR - 1 && n_extra == 0) if (draw_state == WL_SBR - 1 && n_extra == 0)
{ {
@@ -4382,11 +4425,14 @@ win_line(wp, lnum, startrow, endrow, nochange)
if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr) if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)
&& !wp->w_p_list) && !wp->w_p_list)
{ {
n_extra = win_lbr_chartabsize(wp, ptr - ( char_u *p = ptr - (
# ifdef FEAT_MBYTE # ifdef FEAT_MBYTE
has_mbyte ? mb_l : has_mbyte ? mb_l :
# endif # endif
1), (colnr_T)vcol, NULL) - 1; 1);
/* TODO: is passing p for start of the line OK? */
n_extra = win_lbr_chartabsize(wp, p, p, (colnr_T)vcol,
NULL) - 1;
c_extra = ' '; c_extra = ' ';
if (vim_iswhite(c)) if (vim_iswhite(c))
{ {
@@ -8916,8 +8962,8 @@ windgoto(row, col)
{ {
if (noinvcurs) if (noinvcurs)
screen_stop_highlight(); screen_stop_highlight();
if (row == screen_cur_row && (col > screen_cur_col) && if (row == screen_cur_row && (col > screen_cur_col)
*T_CRI != NUL) && *T_CRI != NUL)
term_cursor_right(col - screen_cur_col); term_cursor_right(col - screen_cur_col);
else else
term_windgoto(row, col); term_windgoto(row, col);

View File

@@ -134,6 +134,12 @@ typedef struct
int wo_arab; int wo_arab;
# define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */ # define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */
#endif #endif
#ifdef FEAT_LINEBREAK
int wo_bri;
# define w_p_bri w_onebuf_opt.wo_bri /* 'breakindent' */
char_u *wo_briopt;
# define w_p_briopt w_onebuf_opt.wo_briopt /* 'breakindentopt' */
#endif
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
int wo_diff; int wo_diff;
# define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */ # define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */
@@ -2189,6 +2195,11 @@ struct window_S
#ifdef FEAT_SYN_HL #ifdef FEAT_SYN_HL
int *w_p_cc_cols; /* array of columns to highlight or NULL */ int *w_p_cc_cols; /* array of columns to highlight or NULL */
#endif #endif
#ifdef FEAT_LINEBREAK
int w_p_brimin; /* minimum width for breakindent */
int w_p_brishift; /* additional shift for breakindent */
int w_p_brisbr; /* sbr in 'briopt' */
#endif
/* transform a pointer to a "onebuf" option into a "allbuf" option */ /* transform a pointer to a "onebuf" option into a "allbuf" option */
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T)) #define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))

View File

@@ -37,6 +37,7 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
test99.out test100.out test101.out test102.out test103.out \ test99.out test100.out test101.out test102.out test103.out \
test104.out test105.out test106.out test107.out \ test104.out test105.out test106.out test107.out \
test_autoformat_join.out \ test_autoformat_join.out \
test_breakindent.out \
test_eval.out \ test_eval.out \
test_options.out test_options.out
@@ -163,5 +164,6 @@ test105.out: test105.in
test106.out: test106.in test106.out: test106.in
test107.out: test107.in test107.out: test107.in
test_autoformat_join.out: test_autoformat_join.in test_autoformat_join.out: test_autoformat_join.in
test_breakindent.out: test_breakindent.in
test_eval.out: test_eval.in test_eval.out: test_eval.in
test_options.out: test_options.in test_options.out: test_options.in

View File

@@ -36,6 +36,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test100.out test101.out test102.out test103.out test104.out \ test100.out test101.out test102.out test103.out test104.out \
test105.out test106.out test107.out\ test105.out test106.out test107.out\
test_autoformat_join.out \ test_autoformat_join.out \
test_breakindent.out \
test_eval.out \ test_eval.out \
test_options.out test_options.out

View File

@@ -56,6 +56,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test100.out test101.out test102.out test103.out test104.out \ test100.out test101.out test102.out test103.out test104.out \
test105.out test106.out test107.out \ test105.out test106.out test107.out \
test_autoformat_join.out \ test_autoformat_join.out \
test_breakindent.out \
test_eval.out \ test_eval.out \
test_options.out test_options.out

View File

@@ -39,6 +39,7 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
test105.out test106.out test107.out \ test105.out test106.out test107.out \
test_autoformat_join.out \ test_autoformat_join.out \
test_eval.out \ test_eval.out \
test_breakindent.out \
test_options.out test_options.out
.SUFFIXES: .in .out .SUFFIXES: .in .out

View File

@@ -97,6 +97,7 @@ SCRIPT = test1.out test2.out test3.out test4.out test5.out \
test100.out test101.out test103.out test104.out \ test100.out test101.out test103.out test104.out \
test105.out test106.out test107.out \ test105.out test106.out test107.out \
test_autoformat_join.out \ test_autoformat_join.out \
test_breakindent.out \
test_eval.out \ test_eval.out \
test_options.out test_options.out

View File

@@ -34,6 +34,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
test99.out test100.out test101.out test102.out test103.out \ test99.out test100.out test101.out test102.out test103.out \
test104.out test105.out test106.out test107.out \ test104.out test105.out test106.out test107.out \
test_autoformat_join.out \ test_autoformat_join.out \
test_breakindent.out \
test_eval.out \ test_eval.out \
test_options.out test_options.out

View File

@@ -0,0 +1,79 @@
Test for breakindent
STARTTEST
:so small.vim
:if !exists("+breakindent") | e! test.ok | w! test.out | qa! | endif
:10new|:vsp|:vert resize 20
:put =\"\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\"
:set ts=4 sw=4 sts=4 breakindent
:fu! ScreenChar(width)
: let c=''
: for i in range(1,a:width)
: let c.=nr2char(screenchar(line('.'), i))
: endfor
: let c.="\n"
: for i in range(1,a:width)
: let c.=nr2char(screenchar(line('.')+1, i))
: endfor
: let c.="\n"
: for i in range(1,a:width)
: let c.=nr2char(screenchar(line('.')+2, i))
: endfor
: return c
:endfu
:fu DoRecordScreen()
: wincmd l
: $put =printf(\"\n%s\", g:test)
: $put =g:line1
: wincmd p
:endfu
:let g:test="Test 1: Simple breakindent"
:let line1=ScreenChar(8)
:call DoRecordScreen()
:let g:test="Test 2: Simple breakindent + sbr=>>"
:set sbr=>>
:let line1=ScreenChar(8)
:call DoRecordScreen()
:let g:test ="Test 3: Simple breakindent + briopt:sbr"
:set briopt=sbr,min:0 sbr=++
:let line1=ScreenChar(8)
:call DoRecordScreen()
:let g:test ="Test 4: Simple breakindent + min width: 18"
:set sbr= briopt=min:18
:let line1=ScreenChar(8)
:call DoRecordScreen()
:let g:test =" Test 5: Simple breakindent + shift by 2"
:set briopt=shift:2,min:0
:let line1=ScreenChar(8)
:call DoRecordScreen()
:let g:test=" Test 6: Simple breakindent + shift by -1"
:set briopt=shift:-1,min:0
:let line1=ScreenChar(8)
:call DoRecordScreen()
:let g:test=" Test 7: breakindent + shift by +1 + nu + sbr=? briopt:sbr"
:set briopt=shift:1,sbr,min:0 nu sbr=? nuw=4
:let line1=ScreenChar(10)
:call DoRecordScreen()
:let g:test=" Test 8: breakindent + shift:1 + nu + sbr=# list briopt:sbr"
:set briopt=shift:1,sbr,min:0 nu sbr=# list
:let line1=ScreenChar(10)
:call DoRecordScreen()
:let g:test=" Test 9: breakindent + shift by +1 + 'nu' + sbr=# list"
:set briopt-=sbr
:let line1=ScreenChar(10)
:call DoRecordScreen()
:let g:test=" Test 10: breakindent + shift by +1 + 'nu' + sbr=~ cpo+=n"
:set cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0
:let line1=ScreenChar(10)
:call DoRecordScreen()
:wincmd p
:let g:test="\n Test 11: strdisplaywidth when breakindent is on"
:set cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4
:let text=getline(2) "skip leading tab when calculating text width
:let width = strlen(text[1:])+indent(2)*4+strlen(&sbr)*3 " text wraps 3 times
:$put =g:test
:$put =printf(\"strdisplaywidth: %d == calculated: %d\", strdisplaywidth(text), width)
:%w! test.out
:qa!
ENDTEST
dummy text

View File

@@ -0,0 +1,55 @@
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP
Test 1: Simple breakindent
abcd
qrst
GHIJ
Test 2: Simple breakindent + sbr=>>
abcd
>>qr
>>EF
Test 3: Simple breakindent + briopt:sbr
abcd
++ qrst
++ GHIJ
Test 4: Simple breakindent + min width: 18
abcd
qrstuv
IJKLMN
Test 5: Simple breakindent + shift by 2
abcd
qr
EF
Test 6: Simple breakindent + shift by -1
abcd
qrstu
HIJKL
Test 7: breakindent + shift by +1 + nu + sbr=? briopt:sbr
2 ab
? m
? x
Test 8: breakindent + shift:1 + nu + sbr=# list briopt:sbr
2 ^Iabcd
# opq
# BCD
Test 9: breakindent + shift by +1 + 'nu' + sbr=# list
2 ^Iabcd
#op
#AB
Test 10: breakindent + shift by +1 + 'nu' + sbr=~ cpo+=n
2 ab
~ mn
~ yz
Test 11: strdisplaywidth when breakindent is on
strdisplaywidth: 46 == calculated: 64

View File

@@ -3162,15 +3162,15 @@ vcol2col(wp, lnum, vcol)
/* try to advance to the specified column */ /* try to advance to the specified column */
int count = 0; int count = 0;
char_u *ptr; char_u *ptr;
char_u *start; char_u *line;
start = ptr = ml_get_buf(wp->w_buffer, lnum, FALSE); line = ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
while (count < vcol && *ptr != NUL) while (count < vcol && *ptr != NUL)
{ {
count += win_lbr_chartabsize(wp, ptr, count, NULL); count += win_lbr_chartabsize(wp, line, ptr, count, NULL);
mb_ptr_adv(ptr); mb_ptr_adv(ptr);
} }
return (int)(ptr - start); return (int)(ptr - line);
} }
#endif #endif

View File

@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
338,
/**/ /**/
337, 337,
/**/ /**/