Skip to content

Instantly share code, notes, and snippets.

@shirosaki
Last active December 18, 2015 02:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shirosaki/5710831 to your computer and use it in GitHub Desktop.
Save shirosaki/5710831 to your computer and use it in GitHub Desktop.
Update for Vim v7-4a-024 of https://retracile.net/wiki/VimBreakIndent
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -6399,18 +6399,18 @@ gui_win32s idem, and Win32s system bein
hangul_input Compiled with Hangul input support. |hangul|
iconv Can use iconv() for conversion.
insert_expand Compiled with support for CTRL-X expansion commands in
Insert mode.
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|.
localmap Compiled with local mappings and abbr. |:map-local|
lua Compiled with Lua interface |Lua|.
mac Macintosh version of Vim.
macunix Macintosh version of Vim, using Unix files (OS-X).
menu Compiled with support for |:menu|.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1195,16 +1195,48 @@ A jump table for the options with a shor
global
{not in Vi}
{not available when compiled without the |+linebreak|
feature}
This option lets you choose which characters might cause a line
break if 'linebreak' is on. Only works for ASCII and also for 8-bit
characters when 'encoding' is an 8-bit encoding.
+ *'breakindent'* *'bri'*
+'breakindent' 'bri' boolean (default off)
+ local to window
+ {not in Vi}
+ {not available when compiled without the |+linebreak|
+ feature}
+ Every wrapped line will continue visually indented (same amount of
+ space as the beginning of that line), thus preserving horizontal blocks
+ of text.
+
+ *'breakindentmin'* *'brimin'*
+'breakindentmin' 'brimin' number (default 20)
+ local to window
+ {not in Vi}
+ {not available when compiled without the |+linebreak|
+ feature}
+ Minimum text width that will be kept after applying 'breakindent',
+ even if the resulting text should normally be narrower. This prevents
+ text indented almost to the right window border oocupying lot of
+ vertical space when broken.
+
+ *'breakindentshift'* *'brishift'*
+'breakindentshift' 'brishift' number (default 20)
+ local to window
+ {not in Vi}
+ {not available when compiled without the |+linebreak|
+ feature}
+ After applying 'breakindent', wrapped line beginning will be shift by
+ given number of characters. It permits dynamic French paragraph
+ indentation (negative) or emphasizing the line continuation
+ (positive).
+
*'browsedir'* *'bsdir'*
'browsedir' 'bsdir' string (default: "last")
global
{not in Vi} {only for Motif, Athena, GTK, Mac and
Win32 GUI}
Which directory to use for the file browser:
last Use same directory as with last file browser, where a
file was opened or saved.
@@ -4567,22 +4599,23 @@ A jump table for the options with a shor
update use |:redraw|.
*'linebreak'* *'lbr'* *'nolinebreak'* *'nolbr'*
'linebreak' 'lbr' boolean (default off)
local to window
{not in Vi}
{not available when compiled without the |+linebreak|
feature}
- If on Vim will wrap long lines at a character in 'breakat' rather
+ If on, Vim will wrap long lines at a character in 'breakat' rather
than at the last character that fits on the screen. Unlike
'wrapmargin' and 'textwidth', this does not insert <EOL>s in the file,
- it only affects the way the file is displayed, not its contents. The
- value of 'showbreak' is used to put in front of wrapped lines.
- This option is not used when the 'wrap' option is off or 'list' is on.
+ it only affects the way the file is displayed, not its contents.
+ If 'breakindent' is set, line is visually indented. Then, the value
+ of 'showbreak' is used to put in front of wrapped lines. This option
+ is not used when the 'wrap' option is off or 'list' is on.
Note that <Tab> characters after an <EOL> are mostly not displayed
with the right amount of white space.
*'lines'* *E593*
'lines' number (default 24 or terminal height)
global
Number of lines of the Vim window.
Normally you don't need to set this. It is done automatically by the
diff --git a/runtime/doc/tags b/runtime/doc/tags
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -85,16 +85,22 @@
'binary' options.txt /*'binary'*
'biosk' options.txt /*'biosk'*
'bioskey' options.txt /*'bioskey'*
'bk' options.txt /*'bk'*
'bkc' options.txt /*'bkc'*
'bl' options.txt /*'bl'*
'bomb' options.txt /*'bomb'*
'breakat' options.txt /*'breakat'*
+'breakindent' options.txt /*'breakindent'*
+'breakindentmin' options.txt /*'breakindentmin'*
+'breakindentshift' options.txt /*'breakindentshift'*
+'bri' options.txt /*'bri'*
+'brimin' options.txt /*'brimin'*
+'brishift' options.txt /*'brishift'*
'brk' options.txt /*'brk'*
'browsedir' options.txt /*'browsedir'*
'bs' options.txt /*'bs'*
'bsdir' options.txt /*'bsdir'*
'bsk' options.txt /*'bsk'*
'bt' options.txt /*'bt'*
'bufhidden' options.txt /*'bufhidden'*
'buflisted' options.txt /*'buflisted'*
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -319,16 +319,25 @@ call append("$", "\t(local to window)")
call <SID>OptionL("scr")
call append("$", "scrolloff\tnumber of screen lines to show around the cursor")
call append("$", " \tset so=" . &so)
call append("$", "wrap\tlong lines wrap")
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("$", "breakindentmin\tminimum text width after indent in 'breakindent'")
+call append("$", "\t(local to window)")
+call <SID>OptionL("brimin")
+call append("$", "breakindentshift\tshift beginning of 'breakindent'ed line by this number of characters (negative left)")
+call append("$", "\t(local to window)")
+call <SID>OptionL("brishift")
call append("$", "breakat\twhich characters might cause a line break")
call <SID>OptionG("brk", &brk)
call append("$", "showbreak\tstring to put before wrapped screen lines")
call <SID>OptionG("sbr", &sbr)
call append("$", "sidescroll\tminimal number of columns to scroll horizontally")
call append("$", " \tset ss=" . &ss)
call append("$", "sidescrolloff\tminimal number of columns to keep left and right of the cursor")
call append("$", " \tset siso=" . &siso)
diff --git a/src/charset.c b/src/charset.c
--- a/src/charset.c
+++ b/src/charset.c
@@ -847,51 +847,54 @@ win_chartabsize(wp, p, col)
}
#endif
/*
* Return the number of characters the string 's' will take on the screen,
* taking into account the size of a tab.
*/
int
-linetabsize(s)
+linetabsize(s, lnum)
char_u *s;
+ linenr_T lnum;
{
- return linetabsize_col(0, s);
+ return linetabsize_col(0, s, lnum);
}
/*
* Like linetabsize(), but starting at column "startcol".
*/
int
-linetabsize_col(startcol, s)
+linetabsize_col(startcol, s, lnum)
int startcol;
char_u *s;
+ linenr_T lnum;
{
colnr_T col = startcol;
while (*s != NUL)
- col += lbr_chartabsize_adv(&s, col);
+ col += lbr_chartabsize_adv(&s, col, lnum);
return (int)col;
}
/*
* Like linetabsize(), but for a given window instead of the current one.
*/
int
-win_linetabsize(wp, p, len)
+win_linetabsize(wp, p, len, lnum)
win_T *wp;
char_u *p;
colnr_T len;
+ linenr_T lnum;
{
colnr_T col = 0;
char_u *s;
for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s))
- col += win_lbr_chartabsize(wp, s, col, NULL);
+ col += win_lbr_chartabsize(wp, s, col, NULL, lnum);
return (int)col;
}
/*
* Return TRUE if 'c' is a normal identifier character:
* Letters and characters from the 'isident' option.
*/
int
@@ -1016,63 +1019,69 @@ vim_isprintc_strict(c)
#endif
return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
}
/*
* like chartabsize(), but also check for line breaks on the screen
*/
int
-lbr_chartabsize(s, col)
+lbr_chartabsize(s, col, lnum)
unsigned char *s;
colnr_T col;
+ linenr_T lnum;
{
#ifdef FEAT_LINEBREAK
- if (!curwin->w_p_lbr && *p_sbr == NUL)
+ if (!curwin->w_p_lbr && *p_sbr == NUL && !curwin->w_p_bri)
{
#endif
#ifdef FEAT_MBYTE
if (curwin->w_p_wrap)
return win_nolbr_chartabsize(curwin, s, col, NULL);
#endif
RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
#ifdef FEAT_LINEBREAK
}
- return win_lbr_chartabsize(curwin, s, col, NULL);
+ return win_lbr_chartabsize(curwin, s, col, NULL, lnum);
#endif
}
/*
* Call lbr_chartabsize() and advance the pointer.
*/
int
-lbr_chartabsize_adv(s, col)
+lbr_chartabsize_adv(s, col, lnum)
char_u **s;
colnr_T col;
+ linenr_T lnum;
{
int retval;
- retval = lbr_chartabsize(*s, col);
+ retval = lbr_chartabsize(*s, col, lnum);
mb_ptr_adv(*s);
return retval;
}
/*
* This function is used very often, keep it fast!!!!
*
* If "headp" not NULL, set *headp to the size of what we for 'showbreak'
* string at start of line. Warning: *headp is only set if it's a non-zero
* value, init to 0 before calling.
+ *
+ * linenr argument needed if in visual highlighting and breakindent=on, then
+ * the line calculated is not current; if 0, normal functionality is preserved.
*/
int
-win_lbr_chartabsize(wp, s, col, headp)
+win_lbr_chartabsize(wp, s, col, headp, lnum)
win_T *wp;
char_u *s;
colnr_T col;
int *headp UNUSED;
+ linenr_T lnum;
{
#ifdef FEAT_LINEBREAK
int c;
int size;
colnr_T col2;
colnr_T colmax;
int added;
# ifdef FEAT_MBYTE
@@ -1081,19 +1090,19 @@ win_lbr_chartabsize(wp, s, col, headp)
# define mb_added 0
# endif
int numberextra;
char_u *ps;
int tab_corr = (*s == TAB);
int n;
/*
- * No 'linebreak' and 'showbreak': return quickly.
+ * No 'linebreak' and 'showbreak' and 'breakindent': return quickly.
*/
- if (!wp->w_p_lbr && *p_sbr == NUL)
+ if (!wp->w_p_lbr && !wp->w_p_bri && *p_sbr == NUL)
#endif
{
#ifdef FEAT_MBYTE
if (wp->w_p_wrap)
return win_nolbr_chartabsize(wp, s, col, headp);
#endif
RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
}
@@ -1158,34 +1167,40 @@ win_lbr_chartabsize(wp, s, col, headp)
&& wp->w_p_wrap && in_win_border(wp, col))
{
++size; /* Count the ">" in the last column. */
mb_added = 1;
}
# 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;
if (col >= (colnr_T)W_WIDTH(wp))
{
col -= W_WIDTH(wp);
numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
if (numberextra > 0)
col = col % numberextra;
}
if (col == 0 || col + size > (colnr_T)W_WIDTH(wp))
{
- added = vim_strsize(p_sbr);
+ added = 0;
+ if (*p_sbr != NUL)
+ added += vim_strsize(p_sbr);
+ if (wp->w_p_bri)
+ added += get_breakindent_win(wp,lnum);
+
if (tab_corr)
size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
else
size += added;
if (col != 0)
added = 0;
}
}
@@ -1283,22 +1298,23 @@ getvcol(wp, pos, start, cursor, end)
ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
if (pos->col == MAXCOL)
posptr = NULL; /* continue until the NUL */
else
posptr = ptr + pos->col;
/*
* 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
)
{
#ifndef FEAT_MBYTE
head = 0;
#endif
for (;;)
{
@@ -1350,17 +1366,17 @@ getvcol(wp, pos, start, cursor, end)
}
}
else
{
for (;;)
{
/* A tab gets expanded, depending on the current column */
head = 0;
- incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
+ incr = win_lbr_chartabsize(wp, ptr, vcol, &head, pos->lnum);
/* make sure we don't go past the end of the line */
if (*ptr == NUL)
{
incr = 1; /* NUL at end of line only takes one column */
break;
}
if (posptr != NULL && ptr >= posptr) /* character at pos->col */
diff --git a/src/edit.c b/src/edit.c
--- a/src/edit.c
+++ b/src/edit.c
@@ -423,17 +423,17 @@ edit(cmdchar, startln, count)
Insstart = where_paste_started;
else
#endif
{
Insstart = curwin->w_cursor;
if (startln)
Insstart.col = 0;
}
- Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
+ Insstart_textlen = (colnr_T)linetabsize(ml_get_curline(), Insstart.lnum);
Insstart_blank_vcol = MAXCOL;
if (!did_ai)
ai_col = 0;
if (cmdchar != NUL && restart_edit == 0)
{
ResetRedobuff();
AppendNumberToRedobuff(count);
@@ -1946,17 +1946,17 @@ change_indent(type, amount, round, repla
{
last_vcol = vcol;
#ifdef FEAT_MBYTE
if (has_mbyte && new_cursor_col >= 0)
new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col);
else
#endif
++new_cursor_col;
- vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_T)vcol);
+ vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_T)vcol, curwin->w_cursor.lnum);
}
vcol = last_vcol;
/*
* May need to insert spaces to be able to position the cursor on
* the right screen column.
*/
if (vcol != (int)curwin->w_virtcol)
@@ -6738,17 +6738,17 @@ stop_arrow()
if (arrow_used)
{
if (u_save_cursor() == OK)
{
arrow_used = FALSE;
ins_need_undo = FALSE;
}
Insstart = curwin->w_cursor; /* new insertion starts here */
- Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
+ Insstart_textlen = (colnr_T)linetabsize(ml_get_curline(), curwin->w_cursor.lnum);
ai_col = 0;
#ifdef FEAT_VREPLACE
if (State & VREPLACE_FLAG)
{
orig_line_count = curbuf->b_ml.ml_line_count;
vr_lines_changed = 1;
}
#endif
@@ -7093,19 +7093,20 @@ oneleft()
return FAIL;
# ifdef FEAT_LINEBREAK
/* We might get stuck on 'showbreak', skip over it. */
width = 1;
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
) || getviscol() < v)
break;
++width;
}
# else
@@ -9735,21 +9736,21 @@ ins_tab()
ptr += Insstart.col - fpos.col;
fpos.col = Insstart.col;
}
/* compute virtual column numbers of first white and cursor */
getvcol(curwin, &fpos, &vcol, NULL, NULL);
getvcol(curwin, cursor, &want_vcol, NULL, NULL);
- /* Use as many TABs as possible. Beware of 'showbreak' and
+ /* Use as many TABs as possible. Beware of 'breakindent', 'showbreak' and
* 'linebreak' adding extra virtual columns. */
while (vim_iswhite(*ptr))
{
- i = lbr_chartabsize((char_u *)"\t", vcol);
+ i = lbr_chartabsize((char_u *)"\t", vcol, cursor->lnum);
if (vcol + i > want_vcol)
break;
if (*ptr != TAB)
{
*ptr = TAB;
if (change_col < 0)
{
change_col = fpos.col; /* Column of first change */
@@ -9765,17 +9766,17 @@ ins_tab()
if (change_col >= 0)
{
int repl_off = 0;
/* Skip over the spaces we need. */
while (vcol < want_vcol && *ptr == ' ')
{
- vcol += lbr_chartabsize(ptr, vcol);
+ vcol += lbr_chartabsize(ptr, vcol, cursor->lnum);
++ptr;
++repl_off;
}
if (vcol > want_vcol)
{
/* Must have a char with 'showbreak' just before it. */
--ptr;
--repl_off;
@@ -10021,17 +10022,17 @@ ins_copychar(lnum)
/* try to advance to the cursor column */
temp = 0;
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(&ptr, (colnr_T)temp, lnum);
}
if ((colnr_T)temp > curwin->w_virtcol)
ptr = prev_ptr;
#ifdef FEAT_MBYTE
c = (*mb_ptr2char)(ptr);
#else
c = *ptr;
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -17561,18 +17561,21 @@ f_strdisplaywidth(argvars, rettv)
typval_T *argvars;
typval_T *rettv;
{
char_u *s = get_tv_string(&argvars[0]);
int col = 0;
if (argvars[1].v_type != VAR_UNKNOWN)
col = get_tv_number(&argvars[1]);
-
- rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col);
+ /*
+ * FIXME: passing 0 as 3rd argument to linetabsize_col, instead of real line number;
+ * (can we get it from here somehow?); might give incorrect result with breakindent!
+ */
+ rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s, 0) - col);
}
/*
* "strwidth()" function
*/
static void
f_strwidth(argvars, rettv)
typval_T *argvars;
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -256,17 +256,17 @@ linelen(has_tab)
first = skipwhite(line);
/* find the character after the last non-blank character */
for (last = first + STRLEN(first);
last > first && vim_iswhite(last[-1]); --last)
;
save = *last;
*last = NUL;
- len = linetabsize(line); /* get line length */
+ len = linetabsize(line, curwin->w_cursor.lnum); /* get line length */
if (has_tab != NULL) /* check for embedded TAB */
*has_tab = (vim_strrchr(first, TAB) != NULL);
*last = save;
return len;
}
/* Buffer for two lines used during sorting. They are allocated to
diff --git a/src/getchar.c b/src/getchar.c
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -2628,17 +2628,17 @@ vgetorpeek(advance)
*/
col = vcol = curwin->w_wcol = 0;
ptr = ml_get_curline();
while (col < curwin->w_cursor.col)
{
if (!vim_iswhite(ptr[col]))
curwin->w_wcol = vcol;
vcol += lbr_chartabsize(ptr + col,
- (colnr_T)vcol);
+ (colnr_T)vcol, curwin->w_cursor.lnum);
#ifdef FEAT_MBYTE
if (has_mbyte)
col += (*mb_ptr2len)(ptr + col);
else
#endif
++col;
}
curwin->w_wrow = curwin->w_cline_row
diff --git a/src/gui_beval.c b/src/gui_beval.c
--- a/src/gui_beval.c
+++ b/src/gui_beval.c
@@ -330,17 +330,17 @@ get_beval_info(beval, getword, winp, lnu
if (wp != NULL && row < wp->w_height && col < W_WIDTH(wp))
{
/* Found a window and the cursor is in the text. Now find the line
* number. */
if (!mouse_comp_pos(wp, &row, &col, &lnum))
{
/* Not past end of the file. */
lbuf = ml_get_buf(wp->w_buffer, lnum, FALSE);
- if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL))
+ if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL, lnum))
{
/* Not past end of line. */
if (getword)
{
/* For Netbeans we get the relevant part of the line
* instead of the whole line. */
int len;
pos_T *spos = NULL, *epos = NULL;
diff --git a/src/misc1.c b/src/misc1.c
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -463,16 +463,53 @@ get_number_indent(lnum)
}
if (pos.lnum == 0 || *ml_get_pos(&pos) == NUL)
return -1;
getvcol(curwin, &pos, &col, NULL, NULL);
return (int)col;
}
+#ifdef FEAT_LINEBREAK
+/*
+ * Return appropriate space number for breakindent, taking influencing
+ * parameters into account. Window must be specified, since it is not
+ * necessarily always the current one. If lnum==0, current line is calculated,
+ * specified line otherwise.
+ */
+ int
+get_breakindent_win(wp,lnum)
+ win_T* wp;
+ linenr_T lnum;
+{
+ int bri;
+ /* window width minus barren space, i.e. what rests for text */
+ const int eff_wwidth = W_WIDTH(wp)
+ - (wp->w_p_nu && !vim_strchr(p_cpo,CPO_NUMCOL) ? number_width(wp) : 0);
+ /* - (*p_sbr == NUL ? 0 : vim_strsize(p_sbr)); */
+
+ bri = get_indent_buf(wp->w_buffer,lnum?lnum:wp->w_cursor.lnum) + wp->w_p_brishift;
+
+ /* if numbering and 'c' in 'cpoptions', cancel it out effectively */
+ /* (this could be replaced by an equivalent call to win_col_off2()) */
+ if (curwin->w_p_nu && vim_strchr(p_cpo, CPO_NUMCOL))
+ bri += number_width(wp);
+
+ /* never indent past left window margin */
+ if (bri < 0)
+ bri = 0;
+ /* always leave at least bri_min characters on the left,
+ * if text width is sufficient */
+ else if (bri > eff_wwidth - wp->w_p_brimin)
+ bri = eff_wwidth - wp->w_p_brimin < 0 ? 0 : eff_wwidth - wp->w_p_brimin;
+
+ return bri;
+}
+#endif
+
#if defined(FEAT_CINDENT) || defined(FEAT_SMARTINDENT)
static int cin_is_cinword __ARGS((char_u *line));
/*
* Return TRUE if the string "line" starts with a word from 'cinwords'.
*/
static int
@@ -1945,17 +1982,17 @@ plines_win_nofold(wp, lnum)
{
char_u *s;
long col;
int width;
s = ml_get_buf(wp->w_buffer, lnum, FALSE);
if (*s == NUL) /* empty line */
return 1;
- col = win_linetabsize(wp, s, (colnr_T)MAXCOL);
+ col = win_linetabsize(wp, s, (colnr_T)MAXCOL, lnum);
/*
* If list mode is on, then the '$' at the end of the line may take up one
* extra column.
*/
if (wp->w_p_list && lcs_eol != NUL)
col += 1;
@@ -2001,29 +2038,29 @@ plines_win_col(wp, lnum, column)
return lines + 1;
#endif
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, s, (colnr_T)col, NULL, lnum);
mb_ptr_adv(s);
}
/*
* If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
* INSERT mode, then col must be adjusted so that it represents the last
* screen position of the TAB. This only fixes an error when the TAB wraps
* from one screen line to the next (when 'columns' is not a multiple of
* 'ts') -- webb.
*/
if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1))
- col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL) - 1;
+ col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL, lnum) - 1;
/*
* Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
*/
width = W_WIDTH(wp) - win_col_off(wp);
if (width <= 0)
return 9999;
@@ -9044,17 +9081,17 @@ get_lisp_indent()
if (vi_lisp && get_indent() == 0)
amount = 2;
else
{
amount = 0;
while (*that && col)
{
- amount += lbr_chartabsize_adv(&that, (colnr_T)amount);
+ amount += lbr_chartabsize_adv(&that, (colnr_T)amount, pos->lnum);
col--;
}
/*
* Some keywords require "body" indenting rules (the
* non-standard-lisp ones are Scheme special forms):
*
* (let ((a 1)) instead (let ((a 1))
@@ -9067,17 +9104,17 @@ get_lisp_indent()
else
{
that++;
amount++;
firsttry = amount;
while (vim_iswhite(*that))
{
- amount += lbr_chartabsize(that, (colnr_T)amount);
+ amount += lbr_chartabsize(that, (colnr_T)amount, pos->lnum);
++that;
}
if (*that && *that != ';') /* not a comment line */
{
/* test *that != '(' to accommodate first let/do
* argument if it is more than one line */
if (!vi_lisp && *that != '(' && *that != '[')
@@ -9106,24 +9143,24 @@ get_lisp_indent()
if ((*that == '(' || *that == '[')
&& !quotecount)
++parencount;
if ((*that == ')' || *that == ']')
&& !quotecount)
--parencount;
if (*that == '\\' && *(that+1) != NUL)
amount += lbr_chartabsize_adv(&that,
- (colnr_T)amount);
+ (colnr_T)amount, pos->lnum);
amount += lbr_chartabsize_adv(&that,
- (colnr_T)amount);
+ (colnr_T)amount, pos->lnum);
}
}
while (vim_iswhite(*that))
{
- amount += lbr_chartabsize(that, (colnr_T)amount);
+ amount += lbr_chartabsize(that, (colnr_T)amount, pos->lnum);
that++;
}
if (!*that || *that == ';')
amount = firsttry;
}
}
}
}
diff --git a/src/misc2.c b/src/misc2.c
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -161,17 +161,17 @@ coladvance2(pos, addspaces, finetune, wc
if (wcol >= MAXCOL)
{
idx = (int)STRLEN(line) - 1 + one_more;
col = wcol;
#ifdef FEAT_VIRTUALEDIT
if ((addspaces || finetune) && !VIsual_active)
{
- curwin->w_curswant = linetabsize(line) + one_more;
+ curwin->w_curswant = linetabsize(line, pos->lnum) + one_more;
if (curwin->w_curswant > 0)
--curwin->w_curswant;
}
#endif
}
else
{
#ifdef FEAT_VIRTUALEDIT
@@ -179,17 +179,17 @@ coladvance2(pos, addspaces, finetune, wc
if (finetune
&& curwin->w_p_wrap
# ifdef FEAT_VERTSPLIT
&& curwin->w_width != 0
# endif
&& wcol >= (colnr_T)width)
{
- csize = linetabsize(line);
+ csize = linetabsize(line, pos->lnum);
if (csize > 0)
csize--;
if (wcol / width > (colnr_T)csize / width
&& ((State & INSERT) == 0 || (int)wcol > csize + 1))
{
/* In case of line wrapping don't move the cursor beyond the
* right screen edge. In Insert mode allow going just beyond
@@ -200,20 +200,20 @@ coladvance2(pos, addspaces, finetune, wc
}
#endif
ptr = line;
while (col <= wcol && *ptr != NUL)
{
/* Count a tab for what it's worth (if list mode not on) */
#ifdef FEAT_LINEBREAK
- csize = win_lbr_chartabsize(curwin, ptr, col, &head);
+ csize = win_lbr_chartabsize(curwin, ptr, col, &head, pos->lnum);
mb_ptr_adv(ptr);
#else
- csize = lbr_chartabsize_adv(&ptr, col);
+ csize = lbr_chartabsize_adv(&ptr, col, pos->lnum);
#endif
col += csize;
}
idx = (int)(ptr - line);
/*
* Handle all the special cases. The virtual_active() check
* is needed to ensure that a virtual position off the end of
* a line has the correct indexing. The one_more comparison
diff --git a/src/normal.c b/src/normal.c
--- a/src/normal.c
+++ b/src/normal.c
@@ -4530,17 +4530,17 @@ find_decl(ptr, len, locally, thisblock,
* Return OK if able to move cursor, FAIL otherwise.
*/
static int
nv_screengo(oap, dir, dist)
oparg_T *oap;
int dir;
long dist;
{
- int linelen = linetabsize(ml_get_curline());
+ int linelen = linetabsize(ml_get_curline(), curwin->w_cursor.lnum);
int retval = OK;
int atend = FALSE;
int n;
int col_off1; /* margin offset for first screen line */
int col_off2; /* margin offset for wrapped screen line */
int width1; /* text width for first screen line */
int width2; /* test width for wrapped screen line */
@@ -4603,17 +4603,17 @@ nv_screengo(oap, dir, dist)
--curwin->w_cursor.lnum;
#ifdef FEAT_FOLDING
/* Move to the start of a closed fold. Don't do that when
* 'foldopen' contains "all": it will open in a moment. */
if (!(fdo_flags & FDO_ALL))
(void)hasFolding(curwin->w_cursor.lnum,
&curwin->w_cursor.lnum, NULL);
#endif
- linelen = linetabsize(ml_get_curline());
+ linelen = linetabsize(ml_get_curline(), curwin->w_cursor.lnum);
if (linelen > width1)
curwin->w_curswant += (((linelen - width1 - 1) / width2)
+ 1) * width2;
}
}
else /* dir == FORWARD */
{
if (linelen > width1)
@@ -4633,17 +4633,17 @@ nv_screengo(oap, dir, dist)
#endif
if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
{
retval = FAIL;
break;
}
curwin->w_cursor.lnum++;
curwin->w_curswant %= width2;
- linelen = linetabsize(ml_get_curline());
+ linelen = linetabsize(ml_get_curline(), curwin->w_cursor.lnum);
}
}
}
#ifdef FEAT_VERTSPLIT
}
#endif
coladvance(curwin->w_curswant);
diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -430,17 +430,17 @@ shift_block(oap, amount)
if (has_mbyte)
bd.textstart += (*mb_ptr2len)(bd.textstart);
else
#endif
++bd.textstart;
}
for ( ; vim_iswhite(*bd.textstart); )
{
- incr = lbr_chartabsize_adv(&bd.textstart, (colnr_T)(bd.start_vcol));
+ incr = lbr_chartabsize_adv(&bd.textstart, (colnr_T)(bd.start_vcol), curwin->w_cursor.lnum);
total += incr;
bd.start_vcol += incr;
}
/* OK, now total=all the VWS reqd, and textstart points at the 1st
* non-ws char in the block. */
if (!curbuf->b_p_et)
i = ((ws_vcol % p_ts) + total) / p_ts; /* number of tabs */
if (i)
@@ -490,17 +490,17 @@ shift_block(oap, amount)
if (bd.startspaces)
mb_ptr_adv(non_white);
/* The character's column is in "bd.start_vcol". */
non_white_col = bd.start_vcol;
while (vim_iswhite(*non_white))
{
- incr = lbr_chartabsize_adv(&non_white, non_white_col);
+ incr = lbr_chartabsize_adv(&non_white, non_white_col, curwin->w_cursor.lnum);
non_white_col += incr;
}
block_space_width = non_white_col - oap->start_vcol;
/* We will shift by "total" or "block_space_width", whichever is less.
*/
shift_amount = (block_space_width < (size_t)total
? block_space_width : (size_t)total);
@@ -515,17 +515,17 @@ shift_block(oap, amount)
/* If "bd.startspaces" is set, "bd.textstart" points to the character
* preceding the block. We have to subtract its width to obtain its
* column number. */
if (bd.startspaces)
verbatim_copy_width -= bd.start_char_vcols;
while (verbatim_copy_width < destination_col)
{
- incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
+ incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width, curwin->w_cursor.lnum);
if (verbatim_copy_width + incr > destination_col)
break;
verbatim_copy_width += incr;
mb_ptr_adv(verbatim_copy_end);
}
/* If "destination_col" is different from the width of the initial
* part of the line that will be copied, it means we encountered a tab
@@ -3613,17 +3613,17 @@ do_put(regname, dir, count, flags)
++nr_lines;
}
/* get the old line and advance to the position to insert at */
oldp = ml_get_curline();
oldlen = (int)STRLEN(oldp);
for (ptr = oldp; vcol < col && *ptr; )
{
/* Count a tab for what it's worth (if list mode not on) */
- incr = lbr_chartabsize_adv(&ptr, (colnr_T)vcol);
+ incr = lbr_chartabsize_adv(&ptr, (colnr_T)vcol, lnum);
vcol += incr;
}
bd.textcol = (colnr_T)(ptr - oldp);
shortline = (vcol < col) || (vcol == col && !*ptr) ;
if (vcol < col) /* line too short, padd with spaces */
bd.startspaces = col - vcol;
@@ -3647,17 +3647,17 @@ do_put(regname, dir, count, flags)
}
}
yanklen = (int)STRLEN(y_array[i]);
/* calculate number of spaces required to fill right side of block*/
spaces = y_width + 1;
for (j = 0; j < yanklen; j++)
- spaces -= lbr_chartabsize(&y_array[i][j], 0);
+ spaces -= lbr_chartabsize(&y_array[i][j], 0, lnum);
if (spaces < 0)
spaces = 0;
/* insert the new text */
totlen = count * (yanklen + spaces) + bd.startspaces + bd.endspaces;
newp = alloc_check((unsigned)totlen + oldlen + 1);
if (newp == NULL)
break;
@@ -5164,17 +5164,17 @@ block_prep(oap, bdp, lnum, is_del)
bdp->start_char_vcols = 0;
line = ml_get(lnum);
pstart = line;
prev_pstart = line;
while (bdp->start_vcol < oap->start_vcol && *pstart)
{
/* Count a tab for what it's worth (if list mode not on) */
- incr = lbr_chartabsize(pstart, (colnr_T)bdp->start_vcol);
+ incr = lbr_chartabsize(pstart, (colnr_T)bdp->start_vcol, lnum);
bdp->start_vcol += incr;
#ifdef FEAT_VISUALEXTRA
if (vim_iswhite(*pstart))
{
bdp->pre_whitesp += incr;
bdp->pre_whitesp_c++;
}
else
@@ -5233,17 +5233,17 @@ block_prep(oap, bdp, lnum, is_del)
}
else
{
prev_pend = pend;
while (bdp->end_vcol <= oap->end_vcol && *pend != NUL)
{
/* Count a tab for what it's worth (if list mode not on) */
prev_pend = pend;
- incr = lbr_chartabsize_adv(&pend, (colnr_T)bdp->end_vcol);
+ incr = lbr_chartabsize_adv(&pend, (colnr_T)bdp->end_vcol, lnum);
bdp->end_vcol += incr;
}
if (bdp->end_vcol <= oap->end_vcol
&& (!is_del
|| oap->op_type == OP_APPEND
|| oap->op_type == OP_REPLACE)) /* line too short */
{
#ifdef FEAT_VISUALEXTRA
@@ -6746,17 +6746,17 @@ cursor_pos_info()
}
else
#endif
{
p = ml_get_curline();
validate_virtcol();
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
(int)curwin->w_virtcol + 1);
- col_print(buf2, sizeof(buf2), (int)STRLEN(p), linetabsize(p));
+ col_print(buf2, sizeof(buf2), (int)STRLEN(p), linetabsize(p, curwin->w_cursor.lnum));
if (char_count_cursor == byte_count_cursor
&& char_count == byte_count)
vim_snprintf((char *)IObuff, IOSIZE,
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"),
(char *)buf1, (char *)buf2,
(long)curwin->w_cursor.lnum,
(long)curbuf->b_ml.ml_line_count,
diff --git a/src/option.c b/src/option.c
--- a/src/option.c
+++ b/src/option.c
@@ -182,16 +182,21 @@
/*
* Definition of the PV_ values for window-local options.
* The WV_ values are defined in option.h.
*/
#define PV_LIST OPT_WIN(WV_LIST)
#ifdef FEAT_ARABIC
# define PV_ARAB OPT_WIN(WV_ARAB)
#endif
+#ifdef FEAT_LINEBREAK
+# define PV_BRI OPT_WIN(WV_BRI)
+# define PV_BRIMIN OPT_WIN(WV_BRIMIN)
+# define PV_BRISHIFT OPT_WIN(WV_BRISHIFT)
+#endif
#ifdef FEAT_DIFF
# define PV_DIFF OPT_WIN(WV_DIFF)
#endif
#ifdef FEAT_FOLDING
# define PV_FDC OPT_WIN(WV_FDC)
# define PV_FEN OPT_WIN(WV_FEN)
# define PV_FDI OPT_WIN(WV_FDI)
# define PV_FDL OPT_WIN(WV_FDL)
@@ -641,16 +646,43 @@ static struct vimoption
#ifdef FEAT_LINEBREAK
(char_u *)&p_breakat, PV_NONE,
{(char_u *)" \t!@*-+;:,./?", (char_u *)0L}
#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},
+ {"breakindentmin", "brimin", P_NUM|P_VI_DEF|P_VIM|P_RWIN,
+#ifdef FEAT_LINEBREAK
+ (char_u *)VAR_WIN, PV_BRIMIN,
+ {(char_u *)20L, (char_u *)20L}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
+ {"breakindentshift", "brishift", P_NUM|P_VI_DEF|P_VIM|P_RWIN,
+#ifdef FEAT_LINEBREAK
+ (char_u *)VAR_WIN, PV_BRISHIFT,
+ {(char_u *)0L, (char_u *)0L}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
{"browsedir", "bsdir",P_STRING|P_VI_DEF,
#ifdef FEAT_BROWSE
(char_u *)&p_bsdir, PV_NONE,
{(char_u *)"last", (char_u *)0L}
#else
(char_u *)NULL, PV_NONE,
{(char_u *)0L, (char_u *)0L}
#endif
@@ -8479,16 +8511,26 @@ set_num_option(opt_idx, varp, value, err
}
if (curwin->w_p_nuw > 10)
{
errmsg = e_invarg;
curwin->w_p_nuw = 10;
}
curwin->w_nrwidth_line_count = 0;
}
+
+ /* 'breakindentmin' must be positive */
+ else if (pp == &curwin->w_p_brimin)
+ {
+ if (curwin->w_p_brimin < 1)
+ {
+ errmsg = e_positive;
+ curwin->w_p_brimin = 1;
+ }
+ }
#endif
else if (pp == &curbuf->b_p_tw)
{
if (curbuf->b_p_tw < 0)
{
errmsg = e_positive;
curbuf->b_p_tw = 0;
@@ -9932,16 +9974,19 @@ get_varp(p)
#ifdef FEAT_RIGHTLEFT
case PV_RL: return (char_u *)&(curwin->w_p_rl);
case PV_RLC: return (char_u *)&(curwin->w_p_rlc);
#endif
case PV_SCROLL: return (char_u *)&(curwin->w_p_scr);
case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
#ifdef FEAT_LINEBREAK
case PV_LBR: return (char_u *)&(curwin->w_p_lbr);
+ case PV_BRI: return (char_u *)&(curwin->w_p_bri);
+ case PV_BRIMIN: return (char_u *)&(curwin->w_p_brimin);
+ case PV_BRISHIFT: return (char_u *)&(curwin->w_p_brishift);
#endif
#ifdef FEAT_SCROLLBIND
case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
#endif
#ifdef FEAT_CURSORBIND
case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
#endif
#ifdef FEAT_CONCEAL
@@ -10121,16 +10166,18 @@ copy_winopt(from, to)
to->wo_stl = vim_strsave(from->wo_stl);
#endif
to->wo_wrap = from->wo_wrap;
#ifdef FEAT_DIFF
to->wo_wrap_save = from->wo_wrap_save;
#endif
#ifdef FEAT_LINEBREAK
to->wo_lbr = from->wo_lbr;
+ to->wo_bri = from->wo_bri;
+ to->wo_brimin = from->wo_brimin;
#endif
#ifdef FEAT_SCROLLBIND
to->wo_scb = from->wo_scb;
to->wo_scb_save = from->wo_scb_save;
#endif
#ifdef FEAT_CURSORBIND
to->wo_crb = from->wo_crb;
to->wo_crb_save = from->wo_crb_save;
diff --git a/src/option.h b/src/option.h
--- a/src/option.h
+++ b/src/option.h
@@ -1048,16 +1048,21 @@ enum
#endif
#ifdef FEAT_CONCEAL
, WV_COCU
, WV_COLE
#endif
#ifdef FEAT_CURSORBIND
, WV_CRBIND
#endif
+#ifdef FEAT_LINEBREAK
+ , WV_BRI
+ , WV_BRIMIN
+ , WV_BRISHIFT
+#endif
#ifdef FEAT_DIFF
, WV_DIFF
#endif
#ifdef FEAT_FOLDING
, WV_FDC
, WV_FEN
, WV_FDI
, WV_FDL
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
--- a/src/proto/charset.pro
+++ b/src/proto/charset.pro
@@ -9,31 +9,31 @@ char_u *transchar_byte __ARGS((int c));
void transchar_nonprint __ARGS((char_u *buf, int c));
void transchar_hex __ARGS((char_u *buf, int c));
int byte2cells __ARGS((int b));
int char2cells __ARGS((int c));
int ptr2cells __ARGS((char_u *p));
int vim_strsize __ARGS((char_u *s));
int vim_strnsize __ARGS((char_u *s, int len));
int chartabsize __ARGS((char_u *p, colnr_T col));
-int linetabsize __ARGS((char_u *s));
-int linetabsize_col __ARGS((int startcol, char_u *s));
-int win_linetabsize __ARGS((win_T *wp, char_u *p, colnr_T len));
+int linetabsize __ARGS((char_u *s, linenr_T lnum));
+int linetabsize_col __ARGS((int startcol, char_u *s, linenr_T lnum));
+int win_linetabsize __ARGS((win_T *wp, char_u *p, colnr_T len, linenr_T lnum));
int vim_isIDc __ARGS((int c));
int vim_iswordc __ARGS((int c));
int vim_iswordc_buf __ARGS((int c, buf_T *buf));
int vim_iswordp __ARGS((char_u *p));
int vim_iswordp_buf __ARGS((char_u *p, buf_T *buf));
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((unsigned char *s, colnr_T col, linenr_T lnum));
+int lbr_chartabsize_adv __ARGS((char_u **s, colnr_T col, linenr_T lnum));
+int win_lbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp, linenr_T lnum));
int in_win_border __ARGS((win_T *wp, colnr_T vcol));
void getvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end));
colnr_T getvcol_nolist __ARGS((pos_T *posp));
void getvvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end));
void getvcols __ARGS((win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right));
char_u *skipwhite __ARGS((char_u *q));
char_u *skipdigits __ARGS((char_u *q));
char_u *skiphex __ARGS((char_u *q));
diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro
--- a/src/proto/misc1.pro
+++ b/src/proto/misc1.pro
@@ -1,15 +1,16 @@
/* misc1.c */
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 set_indent __ARGS((int size, int flags));
int get_number_indent __ARGS((linenr_T lnum));
+int get_breakindent_win __ARGS((win_T *wp, linenr_T lnum));
int open_line __ARGS((int dir, int flags, int 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));
int plines __ARGS((linenr_T lnum));
int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight));
int plines_nofill __ARGS((linenr_T lnum));
int plines_win_nofill __ARGS((win_T *wp, linenr_T lnum, int winheight));
int plines_win_nofold __ARGS((win_T *wp, linenr_T lnum));
diff --git a/src/regexp.c b/src/regexp.c
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -4247,17 +4247,18 @@ reg_match_visual()
getvvcol(wp, &top, &start, NULL, &end);
getvvcol(wp, &bot, &start2, NULL, &end2);
if (start2 < start)
start = start2;
if (end2 > end)
end = end2;
if (top.col == MAXCOL || bot.col == MAXCOL)
end = MAXCOL;
- cols = win_linetabsize(wp, regline, (colnr_T)(reginput - regline));
+ cols = win_linetabsize(wp, regline, (colnr_T)(reginput - regline),
+ reglnum + reg_firstlnum);
if (cols < start || cols > end - (*p_sel == 'e'))
return FALSE;
}
return TRUE;
}
#endif
#define ADVANCE_REGINPUT() mb_ptr_adv(reginput)
@@ -4455,17 +4456,18 @@ regmatch(scan)
case RE_COL:
if (!re_num_cmp((long_u)(reginput - regline) + 1, scan))
status = RA_NOMATCH;
break;
case RE_VCOL:
if (!re_num_cmp((long_u)win_linetabsize(
reg_win == NULL ? curwin : reg_win,
- regline, (colnr_T)(reginput - regline)) + 1, scan))
+ regline, (colnr_T)(reginput - regline),
+ reglnum + reg_firstlnum) + 1, scan))
status = RA_NOMATCH;
break;
case BOW: /* \<word; reginput points to w */
if (c == NUL) /* Can't match at end of line */
status = RA_NOMATCH;
#ifdef FEAT_MBYTE
else if (has_mbyte)
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -5920,17 +5920,18 @@ nfa_regmatch(prog, start, submatch, m)
break;
case NFA_VCOL:
case NFA_VCOL_GT:
case NFA_VCOL_LT:
result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_VCOL,
(long_u)win_linetabsize(
reg_win == NULL ? curwin : reg_win,
- regline, (colnr_T)(reginput - regline)) + 1);
+ regline, (colnr_T)(reginput - regline),
+ reglnum + reg_firstlnum) + 1);
if (result)
{
add_here = TRUE;
add_state = t->state->out;
}
break;
case NFA_MARK:
diff --git a/src/screen.c b/src/screen.c
--- a/src/screen.c
+++ b/src/screen.c
@@ -2969,20 +2969,25 @@ win_line(wp, lnum, startrow, endrow, noc
# define WL_FOLD WL_CMDLINE
#endif
#ifdef FEAT_SIGNS
# define WL_SIGN WL_FOLD + 1 /* column for signs */
#else
# 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 */
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
int feedback_col = 0;
int feedback_old_attr = -1;
#endif
@@ -3311,17 +3316,17 @@ win_line(wp, lnum, startrow, endrow, noc
v = wp->w_leftcol;
if (v > 0)
{
#ifdef FEAT_MBYTE
char_u *prev_ptr = ptr;
#endif
while (vcol < v && *ptr != NUL)
{
- c = win_lbr_chartabsize(wp, ptr, (colnr_T)vcol, NULL);
+ c = win_lbr_chartabsize(wp, ptr, (colnr_T)vcol, NULL, lnum);
vcol += c;
#ifdef FEAT_MBYTE
prev_ptr = ptr;
#endif
mb_ptr_adv(ptr);
}
#if defined(FEAT_SYN_HL) || defined(FEAT_VIRTUALEDIT) || defined(FEAT_VISUAL)
@@ -3693,16 +3698,41 @@ win_line(wp, lnum, startrow, endrow, noc
* when CursorLineNr isn't set? */
if ((wp->w_p_cul || wp->w_p_rnu)
&& lnum == wp->w_cursor.lnum)
char_attr = hl_attr(HLF_CLN);
#endif
}
}
+#ifdef FEAT_LINEBREAK
+ /* draw 'breakindent': indent wrapped text accordingly */
+ if (draw_state == WL_BRI -1 && n_extra == 0)
+ {
+ draw_state = WL_BRI;
+# ifdef FEAT_DIFF
+ /* FIXME: handle (filler_todo > 0): or modify showbreak so that ---- lines are shorter by the amount needed? */
+# endif
+ if (wp->w_p_bri && row != startrow) /* FIXME: what is startrow? Don't we need it as well?? */
+ {
+ p_extra = NUL;
+ c_extra = ' ';
+ n_extra = get_breakindent_win(wp,lnum);
+ char_attr = 0; /* was: hl_attr(HLF_AT); */
+ /* FIXME: why do we need to adjust vcol if showbreak does not?? */
+ // vcol += n_extra;
+ /* FIXME: is this relevant here? copied shamelessly from showbreak */
+ /* Correct end of highlighted area for 'breakindent',
+ * required when 'linebreak' is also set. */
+ if (tocol == vcol)
+ tocol += n_extra;
+ }
+ }
+#endif
+
#if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
if (draw_state == WL_SBR - 1 && n_extra == 0)
{
draw_state = WL_SBR;
# ifdef FEAT_DIFF
if (filler_todo > 0)
{
/* Draw "deleted" diff line(s). */
@@ -4404,17 +4434,17 @@ win_line(wp, lnum, startrow, endrow, noc
*/
if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)
&& !wp->w_p_list)
{
n_extra = win_lbr_chartabsize(wp, ptr - (
# ifdef FEAT_MBYTE
has_mbyte ? mb_l :
# endif
- 1), (colnr_T)vcol, NULL) - 1;
+ 1), (colnr_T)vcol, NULL, lnum) - 1;
c_extra = ' ';
if (vim_iswhite(c))
{
#ifdef FEAT_CONCEAL
if (c == TAB)
/* See "Tab alignment" below. */
FIX_FOR_BOGUSCOLS;
#endif
diff --git a/src/structs.h b/src/structs.h
--- a/src/structs.h
+++ b/src/structs.h
@@ -129,16 +129,24 @@ typedef struct taggy
* Also used in wininfo_T.
*/
typedef struct
{
#ifdef FEAT_ARABIC
int wo_arab;
# define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */
#endif
+#ifdef FEAT_LINEBREAK
+ int wo_bri;
+# define w_p_bri w_onebuf_opt.wo_bri /* 'breakindent' */
+ long wo_brimin;
+# define w_p_brimin w_onebuf_opt.wo_brimin /* 'breakindentmin' */
+ long wo_brishift;
+# define w_p_brishift w_onebuf_opt.wo_brishift /* 'breakindentshift' */
+#endif
#ifdef FEAT_DIFF
int wo_diff;
# define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */
#endif
#ifdef FEAT_FOLDING
long wo_fdc;
# define w_p_fdc w_onebuf_opt.wo_fdc /* 'foldcolumn' */
int wo_fdc_save;
diff --git a/src/ui.c b/src/ui.c
--- a/src/ui.c
+++ b/src/ui.c
@@ -3170,17 +3170,17 @@ vcol2col(wp, lnum, vcol)
/* try to advance to the specified column */
int count = 0;
char_u *ptr;
char_u *start;
start = ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
while (count < vcol && *ptr != NUL)
{
- count += win_lbr_chartabsize(wp, ptr, count, NULL);
+ count += win_lbr_chartabsize(wp, ptr, count, NULL, lnum);
mb_ptr_adv(ptr);
}
return (int)(ptr - start);
}
#endif
#endif /* FEAT_MOUSE */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment