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.
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|.

View File

@@ -324,6 +324,12 @@ call <SID>BinOptionG("wrap", &wrap)
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("$", "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 <SID>OptionG("brk", &brk)
call append("$", "showbreak\tstring to put before wrapped screen lines")

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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 */
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 == ';')

View File

@@ -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".
*/

View File

@@ -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)

View File

@@ -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
@@ -646,6 +650,24 @@ static struct vimoption
#else
(char_u *)NULL, PV_NONE,
{(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,
@@ -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

View File

@@ -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

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 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));

View File

@@ -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));

View File

@@ -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 : */

View File

@@ -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 */
#if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
# define WL_SBR WL_NR + 1 /* 'showbreak' or 'diff' */
#ifdef FEAT_LINEBREAK
# define WL_BRI WL_NR + 1 /* 'breakindent' */
#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
#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 && 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 (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)
&& !wp->w_p_list)
{
n_extra = win_lbr_chartabsize(wp, ptr - (
char_u *p = ptr - (
# ifdef FEAT_MBYTE
has_mbyte ? mb_l :
# 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 = ' ';
if (vim_iswhite(c))
{
@@ -8916,8 +8962,8 @@ windgoto(row, col)
{
if (noinvcurs)
screen_stop_highlight();
if (row == screen_cur_row && (col > screen_cur_col) &&
*T_CRI != NUL)
if (row == screen_cur_row && (col > screen_cur_col)
&& *T_CRI != NUL)
term_cursor_right(col - screen_cur_col);
else
term_windgoto(row, col);

View File

@@ -134,6 +134,12 @@ typedef struct
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' */
char_u *wo_briopt;
# define w_p_briopt w_onebuf_opt.wo_briopt /* 'breakindentopt' */
#endif
#ifdef FEAT_DIFF
int wo_diff;
# define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */
@@ -2189,6 +2195,11 @@ struct window_S
#ifdef FEAT_SYN_HL
int *w_p_cc_cols; /* array of columns to highlight or NULL */
#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 */
#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 \
test104.out test105.out test106.out test107.out \
test_autoformat_join.out \
test_breakindent.out \
test_eval.out \
test_options.out
@@ -163,5 +164,6 @@ test105.out: test105.in
test106.out: test106.in
test107.out: test107.in
test_autoformat_join.out: test_autoformat_join.in
test_breakindent.out: test_breakindent.in
test_eval.out: test_eval.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 \
test105.out test106.out test107.out\
test_autoformat_join.out \
test_breakindent.out \
test_eval.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 \
test105.out test106.out test107.out \
test_autoformat_join.out \
test_breakindent.out \
test_eval.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 \
test_autoformat_join.out \
test_eval.out \
test_breakindent.out \
test_options.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 \
test105.out test106.out test107.out \
test_autoformat_join.out \
test_breakindent.out \
test_eval.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 \
test104.out test105.out test106.out test107.out \
test_autoformat_join.out \
test_breakindent.out \
test_eval.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 */
int count = 0;
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)
{
count += win_lbr_chartabsize(wp, ptr, count, NULL);
count += win_lbr_chartabsize(wp, line, ptr, count, NULL);
mb_ptr_adv(ptr);
}
return (int)(ptr - start);
return (int)(ptr - line);
}
#endif

View File

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