Last active
December 18, 2015 02:28
-
-
Save shirosaki/5710831 to your computer and use it in GitHub Desktop.
Update for Vim v7-4a-024 of https://retracile.net/wiki/VimBreakIndent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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