mirror of
https://github.com/neovim/neovim.git
synced 2025-09-12 22:38:16 +00:00
vim-patch:8.1.0105: all tab stops are the same
Problem: All tab stops are the same.
Solution: Add the variable tabstop feature. (Christian Brabandt,
closes vim/vim#2711)
04958cbaf2
This commit is contained in:
@@ -934,6 +934,10 @@ This replaces each 'E' character with a euro sign. Read more in |<Char->|.
|
|||||||
this (that's a good habit anyway).
|
this (that's a good habit anyway).
|
||||||
`:retab!` may also change a sequence of spaces by
|
`:retab!` may also change a sequence of spaces by
|
||||||
<Tab> characters, which can mess up a printf().
|
<Tab> characters, which can mess up a printf().
|
||||||
|
A list of tab widths separated by commas may be used
|
||||||
|
in place of a single tabstop. Each value in the list
|
||||||
|
represents the width of one tabstop, except the final
|
||||||
|
value which applies to all following tabstops.
|
||||||
|
|
||||||
*retab-example*
|
*retab-example*
|
||||||
Example for using autocommands and ":retab" to edit a file which is stored
|
Example for using autocommands and ":retab" to edit a file which is stored
|
||||||
|
@@ -7915,6 +7915,11 @@ shiftwidth() *shiftwidth()*
|
|||||||
endif
|
endif
|
||||||
< And then use s:sw() instead of &sw.
|
< And then use s:sw() instead of &sw.
|
||||||
|
|
||||||
|
When there is one argument {col} this is used as column number
|
||||||
|
for which to return the 'shiftwidth' value. This matters for the
|
||||||
|
'vartabstop' feature. If no {col} argument is given, column 1
|
||||||
|
will be assumed.
|
||||||
|
|
||||||
sign_define({name} [, {dict}]) *sign_define()*
|
sign_define({name} [, {dict}]) *sign_define()*
|
||||||
Define a new sign named {name} or modify the attributes of an
|
Define a new sign named {name} or modify the attributes of an
|
||||||
existing sign. This is similar to the |:sign-define| command.
|
existing sign. This is similar to the |:sign-define| command.
|
||||||
|
@@ -5621,6 +5621,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
The 'L' flag in 'cpoptions' changes how tabs are used when 'list' is
|
The 'L' flag in 'cpoptions' changes how tabs are used when 'list' is
|
||||||
set.
|
set.
|
||||||
|
|
||||||
|
The value of 'softtabstop' will be ignored if |'varsofttabstop'| is set
|
||||||
|
to anything other than an empty string.
|
||||||
|
|
||||||
*'spell'* *'nospell'*
|
*'spell'* *'nospell'*
|
||||||
'spell' boolean (default off)
|
'spell' boolean (default off)
|
||||||
local to window
|
local to window
|
||||||
@@ -6158,6 +6161,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
though. Otherwise aligned comments will be wrong when 'tabstop' is
|
though. Otherwise aligned comments will be wrong when 'tabstop' is
|
||||||
changed.
|
changed.
|
||||||
|
|
||||||
|
The value of 'tabstop' will be ignored if |'vartabstop'| is set to
|
||||||
|
anything other than an empty string.
|
||||||
|
|
||||||
*'tagbsearch'* *'tbs'* *'notagbsearch'* *'notbs'*
|
*'tagbsearch'* *'tbs'* *'notagbsearch'* *'notbs'*
|
||||||
'tagbsearch' 'tbs' boolean (default on)
|
'tagbsearch' 'tbs' boolean (default on)
|
||||||
global
|
global
|
||||||
@@ -6542,6 +6548,38 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
written to disk (see |crash-recovery|). Also used for the
|
written to disk (see |crash-recovery|). Also used for the
|
||||||
|CursorHold| autocommand event.
|
|CursorHold| autocommand event.
|
||||||
|
|
||||||
|
*'varsofttabstop'* *'vsts'*
|
||||||
|
'varsofttabstop' 'vsts' string (default "")
|
||||||
|
local to buffer
|
||||||
|
A list of the number of spaces that a <Tab> counts for while editing,
|
||||||
|
such as inserting a <Tab> or using <BS>. It "feels" like variable-
|
||||||
|
width <Tab>s are being inserted, while in fact a mixture of spaces
|
||||||
|
and <Tab>s is used. Tab widths are separated with commas, with the
|
||||||
|
final value applying to all subsequent tabs.
|
||||||
|
|
||||||
|
For example, when editing assembly language files where statements
|
||||||
|
start in the 8th column and comments in the 40th, it may be useful
|
||||||
|
to use the following: >
|
||||||
|
:set varsofttabstop=8,32,8
|
||||||
|
< This will set soft tabstops at the 8th and 40th columns, and at every
|
||||||
|
8th column thereafter.
|
||||||
|
|
||||||
|
Note that the value of |'softtabstop'| will be ignored while
|
||||||
|
'varsofttabstop' is set.
|
||||||
|
|
||||||
|
*'vartabstop'* *'vts'*
|
||||||
|
'vartabstop' 'vts' string (default "")
|
||||||
|
local to buffer
|
||||||
|
A list of the number of spaces that a <Tab> in the file counts for,
|
||||||
|
separated by commas. Each value corresponds to one tab, with the
|
||||||
|
final value applying to all subsequent tabs. For example: >
|
||||||
|
:set vartabstop=4,20,10,8
|
||||||
|
< This will make the first tab 4 spaces wide, the second 20 spaces,
|
||||||
|
the third 10 spaces, and all following tabs 8 spaces.
|
||||||
|
|
||||||
|
Note that the value of |'tabstop'| will be ignored while 'vartabstop'
|
||||||
|
is set.
|
||||||
|
|
||||||
*'verbose'* *'vbs'*
|
*'verbose'* *'vbs'*
|
||||||
'verbose' 'vbs' number (default 0)
|
'verbose' 'vbs' number (default 0)
|
||||||
global
|
global
|
||||||
|
@@ -810,6 +810,14 @@ call <SID>OptionL("ts")
|
|||||||
call append("$", "shiftwidth\tnumber of spaces used for each step of (auto)indent")
|
call append("$", "shiftwidth\tnumber of spaces used for each step of (auto)indent")
|
||||||
call append("$", "\t(local to buffer)")
|
call append("$", "\t(local to buffer)")
|
||||||
call <SID>OptionL("sw")
|
call <SID>OptionL("sw")
|
||||||
|
if has("vartabs")
|
||||||
|
call append("$", "vartabstop\tlist of number of spaces a tab counts for")
|
||||||
|
call append("$", "\t(local to buffer)")
|
||||||
|
call <SID>OptionL("vts")
|
||||||
|
call append("$", "varsofttabstop\tlist of number of spaces a soft tabsstop counts for")
|
||||||
|
call append("$", "\t(local to buffer)")
|
||||||
|
call <SID>OptionL("vsts")
|
||||||
|
endif
|
||||||
call append("$", "smarttab\ta <Tab> in an indent inserts 'shiftwidth' spaces")
|
call append("$", "smarttab\ta <Tab> in an indent inserts 'shiftwidth' spaces")
|
||||||
call <SID>BinOptionG("sta", &sta)
|
call <SID>BinOptionG("sta", &sta)
|
||||||
call append("$", "softtabstop\tif non-zero, number of spaces to insert for a <Tab>")
|
call append("$", "softtabstop\tif non-zero, number of spaces to insert for a <Tab>")
|
||||||
|
@@ -282,7 +282,7 @@ int open_buffer(
|
|||||||
|
|
||||||
// Set/reset the Changed flag first, autocmds may change the buffer.
|
// Set/reset the Changed flag first, autocmds may change the buffer.
|
||||||
// Apply the automatic commands, before processing the modelines.
|
// Apply the automatic commands, before processing the modelines.
|
||||||
// So the modelines have priority over auto commands.
|
// So the modelines have priority over autocommands.
|
||||||
|
|
||||||
// When reading stdin, the buffer contents always needs writing, so set
|
// When reading stdin, the buffer contents always needs writing, so set
|
||||||
// the changed flag. Unless in readonly mode: "ls | nvim -R -".
|
// the changed flag. Unless in readonly mode: "ls | nvim -R -".
|
||||||
@@ -1946,6 +1946,20 @@ void free_buf_options(buf_T *buf, int free_p_ff)
|
|||||||
clear_string_option(&buf->b_p_fo);
|
clear_string_option(&buf->b_p_fo);
|
||||||
clear_string_option(&buf->b_p_flp);
|
clear_string_option(&buf->b_p_flp);
|
||||||
clear_string_option(&buf->b_p_isk);
|
clear_string_option(&buf->b_p_isk);
|
||||||
|
clear_string_option(&buf->b_p_vsts);
|
||||||
|
if (buf->b_p_vsts_nopaste) {
|
||||||
|
xfree(buf->b_p_vsts_nopaste);
|
||||||
|
}
|
||||||
|
buf->b_p_vsts_nopaste = NULL;
|
||||||
|
if (buf->b_p_vsts_array) {
|
||||||
|
xfree(buf->b_p_vsts_array);
|
||||||
|
}
|
||||||
|
buf->b_p_vsts_array = NULL;
|
||||||
|
clear_string_option(&buf->b_p_vts);
|
||||||
|
if (buf->b_p_vts_array) {
|
||||||
|
xfree(buf->b_p_vts_array);
|
||||||
|
}
|
||||||
|
buf->b_p_vts_array = NULL;
|
||||||
clear_string_option(&buf->b_p_keymap);
|
clear_string_option(&buf->b_p_keymap);
|
||||||
keymap_ga_clear(&buf->b_kmap_ga);
|
keymap_ga_clear(&buf->b_kmap_ga);
|
||||||
ga_clear(&buf->b_kmap_ga);
|
ga_clear(&buf->b_kmap_ga);
|
||||||
@@ -5375,8 +5389,8 @@ bool bt_terminal(const buf_T *const buf)
|
|||||||
return buf != NULL && buf->b_p_bt[0] == 't';
|
return buf != NULL && buf->b_p_bt[0] == 't';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if "buf" is a "nofile", "acwrite" or "terminal" buffer.
|
// Return true if "buf" is a "nofile", "acwrite", "terminal" or "prompt"
|
||||||
// This means the buffer name is not a file name.
|
// buffer. This means the buffer name is not a file name.
|
||||||
bool bt_nofile(const buf_T *const buf)
|
bool bt_nofile(const buf_T *const buf)
|
||||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
@@ -5386,7 +5400,8 @@ bool bt_nofile(const buf_T *const buf)
|
|||||||
|| buf->b_p_bt[0] == 'p');
|
|| buf->b_p_bt[0] == 'p');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if "buf" is a "nowrite", "nofile" or "terminal" buffer.
|
// Return true if "buf" is a "nowrite", "nofile", "terminal" or "prompt"
|
||||||
|
// buffer.
|
||||||
bool bt_dontwrite(const buf_T *const buf)
|
bool bt_dontwrite(const buf_T *const buf)
|
||||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
|
@@ -743,6 +743,11 @@ struct file_buffer {
|
|||||||
long b_p_wm; ///< 'wrapmargin'
|
long b_p_wm; ///< 'wrapmargin'
|
||||||
long b_p_wm_nobin; ///< b_p_wm saved for binary mode
|
long b_p_wm_nobin; ///< b_p_wm saved for binary mode
|
||||||
long b_p_wm_nopaste; ///< b_p_wm saved for paste mode
|
long b_p_wm_nopaste; ///< b_p_wm saved for paste mode
|
||||||
|
char_u *b_p_vsts; ///< 'varsofttabstop'
|
||||||
|
long *b_p_vsts_array; ///< 'varsofttabstop' in internal format
|
||||||
|
char_u *b_p_vsts_nopaste; ///< b_p_vsts saved for paste mode
|
||||||
|
char_u *b_p_vts; ///< 'vartabstop'
|
||||||
|
long *b_p_vts_array; ///< 'vartabstop' in internal format
|
||||||
char_u *b_p_keymap; ///< 'keymap'
|
char_u *b_p_keymap; ///< 'keymap'
|
||||||
|
|
||||||
// local values for options which are normally global
|
// local values for options which are normally global
|
||||||
|
@@ -828,6 +828,7 @@ int copy_indent(int size, char_u *src)
|
|||||||
int tab_pad;
|
int tab_pad;
|
||||||
int ind_done;
|
int ind_done;
|
||||||
int round;
|
int round;
|
||||||
|
int ind_col;
|
||||||
|
|
||||||
// Round 1: compute the number of characters needed for the indent
|
// Round 1: compute the number of characters needed for the indent
|
||||||
// Round 2: copy the characters.
|
// Round 2: copy the characters.
|
||||||
@@ -835,13 +836,15 @@ int copy_indent(int size, char_u *src)
|
|||||||
todo = size;
|
todo = size;
|
||||||
ind_len = 0;
|
ind_len = 0;
|
||||||
ind_done = 0;
|
ind_done = 0;
|
||||||
|
ind_col = 0;
|
||||||
s = src;
|
s = src;
|
||||||
|
|
||||||
// Count/copy the usable portion of the source line.
|
// Count/copy the usable portion of the source line.
|
||||||
while (todo > 0 && ascii_iswhite(*s)) {
|
while (todo > 0 && ascii_iswhite(*s)) {
|
||||||
if (*s == TAB) {
|
if (*s == TAB) {
|
||||||
tab_pad = (int)curbuf->b_p_ts
|
tab_pad = tabstop_padding(ind_done,
|
||||||
- (ind_done % (int)curbuf->b_p_ts);
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
|
|
||||||
// Stop if this tab will overshoot the target.
|
// Stop if this tab will overshoot the target.
|
||||||
if (todo < tab_pad) {
|
if (todo < tab_pad) {
|
||||||
@@ -849,9 +852,11 @@ int copy_indent(int size, char_u *src)
|
|||||||
}
|
}
|
||||||
todo -= tab_pad;
|
todo -= tab_pad;
|
||||||
ind_done += tab_pad;
|
ind_done += tab_pad;
|
||||||
|
ind_col += tab_pad;
|
||||||
} else {
|
} else {
|
||||||
todo--;
|
todo--;
|
||||||
ind_done++;
|
ind_done++;
|
||||||
|
ind_col++;
|
||||||
}
|
}
|
||||||
ind_len++;
|
ind_len++;
|
||||||
|
|
||||||
@@ -862,11 +867,12 @@ int copy_indent(int size, char_u *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fill to next tabstop with a tab, if possible.
|
// Fill to next tabstop with a tab, if possible.
|
||||||
tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
|
tab_pad = tabstop_padding(ind_done, curbuf->b_p_ts, curbuf->b_p_vts_array);
|
||||||
|
|
||||||
if ((todo >= tab_pad) && !curbuf->b_p_et) {
|
if ((todo >= tab_pad) && !curbuf->b_p_et) {
|
||||||
todo -= tab_pad;
|
todo -= tab_pad;
|
||||||
ind_len++;
|
ind_len++;
|
||||||
|
ind_col += tab_pad;
|
||||||
|
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
*p++ = TAB;
|
*p++ = TAB;
|
||||||
@@ -874,14 +880,22 @@ int copy_indent(int size, char_u *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add tabs required for indent.
|
// Add tabs required for indent.
|
||||||
while (todo >= (int)curbuf->b_p_ts && !curbuf->b_p_et) {
|
if (!curbuf->b_p_et) {
|
||||||
todo -= (int)curbuf->b_p_ts;
|
for (;;) {
|
||||||
|
tab_pad = tabstop_padding(ind_col,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
|
if (todo < tab_pad) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
todo -= tab_pad;
|
||||||
ind_len++;
|
ind_len++;
|
||||||
|
ind_col += tab_pad;
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
*p++ = TAB;
|
*p++ = TAB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Count/add spaces required for indent.
|
// Count/add spaces required for indent.
|
||||||
while (todo > 0) {
|
while (todo > 0) {
|
||||||
@@ -1029,7 +1043,9 @@ int open_line(
|
|||||||
|| do_si
|
|| do_si
|
||||||
) {
|
) {
|
||||||
// count white space on current line
|
// count white space on current line
|
||||||
newindent = get_indent_str(saved_line, (int)curbuf->b_p_ts, false);
|
newindent = get_indent_str_vtab(saved_line,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array, false);
|
||||||
if (newindent == 0 && !(flags & OPENLINE_COM_LIST)) {
|
if (newindent == 0 && !(flags & OPENLINE_COM_LIST)) {
|
||||||
newindent = second_line_indent; // for ^^D command in insert mode
|
newindent = second_line_indent; // for ^^D command in insert mode
|
||||||
}
|
}
|
||||||
@@ -1453,7 +1469,9 @@ int open_line(
|
|||||||
if (curbuf->b_p_ai
|
if (curbuf->b_p_ai
|
||||||
|| do_si
|
|| do_si
|
||||||
) {
|
) {
|
||||||
newindent = get_indent_str(leader, (int)curbuf->b_p_ts, false);
|
newindent = get_indent_str_vtab(leader,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the indent offset
|
// Add the indent offset
|
||||||
|
@@ -744,8 +744,7 @@ int vim_strnsize(char_u *s, int len)
|
|||||||
/// @return Number of characters.
|
/// @return Number of characters.
|
||||||
#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
|
#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
|
||||||
if (*(p) == TAB && (!(wp)->w_p_list || wp->w_p_lcs_chars.tab1)) { \
|
if (*(p) == TAB && (!(wp)->w_p_list || wp->w_p_lcs_chars.tab1)) { \
|
||||||
const int ts = (int)(buf)->b_p_ts; \
|
return tabstop_padding(col, (buf)->b_p_ts, (buf)->b_p_vts_array); \
|
||||||
return (ts - (int)(col % ts)); \
|
|
||||||
} else { \
|
} else { \
|
||||||
return ptr2cells(p); \
|
return ptr2cells(p); \
|
||||||
}
|
}
|
||||||
@@ -1143,8 +1142,9 @@ static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
|
if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
|
||||||
n = (int)wp->w_buffer->b_p_ts;
|
return tabstop_padding(col,
|
||||||
return n - (col % n);
|
wp->w_buffer->b_p_ts,
|
||||||
|
wp->w_buffer->b_p_vts_array);
|
||||||
}
|
}
|
||||||
n = ptr2cells(s);
|
n = ptr2cells(s);
|
||||||
|
|
||||||
@@ -1211,6 +1211,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
|
|||||||
char_u *line; // start of the line
|
char_u *line; // start of the line
|
||||||
int incr;
|
int incr;
|
||||||
int head;
|
int head;
|
||||||
|
long *vts = wp->w_buffer->b_p_vts_array;
|
||||||
int ts = (int)wp->w_buffer->b_p_ts;
|
int ts = (int)wp->w_buffer->b_p_ts;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@@ -1251,7 +1252,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
|
|||||||
|
|
||||||
// A tab gets expanded, depending on the current column
|
// A tab gets expanded, depending on the current column
|
||||||
if (c == TAB) {
|
if (c == TAB) {
|
||||||
incr = ts - (vcol % ts);
|
incr = tabstop_padding(vcol, ts, vts);
|
||||||
} else {
|
} else {
|
||||||
// For utf-8, if the byte is >= 0x80, need to look at
|
// For utf-8, if the byte is >= 0x80, need to look at
|
||||||
// further bytes to find the cell width.
|
// further bytes to find the cell width.
|
||||||
|
@@ -597,7 +597,10 @@ static int insert_check(VimState *state)
|
|||||||
s->mincol = curwin->w_wcol;
|
s->mincol = curwin->w_wcol;
|
||||||
validate_cursor_col();
|
validate_cursor_col();
|
||||||
|
|
||||||
if (curwin->w_wcol < s->mincol - curbuf->b_p_ts
|
if (
|
||||||
|
curwin->w_wcol < s->mincol - tabstop_at(get_nolist_virtcol(),
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array)
|
||||||
&& curwin->w_wrow == curwin->w_winrow
|
&& curwin->w_wrow == curwin->w_winrow
|
||||||
+ curwin->w_height_inner - 1 - get_scrolloff_value(curwin)
|
+ curwin->w_height_inner - 1 - get_scrolloff_value(curwin)
|
||||||
&& (curwin->w_cursor.lnum != curwin->w_topline
|
&& (curwin->w_cursor.lnum != curwin->w_topline
|
||||||
@@ -8178,24 +8181,19 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|
|||||||
/*
|
/*
|
||||||
* Handle deleting one 'shiftwidth' or 'softtabstop'.
|
* Handle deleting one 'shiftwidth' or 'softtabstop'.
|
||||||
*/
|
*/
|
||||||
if ( mode == BACKSPACE_CHAR
|
if (mode == BACKSPACE_CHAR
|
||||||
&& ((p_sta && in_indent)
|
&& ((p_sta && in_indent)
|
||||||
|| (get_sts_value() != 0
|
|| ((get_sts_value() != 0
|
||||||
|
|| tabstop_count(curbuf->b_p_vsts_array))
|
||||||
&& curwin->w_cursor.col > 0
|
&& curwin->w_cursor.col > 0
|
||||||
&& (*(get_cursor_pos_ptr() - 1) == TAB
|
&& (*(get_cursor_pos_ptr() - 1) == TAB
|
||||||
|| (*(get_cursor_pos_ptr() - 1) == ' '
|
|| (*(get_cursor_pos_ptr() - 1) == ' '
|
||||||
&& (!*inserted_space_p
|
&& (!*inserted_space_p || arrow_used)))))) {
|
||||||
|| arrow_used)))))) {
|
|
||||||
int ts;
|
|
||||||
colnr_T vcol;
|
colnr_T vcol;
|
||||||
colnr_T want_vcol;
|
colnr_T want_vcol;
|
||||||
colnr_T start_vcol;
|
colnr_T start_vcol;
|
||||||
|
|
||||||
*inserted_space_p = FALSE;
|
*inserted_space_p = false;
|
||||||
if (p_sta && in_indent)
|
|
||||||
ts = get_sw_value(curbuf);
|
|
||||||
else
|
|
||||||
ts = get_sts_value();
|
|
||||||
// Compute the virtual column where we want to be. Since
|
// Compute the virtual column where we want to be. Since
|
||||||
// 'showbreak' may get in the way, need to get the last column of
|
// 'showbreak' may get in the way, need to get the last column of
|
||||||
// the previous character.
|
// the previous character.
|
||||||
@@ -8204,7 +8202,13 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|
|||||||
dec_cursor();
|
dec_cursor();
|
||||||
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
|
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
|
||||||
inc_cursor();
|
inc_cursor();
|
||||||
want_vcol = (want_vcol / ts) * ts;
|
if (p_sta && in_indent) {
|
||||||
|
want_vcol = (want_vcol / curbuf->b_p_sw) * curbuf->b_p_sw;
|
||||||
|
} else {
|
||||||
|
want_vcol = tabstop_start(want_vcol,
|
||||||
|
curbuf->b_p_sts,
|
||||||
|
curbuf->b_p_vsts_array);
|
||||||
|
}
|
||||||
|
|
||||||
// delete characters until we are at or before want_vcol
|
// delete characters until we are at or before want_vcol
|
||||||
while (vcol > want_vcol
|
while (vcol > want_vcol
|
||||||
@@ -8669,10 +8673,19 @@ static bool ins_tab(void)
|
|||||||
can_cindent = false;
|
can_cindent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When nothing special, insert TAB like a normal character
|
// When nothing special, insert TAB like a normal character.
|
||||||
if (!curbuf->b_p_et
|
if (!curbuf->b_p_et
|
||||||
&& !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf))
|
&& !(
|
||||||
&& get_sts_value() == 0) {
|
p_sta
|
||||||
|
&& ind
|
||||||
|
// These five lines mean 'tabstop' != 'shiftwidth'
|
||||||
|
&& ((tabstop_count(curbuf->b_p_vts_array) > 1)
|
||||||
|
|| (tabstop_count(curbuf->b_p_vts_array) == 1
|
||||||
|
&& tabstop_first(curbuf->b_p_vts_array)
|
||||||
|
!= get_sw_value(curbuf))
|
||||||
|
|| (tabstop_count(curbuf->b_p_vts_array) == 0
|
||||||
|
&& curbuf->b_p_ts != get_sw_value(curbuf))))
|
||||||
|
&& tabstop_count(curbuf->b_p_vsts_array) == 0 && get_sts_value() == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8686,15 +8699,21 @@ static bool ins_tab(void)
|
|||||||
can_si_back = false;
|
can_si_back = false;
|
||||||
AppendToRedobuff("\t");
|
AppendToRedobuff("\t");
|
||||||
|
|
||||||
if (p_sta && ind) { // insert tab in indent, use "shiftwidth"
|
if (p_sta && ind) { // insert tab in indent, use 'shiftwidth'
|
||||||
temp = get_sw_value(curbuf);
|
temp = (int)curbuf->b_p_sw;
|
||||||
} else if (curbuf->b_p_sts != 0) { // use "softtabstop" when set
|
|
||||||
temp = get_sts_value();
|
|
||||||
} else { // otherwise use "tabstop"
|
|
||||||
temp = (int)curbuf->b_p_ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp -= get_nolist_virtcol() % temp;
|
temp -= get_nolist_virtcol() % temp;
|
||||||
|
} else if (tabstop_count(curbuf->b_p_vsts_array) > 0
|
||||||
|
|| curbuf->b_p_sts > 0) {
|
||||||
|
// use 'softtabstop' when set
|
||||||
|
temp = tabstop_padding(get_nolist_virtcol(),
|
||||||
|
curbuf->b_p_sts,
|
||||||
|
curbuf->b_p_vsts_array);
|
||||||
|
} else {
|
||||||
|
// otherwise use 'tabstop'
|
||||||
|
temp = tabstop_padding(get_nolist_virtcol(),
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert the first space with ins_char(). It will delete one char in
|
* Insert the first space with ins_char(). It will delete one char in
|
||||||
@@ -8716,7 +8735,9 @@ static bool ins_tab(void)
|
|||||||
/*
|
/*
|
||||||
* When 'expandtab' not set: Replace spaces by TABs where possible.
|
* When 'expandtab' not set: Replace spaces by TABs where possible.
|
||||||
*/
|
*/
|
||||||
if (!curbuf->b_p_et && (get_sts_value() || (p_sta && ind))) {
|
if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0
|
||||||
|
|| get_sts_value() > 0
|
||||||
|
|| (p_sta && ind))) {
|
||||||
char_u *ptr;
|
char_u *ptr;
|
||||||
char_u *saved_line = NULL; // init for GCC
|
char_u *saved_line = NULL; // init for GCC
|
||||||
pos_T pos;
|
pos_T pos;
|
||||||
|
@@ -4312,6 +4312,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
"title",
|
"title",
|
||||||
"user-commands", // was accidentally included in 5.4
|
"user-commands", // was accidentally included in 5.4
|
||||||
"user_commands",
|
"user_commands",
|
||||||
|
"vartabs",
|
||||||
"vertsplit",
|
"vertsplit",
|
||||||
"virtualedit",
|
"virtualedit",
|
||||||
"visual",
|
"visual",
|
||||||
|
@@ -712,14 +712,15 @@ void ex_retab(exarg_T *eap)
|
|||||||
long len;
|
long len;
|
||||||
long col;
|
long col;
|
||||||
long vcol;
|
long vcol;
|
||||||
long start_col = 0; /* For start of white-space string */
|
long start_col = 0; // For start of white-space string
|
||||||
long start_vcol = 0; /* For start of white-space string */
|
long start_vcol = 0; // For start of white-space string
|
||||||
int temp;
|
|
||||||
long old_len;
|
long old_len;
|
||||||
char_u *ptr;
|
char_u *ptr;
|
||||||
char_u *new_line = (char_u *)1; /* init to non-NULL */
|
char_u *new_line = (char_u *)1; // init to non-NULL
|
||||||
int did_undo; /* called u_save for current line */
|
int did_undo; // called u_save for current line
|
||||||
int new_ts;
|
long *new_ts = 0;
|
||||||
|
char_u *new_ts_str; // string value of tab argument
|
||||||
|
|
||||||
int save_list;
|
int save_list;
|
||||||
linenr_T first_line = 0; /* first changed line */
|
linenr_T first_line = 0; /* first changed line */
|
||||||
linenr_T last_line = 0; /* last changed line */
|
linenr_T last_line = 0; /* last changed line */
|
||||||
@@ -727,14 +728,23 @@ void ex_retab(exarg_T *eap)
|
|||||||
save_list = curwin->w_p_list;
|
save_list = curwin->w_p_list;
|
||||||
curwin->w_p_list = 0; /* don't want list mode here */
|
curwin->w_p_list = 0; /* don't want list mode here */
|
||||||
|
|
||||||
new_ts = getdigits_int(&(eap->arg), false, -1);
|
new_ts_str = eap->arg;
|
||||||
if (new_ts < 0) {
|
if (!tabstop_set(eap->arg, &new_ts)) {
|
||||||
EMSG(_(e_positive));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (new_ts == 0)
|
while (ascii_isdigit(*(eap->arg)) || *(eap->arg) == ',') {
|
||||||
new_ts = curbuf->b_p_ts;
|
(eap->arg)++;
|
||||||
for (lnum = eap->line1; !got_int && lnum <= eap->line2; ++lnum) {
|
}
|
||||||
|
|
||||||
|
// This ensures that either new_ts and new_ts_str are freshly allocated,
|
||||||
|
// or new_ts points to an existing array and new_ts_str is null.
|
||||||
|
if (new_ts == 0) {
|
||||||
|
new_ts = curbuf->b_p_vts_array;
|
||||||
|
new_ts_str = NULL;
|
||||||
|
} else {
|
||||||
|
new_ts_str = vim_strnsave(new_ts_str, eap->arg - new_ts_str);
|
||||||
|
}
|
||||||
|
for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) {
|
||||||
ptr = ml_get(lnum);
|
ptr = ml_get(lnum);
|
||||||
col = 0;
|
col = 0;
|
||||||
vcol = 0;
|
vcol = 0;
|
||||||
@@ -758,13 +768,14 @@ void ex_retab(exarg_T *eap)
|
|||||||
len = num_spaces = vcol - start_vcol;
|
len = num_spaces = vcol - start_vcol;
|
||||||
num_tabs = 0;
|
num_tabs = 0;
|
||||||
if (!curbuf->b_p_et) {
|
if (!curbuf->b_p_et) {
|
||||||
temp = new_ts - (start_vcol % new_ts);
|
int t, s;
|
||||||
if (num_spaces >= temp) {
|
|
||||||
num_spaces -= temp;
|
tabstop_fromto(start_vcol, vcol,
|
||||||
num_tabs++;
|
tabstop_count(new_ts) ? 0 : curbuf->b_p_ts,
|
||||||
}
|
new_ts,
|
||||||
num_tabs += num_spaces / new_ts;
|
&t, &s);
|
||||||
num_spaces -= (num_spaces / new_ts) * new_ts;
|
num_tabs = t;
|
||||||
|
num_spaces = s;
|
||||||
}
|
}
|
||||||
if (curbuf->b_p_et || got_tab
|
if (curbuf->b_p_et || got_tab
|
||||||
|| (num_spaces + num_tabs < len)) {
|
|| (num_spaces + num_tabs < len)) {
|
||||||
@@ -817,15 +828,42 @@ void ex_retab(exarg_T *eap)
|
|||||||
if (got_int)
|
if (got_int)
|
||||||
EMSG(_(e_interr));
|
EMSG(_(e_interr));
|
||||||
|
|
||||||
if (curbuf->b_p_ts != new_ts)
|
// If a single value was given then it can be considered equal to
|
||||||
|
// either the value of 'tabstop' or the value of 'vartabstop'.
|
||||||
|
if (tabstop_count(curbuf->b_p_vts_array) == 0
|
||||||
|
&& tabstop_count(new_ts) == 1
|
||||||
|
&& curbuf->b_p_ts == tabstop_first(new_ts)) {
|
||||||
|
// not changed
|
||||||
|
} else if (tabstop_count(curbuf->b_p_vts_array) > 0
|
||||||
|
&& tabstop_eq(curbuf->b_p_vts_array, new_ts)) {
|
||||||
|
// not changed
|
||||||
|
} else {
|
||||||
redraw_curbuf_later(NOT_VALID);
|
redraw_curbuf_later(NOT_VALID);
|
||||||
|
}
|
||||||
if (first_line != 0) {
|
if (first_line != 0) {
|
||||||
changed_lines(first_line, 0, last_line + 1, 0L, true);
|
changed_lines(first_line, 0, last_line + 1, 0L, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
curwin->w_p_list = save_list; /* restore 'list' */
|
curwin->w_p_list = save_list; /* restore 'list' */
|
||||||
|
|
||||||
curbuf->b_p_ts = new_ts;
|
if (new_ts_str != NULL) { // set the new tabstop
|
||||||
|
// If 'vartabstop' is in use or if the value given to retab has more
|
||||||
|
// than one tabstop then update 'vartabstop'.
|
||||||
|
long *old_vts_ary = curbuf->b_p_vts_array;
|
||||||
|
|
||||||
|
if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_ts) > 1) {
|
||||||
|
set_string_option_direct("vts", -1, new_ts_str,
|
||||||
|
OPT_FREE | OPT_LOCAL, 0);
|
||||||
|
xfree(new_ts_str);
|
||||||
|
curbuf->b_p_vts_array = new_ts;
|
||||||
|
xfree(old_vts_ary);
|
||||||
|
} else {
|
||||||
|
// 'vartabstop' wasn't in use and a single value was given to
|
||||||
|
// retab then update 'tabstop'.
|
||||||
|
curbuf->b_p_ts = tabstop_first(new_ts);
|
||||||
|
xfree(new_ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
coladvance(curwin->w_curswant);
|
coladvance(curwin->w_curswant);
|
||||||
|
|
||||||
u_clearline();
|
u_clearline();
|
||||||
|
@@ -890,8 +890,11 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
|
|||||||
* Appropriately expand any tabs to spaces.
|
* Appropriately expand any tabs to spaces.
|
||||||
*/
|
*/
|
||||||
if (line[col] == TAB || tab_spaces != 0) {
|
if (line[col] == TAB || tab_spaces != 0) {
|
||||||
if (tab_spaces == 0)
|
if (tab_spaces == 0) {
|
||||||
tab_spaces = (int)(curbuf->b_p_ts - (print_pos % curbuf->b_p_ts));
|
tab_spaces = tabstop_padding(print_pos,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
|
}
|
||||||
|
|
||||||
while (tab_spaces > 0) {
|
while (tab_spaces > 0) {
|
||||||
need_break = mch_print_text_out((char_u *)" ", 1);
|
need_break = mch_print_text_out((char_u *)" ", 1);
|
||||||
|
@@ -34,14 +34,20 @@
|
|||||||
// Count the size (in window cells) of the indent in the current line.
|
// Count the size (in window cells) of the indent in the current line.
|
||||||
int get_indent(void)
|
int get_indent(void)
|
||||||
{
|
{
|
||||||
return get_indent_str(get_cursor_line_ptr(), (int)curbuf->b_p_ts, false);
|
return get_indent_str_vtab(get_cursor_line_ptr(),
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Count the size (in window cells) of the indent in line "lnum".
|
// Count the size (in window cells) of the indent in line "lnum".
|
||||||
int get_indent_lnum(linenr_T lnum)
|
int get_indent_lnum(linenr_T lnum)
|
||||||
{
|
{
|
||||||
return get_indent_str(ml_get(lnum), (int)curbuf->b_p_ts, false);
|
return get_indent_str_vtab(ml_get(lnum),
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -49,7 +55,10 @@ int get_indent_lnum(linenr_T lnum)
|
|||||||
// "buf".
|
// "buf".
|
||||||
int get_indent_buf(buf_T *buf, linenr_T lnum)
|
int get_indent_buf(buf_T *buf, linenr_T lnum)
|
||||||
{
|
{
|
||||||
return get_indent_str(ml_get_buf(buf, lnum, false), (int)buf->b_p_ts, false);
|
return get_indent_str_vtab(ml_get_buf(buf, lnum, false),
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
buf->b_p_vts_array,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -82,6 +91,30 @@ int get_indent_str(const char_u *ptr, int ts, int list)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count the size (in window cells) of the indent in line "ptr", using
|
||||||
|
// variable tabstops.
|
||||||
|
// if "list" is true, count only screen size for tabs.
|
||||||
|
int get_indent_str_vtab(const char_u *ptr, long ts, long *vts, bool list)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (; *ptr; ptr++) {
|
||||||
|
if (*ptr == TAB) { // count a tab for what it is worth
|
||||||
|
if (!list || curwin->w_p_lcs_chars.tab1) {
|
||||||
|
count += tabstop_padding(count, ts, vts);
|
||||||
|
} else {
|
||||||
|
// In list mode, when tab is not set, count screen char width
|
||||||
|
// for Tab, displays: ^I
|
||||||
|
count += ptr2cells(ptr);
|
||||||
|
}
|
||||||
|
} else if (*ptr == ' ') {
|
||||||
|
count++; // count a space for one
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the indent of the current line.
|
// Set the indent of the current line.
|
||||||
// Leaves the cursor on the first non-blank in the line.
|
// Leaves the cursor on the first non-blank in the line.
|
||||||
@@ -104,6 +137,7 @@ int set_indent(int size, int flags)
|
|||||||
int line_len;
|
int line_len;
|
||||||
int doit = false;
|
int doit = false;
|
||||||
int ind_done = 0; // Measured in spaces.
|
int ind_done = 0; // Measured in spaces.
|
||||||
|
int ind_col = 0;
|
||||||
int tab_pad;
|
int tab_pad;
|
||||||
int retval = false;
|
int retval = false;
|
||||||
|
|
||||||
@@ -130,7 +164,9 @@ int set_indent(int size, int flags)
|
|||||||
// Count as many characters as we can use.
|
// Count as many characters as we can use.
|
||||||
while (todo > 0 && ascii_iswhite(*p)) {
|
while (todo > 0 && ascii_iswhite(*p)) {
|
||||||
if (*p == TAB) {
|
if (*p == TAB) {
|
||||||
tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
|
tab_pad = tabstop_padding(ind_done,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
|
|
||||||
// Stop if this tab will overshoot the target.
|
// Stop if this tab will overshoot the target.
|
||||||
if (todo < tab_pad) {
|
if (todo < tab_pad) {
|
||||||
@@ -147,35 +183,41 @@ int set_indent(int size, int flags)
|
|||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These diverge from this point.
|
||||||
|
ind_col = ind_done;
|
||||||
// Set initial number of whitespace chars to copy if we are
|
// Set initial number of whitespace chars to copy if we are
|
||||||
// preserving indent but expandtab is set.
|
// preserving indent but expandtab is set.
|
||||||
if (curbuf->b_p_et) {
|
if (curbuf->b_p_et) {
|
||||||
orig_char_len = ind_len;
|
orig_char_len = ind_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill to next tabstop with a tab, if possible.
|
// Fill to next tabstop with a tab, if possible.
|
||||||
tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
|
tab_pad = tabstop_padding(ind_done,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
if ((todo >= tab_pad) && (orig_char_len == -1)) {
|
if ((todo >= tab_pad) && (orig_char_len == -1)) {
|
||||||
doit = true;
|
doit = true;
|
||||||
todo -= tab_pad;
|
todo -= tab_pad;
|
||||||
ind_len++;
|
ind_len++;
|
||||||
|
|
||||||
// ind_done += tab_pad;
|
// ind_done += tab_pad;
|
||||||
|
ind_col += tab_pad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count tabs required for indent.
|
// Count tabs required for indent.
|
||||||
while (todo >= (int)curbuf->b_p_ts) {
|
for (;;) {
|
||||||
|
tab_pad = tabstop_padding(ind_col, curbuf->b_p_ts, curbuf->b_p_vts_array);
|
||||||
|
if (todo < tab_pad) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (*p != TAB) {
|
if (*p != TAB) {
|
||||||
doit = true;
|
doit = true;
|
||||||
} else {
|
} else {
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
todo -= (int)curbuf->b_p_ts;
|
todo -= tab_pad;
|
||||||
ind_len++;
|
ind_len++;
|
||||||
|
ind_col += tab_pad;
|
||||||
// ind_done += (int)curbuf->b_p_ts;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +297,9 @@ int set_indent(int size, int flags)
|
|||||||
|
|
||||||
while (todo > 0 && ascii_iswhite(*p)) {
|
while (todo > 0 && ascii_iswhite(*p)) {
|
||||||
if (*p == TAB) {
|
if (*p == TAB) {
|
||||||
tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
|
tab_pad = tabstop_padding(ind_done,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
|
|
||||||
// Stop if this tab will overshoot the target.
|
// Stop if this tab will overshoot the target.
|
||||||
if (todo < tab_pad) {
|
if (todo < tab_pad) {
|
||||||
@@ -272,18 +316,28 @@ int set_indent(int size, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fill to next tabstop with a tab, if possible.
|
// Fill to next tabstop with a tab, if possible.
|
||||||
tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
|
tab_pad = tabstop_padding(ind_done,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
|
|
||||||
if (todo >= tab_pad) {
|
if (todo >= tab_pad) {
|
||||||
*s++ = TAB;
|
*s++ = TAB;
|
||||||
todo -= tab_pad;
|
todo -= tab_pad;
|
||||||
|
ind_done += tab_pad;
|
||||||
}
|
}
|
||||||
p = skipwhite(p);
|
p = skipwhite(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (todo >= (int)curbuf->b_p_ts) {
|
for (;;) {
|
||||||
|
tab_pad = tabstop_padding(ind_done,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
|
if (todo < tab_pad) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
*s++ = TAB;
|
*s++ = TAB;
|
||||||
todo -= (int)curbuf->b_p_ts;
|
todo -= tab_pad;
|
||||||
|
ind_done += tab_pad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,6 +441,7 @@ int get_breakindent_win(win_T *wp, const char_u *line)
|
|||||||
static long prev_ts = 0; // Cached tabstop value.
|
static long prev_ts = 0; // Cached tabstop value.
|
||||||
static const char_u *prev_line = NULL; // cached pointer to line.
|
static const char_u *prev_line = NULL; // cached pointer to line.
|
||||||
static varnumber_T prev_tick = 0; // Changedtick of cached value.
|
static varnumber_T prev_tick = 0; // Changedtick of cached value.
|
||||||
|
static long *prev_vts = NULL; // Cached vartabs values.
|
||||||
int bri = 0;
|
int bri = 0;
|
||||||
// window width minus window margin space, i.e. what rests for text
|
// window width minus window margin space, i.e. what rests for text
|
||||||
const int eff_wwidth = wp->w_width_inner
|
const int eff_wwidth = wp->w_width_inner
|
||||||
@@ -396,11 +451,16 @@ int get_breakindent_win(win_T *wp, const char_u *line)
|
|||||||
|
|
||||||
// used cached indent, unless pointer or 'tabstop' changed
|
// used cached indent, unless pointer or 'tabstop' changed
|
||||||
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|
||||||
|| prev_tick != buf_get_changedtick(wp->w_buffer)) {
|
|| prev_tick != buf_get_changedtick(wp->w_buffer)
|
||||||
|
|| prev_vts != wp->w_buffer->b_p_vts_array) {
|
||||||
prev_line = line;
|
prev_line = line;
|
||||||
prev_ts = wp->w_buffer->b_p_ts;
|
prev_ts = wp->w_buffer->b_p_ts;
|
||||||
prev_tick = buf_get_changedtick(wp->w_buffer);
|
prev_tick = buf_get_changedtick(wp->w_buffer);
|
||||||
prev_indent = get_indent_str(line, (int)wp->w_buffer->b_p_ts, wp->w_p_list);
|
prev_vts = wp->w_buffer->b_p_vts_array;
|
||||||
|
prev_indent = get_indent_str_vtab(line,
|
||||||
|
wp->w_buffer->b_p_ts,
|
||||||
|
wp->w_buffer->b_p_vts_array,
|
||||||
|
wp->w_p_list);
|
||||||
}
|
}
|
||||||
bri = prev_indent + wp->w_briopt_shift;
|
bri = prev_indent + wp->w_briopt_shift;
|
||||||
|
|
||||||
|
@@ -1758,7 +1758,9 @@ void msg_prt_line(char_u *s, int list)
|
|||||||
c = *s++;
|
c = *s++;
|
||||||
if (c == TAB && (!list || curwin->w_p_lcs_chars.tab1)) {
|
if (c == TAB && (!list || curwin->w_p_lcs_chars.tab1)) {
|
||||||
// tab amount depends on current column
|
// tab amount depends on current column
|
||||||
n_extra = curbuf->b_p_ts - col % curbuf->b_p_ts - 1;
|
n_extra = tabstop_padding(col,
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array) - 1;
|
||||||
if (!list) {
|
if (!list) {
|
||||||
c = ' ';
|
c = ' ';
|
||||||
c_extra = ' ';
|
c_extra = ' ';
|
||||||
|
@@ -333,7 +333,8 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
char_u *newp;
|
char_u *newp;
|
||||||
const int oldcol = curwin->w_cursor.col;
|
const int oldcol = curwin->w_cursor.col;
|
||||||
const int p_sw = get_sw_value(curbuf);
|
const int p_sw = get_sw_value(curbuf);
|
||||||
const int p_ts = (int)curbuf->b_p_ts;
|
const long p_ts = curbuf->b_p_ts;
|
||||||
|
long *p_vts = curbuf->b_p_vts_array;
|
||||||
struct block_def bd;
|
struct block_def bd;
|
||||||
int incr;
|
int incr;
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
@@ -383,12 +384,11 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
}
|
}
|
||||||
/* OK, now total=all the VWS reqd, and textstart points at the 1st
|
/* OK, now total=all the VWS reqd, and textstart points at the 1st
|
||||||
* non-ws char in the block. */
|
* non-ws char in the block. */
|
||||||
if (!curbuf->b_p_et)
|
if (!curbuf->b_p_et) {
|
||||||
i = ((ws_vcol % p_ts) + total) / p_ts; /* number of tabs */
|
tabstop_fromto(ws_vcol, ws_vcol + total, p_ts, p_vts, &i, &j);
|
||||||
if (i)
|
} else {
|
||||||
j = ((ws_vcol % p_ts) + total) % p_ts; /* number of spp */
|
|
||||||
else
|
|
||||||
j = total;
|
j = total;
|
||||||
|
}
|
||||||
|
|
||||||
// if we're splitting a TAB, allow for it
|
// if we're splitting a TAB, allow for it
|
||||||
int col_pre = bd.pre_whitesp_c - (bd.startspaces != 0);
|
int col_pre = bd.pre_whitesp_c - (bd.startspaces != 0);
|
||||||
@@ -3061,15 +3061,18 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
if (gchar_cursor() == TAB) {
|
if (gchar_cursor() == TAB) {
|
||||||
/* Don't need to insert spaces when "p" on the last position of a
|
/* Don't need to insert spaces when "p" on the last position of a
|
||||||
* tab or "P" on the first position. */
|
* tab or "P" on the first position. */
|
||||||
|
int viscol = getviscol();
|
||||||
if (dir == FORWARD
|
if (dir == FORWARD
|
||||||
? (int)curwin->w_cursor.coladd < curbuf->b_p_ts - 1
|
? tabstop_padding(viscol, curbuf->b_p_ts, curbuf->b_p_vts_array) != 1
|
||||||
: curwin->w_cursor.coladd > 0)
|
: curwin->w_cursor.coladd > 0) {
|
||||||
coladvance_force(getviscol());
|
coladvance_force(viscol);
|
||||||
else
|
} else {
|
||||||
curwin->w_cursor.coladd = 0;
|
curwin->w_cursor.coladd = 0;
|
||||||
} else if (curwin->w_cursor.coladd > 0 || gchar_cursor() == NUL)
|
}
|
||||||
|
} else if (curwin->w_cursor.coladd > 0 || gchar_cursor() == NUL) {
|
||||||
coladvance_force(getviscol() + (dir == FORWARD));
|
coladvance_force(getviscol() + (dir == FORWARD));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lnum = curwin->w_cursor.lnum;
|
lnum = curwin->w_cursor.lnum;
|
||||||
col = curwin->w_cursor.col;
|
col = curwin->w_cursor.col;
|
||||||
|
@@ -180,6 +180,8 @@ static long p_ts;
|
|||||||
static long p_tw;
|
static long p_tw;
|
||||||
static int p_udf;
|
static int p_udf;
|
||||||
static long p_wm;
|
static long p_wm;
|
||||||
|
static char_u *p_vsts;
|
||||||
|
static char_u *p_vts;
|
||||||
static char_u *p_keymap;
|
static char_u *p_keymap;
|
||||||
|
|
||||||
// Saved values for when 'bin' is set.
|
// Saved values for when 'bin' is set.
|
||||||
@@ -194,6 +196,7 @@ static int p_et_nopaste;
|
|||||||
static long p_sts_nopaste;
|
static long p_sts_nopaste;
|
||||||
static long p_tw_nopaste;
|
static long p_tw_nopaste;
|
||||||
static long p_wm_nopaste;
|
static long p_wm_nopaste;
|
||||||
|
static char_u *p_vsts_nopaste;
|
||||||
|
|
||||||
typedef struct vimoption {
|
typedef struct vimoption {
|
||||||
char *fullname; // full option name
|
char *fullname; // full option name
|
||||||
@@ -1998,6 +2001,8 @@ static void didset_options2(void)
|
|||||||
|
|
||||||
// Parse default for 'wildmode'.
|
// Parse default for 'wildmode'.
|
||||||
check_opt_wim();
|
check_opt_wim();
|
||||||
|
tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
|
||||||
|
tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check for string options that are NULL (normally only termcap options).
|
/// Check for string options that are NULL (normally only termcap options).
|
||||||
@@ -2064,6 +2069,8 @@ void check_buf_options(buf_T *buf)
|
|||||||
check_string_option(&buf->b_p_lw);
|
check_string_option(&buf->b_p_lw);
|
||||||
check_string_option(&buf->b_p_bkc);
|
check_string_option(&buf->b_p_bkc);
|
||||||
check_string_option(&buf->b_p_menc);
|
check_string_option(&buf->b_p_menc);
|
||||||
|
check_string_option(&buf->b_p_vsts);
|
||||||
|
check_string_option(&buf->b_p_vts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free the string allocated for an option.
|
/// Free the string allocated for an option.
|
||||||
@@ -3110,6 +3117,69 @@ ambw_end:
|
|||||||
if (opt_strings_flags(p_tpf, p_tpf_values, &tpf_flags, true) != OK) {
|
if (opt_strings_flags(p_tpf, p_tpf_values, &tpf_flags, true) != OK) {
|
||||||
errmsg = e_invarg;
|
errmsg = e_invarg;
|
||||||
}
|
}
|
||||||
|
} else if (varp == &(curbuf->b_p_vsts)) { // 'varsofttabstop'
|
||||||
|
char_u *cp;
|
||||||
|
|
||||||
|
if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1])) {
|
||||||
|
if (curbuf->b_p_vsts_array) {
|
||||||
|
xfree(curbuf->b_p_vsts_array);
|
||||||
|
curbuf->b_p_vsts_array = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (cp = *varp; *cp; cp++) {
|
||||||
|
if (ascii_isdigit(*cp)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*cp == ',' && cp > *varp && *(cp - 1) != ',') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
errmsg = e_invarg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errmsg == NULL) {
|
||||||
|
long *oldarray = curbuf->b_p_vsts_array;
|
||||||
|
if (tabstop_set(*varp, &(curbuf->b_p_vsts_array))) {
|
||||||
|
if (oldarray) {
|
||||||
|
xfree(oldarray);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errmsg = e_invarg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (varp == &(curbuf->b_p_vts)) { // 'vartabstop'
|
||||||
|
char_u *cp;
|
||||||
|
|
||||||
|
if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1])) {
|
||||||
|
if (curbuf->b_p_vts_array) {
|
||||||
|
xfree(curbuf->b_p_vts_array);
|
||||||
|
curbuf->b_p_vts_array = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (cp = *varp; *cp; cp++) {
|
||||||
|
if (ascii_isdigit(*cp)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*cp == ',' && cp > *varp && *(cp - 1) != ',') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
errmsg = e_invarg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errmsg == NULL) {
|
||||||
|
long *oldarray = curbuf->b_p_vts_array;
|
||||||
|
if (tabstop_set(*varp, &(curbuf->b_p_vts_array))) {
|
||||||
|
if (oldarray) {
|
||||||
|
xfree(oldarray);
|
||||||
|
}
|
||||||
|
if (foldmethodIsIndent(curwin)) {
|
||||||
|
foldUpdateAll(curwin);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errmsg = e_invarg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Options that are a list of flags.
|
// Options that are a list of flags.
|
||||||
p = NULL;
|
p = NULL;
|
||||||
@@ -5684,6 +5754,8 @@ static char_u *get_varp(vimoption_T *p)
|
|||||||
case PV_TW: return (char_u *)&(curbuf->b_p_tw);
|
case PV_TW: return (char_u *)&(curbuf->b_p_tw);
|
||||||
case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
|
case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
|
||||||
case PV_WM: return (char_u *)&(curbuf->b_p_wm);
|
case PV_WM: return (char_u *)&(curbuf->b_p_wm);
|
||||||
|
case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts);
|
||||||
|
case PV_VTS: return (char_u *)&(curbuf->b_p_vts);
|
||||||
case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
|
case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
|
||||||
case PV_SCL: return (char_u *)&(curwin->w_p_scl);
|
case PV_SCL: return (char_u *)&(curwin->w_p_scl);
|
||||||
case PV_WINHL: return (char_u *)&(curwin->w_p_winhl);
|
case PV_WINHL: return (char_u *)&(curwin->w_p_winhl);
|
||||||
@@ -5935,6 +6007,15 @@ void buf_copy_options(buf_T *buf, int flags)
|
|||||||
buf->b_p_tfu = vim_strsave(p_tfu);
|
buf->b_p_tfu = vim_strsave(p_tfu);
|
||||||
buf->b_p_sts = p_sts;
|
buf->b_p_sts = p_sts;
|
||||||
buf->b_p_sts_nopaste = p_sts_nopaste;
|
buf->b_p_sts_nopaste = p_sts_nopaste;
|
||||||
|
buf->b_p_vsts = vim_strsave(p_vsts);
|
||||||
|
if (p_vsts && p_vsts != empty_option) {
|
||||||
|
tabstop_set(p_vsts, &buf->b_p_vsts_array);
|
||||||
|
} else {
|
||||||
|
buf->b_p_vsts_array = 0;
|
||||||
|
}
|
||||||
|
buf->b_p_vsts_nopaste = p_vsts_nopaste
|
||||||
|
? vim_strsave(p_vsts_nopaste)
|
||||||
|
: NULL;
|
||||||
buf->b_p_com = vim_strsave(p_com);
|
buf->b_p_com = vim_strsave(p_com);
|
||||||
buf->b_p_cms = vim_strsave(p_cms);
|
buf->b_p_cms = vim_strsave(p_cms);
|
||||||
buf->b_p_fo = vim_strsave(p_fo);
|
buf->b_p_fo = vim_strsave(p_fo);
|
||||||
@@ -6006,10 +6087,21 @@ void buf_copy_options(buf_T *buf, int flags)
|
|||||||
*/
|
*/
|
||||||
if (dont_do_help) {
|
if (dont_do_help) {
|
||||||
buf->b_p_isk = save_p_isk;
|
buf->b_p_isk = save_p_isk;
|
||||||
|
if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) {
|
||||||
|
tabstop_set(p_vts, &buf->b_p_vts_array);
|
||||||
|
} else {
|
||||||
|
buf->b_p_vts_array = NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buf->b_p_isk = vim_strsave(p_isk);
|
buf->b_p_isk = vim_strsave(p_isk);
|
||||||
did_isk = true;
|
did_isk = true;
|
||||||
buf->b_p_ts = p_ts;
|
buf->b_p_ts = p_ts;
|
||||||
|
buf->b_p_vts = vim_strsave(p_vts);
|
||||||
|
if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) {
|
||||||
|
tabstop_set(p_vts, &buf->b_p_vts_array);
|
||||||
|
} else {
|
||||||
|
buf->b_p_vts_array = NULL;
|
||||||
|
}
|
||||||
buf->b_help = false;
|
buf->b_help = false;
|
||||||
if (buf->b_p_bt[0] == 'h') {
|
if (buf->b_p_bt[0] == 'h') {
|
||||||
clear_string_option(&buf->b_p_bt);
|
clear_string_option(&buf->b_p_bt);
|
||||||
@@ -6624,6 +6716,12 @@ static void paste_option_changed(void)
|
|||||||
buf->b_p_sts_nopaste = buf->b_p_sts;
|
buf->b_p_sts_nopaste = buf->b_p_sts;
|
||||||
buf->b_p_ai_nopaste = buf->b_p_ai;
|
buf->b_p_ai_nopaste = buf->b_p_ai;
|
||||||
buf->b_p_et_nopaste = buf->b_p_et;
|
buf->b_p_et_nopaste = buf->b_p_et;
|
||||||
|
if (buf->b_p_vsts_nopaste) {
|
||||||
|
xfree(buf->b_p_vsts_nopaste);
|
||||||
|
}
|
||||||
|
buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option
|
||||||
|
? vim_strsave(buf->b_p_vsts)
|
||||||
|
: NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// save global options
|
// save global options
|
||||||
@@ -6638,6 +6736,12 @@ static void paste_option_changed(void)
|
|||||||
p_sts_nopaste = p_sts;
|
p_sts_nopaste = p_sts;
|
||||||
p_tw_nopaste = p_tw;
|
p_tw_nopaste = p_tw;
|
||||||
p_wm_nopaste = p_wm;
|
p_wm_nopaste = p_wm;
|
||||||
|
if (p_vsts_nopaste) {
|
||||||
|
xfree(p_vsts_nopaste);
|
||||||
|
}
|
||||||
|
p_vsts_nopaste = p_vsts && p_vsts != empty_option
|
||||||
|
? vim_strsave(p_vsts)
|
||||||
|
: NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always set the option values, also when 'paste' is set when it is
|
// Always set the option values, also when 'paste' is set when it is
|
||||||
@@ -6649,6 +6753,14 @@ static void paste_option_changed(void)
|
|||||||
buf->b_p_sts = 0; // softtabstop is 0
|
buf->b_p_sts = 0; // softtabstop is 0
|
||||||
buf->b_p_ai = 0; // no auto-indent
|
buf->b_p_ai = 0; // no auto-indent
|
||||||
buf->b_p_et = 0; // no expandtab
|
buf->b_p_et = 0; // no expandtab
|
||||||
|
if (buf->b_p_vsts) {
|
||||||
|
free_string_option(buf->b_p_vsts);
|
||||||
|
}
|
||||||
|
buf->b_p_vsts = empty_option;
|
||||||
|
if (buf->b_p_vsts_array) {
|
||||||
|
xfree(buf->b_p_vsts_array);
|
||||||
|
}
|
||||||
|
buf->b_p_vsts_array = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set global options
|
// set global options
|
||||||
@@ -6665,6 +6777,10 @@ static void paste_option_changed(void)
|
|||||||
p_wm = 0;
|
p_wm = 0;
|
||||||
p_sts = 0;
|
p_sts = 0;
|
||||||
p_ai = 0;
|
p_ai = 0;
|
||||||
|
if (p_vsts) {
|
||||||
|
free_string_option(p_vsts);
|
||||||
|
}
|
||||||
|
p_vsts = empty_option;
|
||||||
} else if (old_p_paste) {
|
} else if (old_p_paste) {
|
||||||
// Paste switched from on to off: Restore saved values.
|
// Paste switched from on to off: Restore saved values.
|
||||||
|
|
||||||
@@ -6675,6 +6791,20 @@ static void paste_option_changed(void)
|
|||||||
buf->b_p_sts = buf->b_p_sts_nopaste;
|
buf->b_p_sts = buf->b_p_sts_nopaste;
|
||||||
buf->b_p_ai = buf->b_p_ai_nopaste;
|
buf->b_p_ai = buf->b_p_ai_nopaste;
|
||||||
buf->b_p_et = buf->b_p_et_nopaste;
|
buf->b_p_et = buf->b_p_et_nopaste;
|
||||||
|
if (buf->b_p_vsts) {
|
||||||
|
free_string_option(buf->b_p_vsts);
|
||||||
|
}
|
||||||
|
buf->b_p_vsts = buf->b_p_vsts_nopaste
|
||||||
|
? vim_strsave(buf->b_p_vsts_nopaste)
|
||||||
|
: empty_option;
|
||||||
|
if (buf->b_p_vsts_array) {
|
||||||
|
xfree(buf->b_p_vsts_array);
|
||||||
|
}
|
||||||
|
if (buf->b_p_vsts && buf->b_p_vsts != empty_option) {
|
||||||
|
tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
|
||||||
|
} else {
|
||||||
|
buf->b_p_vsts_array = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore global options
|
// restore global options
|
||||||
@@ -6692,6 +6822,10 @@ static void paste_option_changed(void)
|
|||||||
p_sts = p_sts_nopaste;
|
p_sts = p_sts_nopaste;
|
||||||
p_tw = p_tw_nopaste;
|
p_tw = p_tw_nopaste;
|
||||||
p_wm = p_wm_nopaste;
|
p_wm = p_wm_nopaste;
|
||||||
|
if (p_vsts) {
|
||||||
|
free_string_option(p_vsts);
|
||||||
|
}
|
||||||
|
p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_p_paste = p_paste;
|
old_p_paste = p_paste;
|
||||||
@@ -6941,6 +7075,265 @@ int check_ff_value(char_u *p)
|
|||||||
return check_opt_strings(p, p_ff_values, false);
|
return check_opt_strings(p, p_ff_values, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the integer values corresponding to the string setting of 'vartabstop'.
|
||||||
|
// "array" will be set, caller must free it if needed.
|
||||||
|
bool tabstop_set(char_u *var, long **array)
|
||||||
|
{
|
||||||
|
long valcount = 1;
|
||||||
|
int t;
|
||||||
|
char_u *cp;
|
||||||
|
|
||||||
|
if ((!var[0] || (var[0] == '0' && !var[1]))) {
|
||||||
|
*array = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cp = var; *cp; cp++) {
|
||||||
|
if (cp == var || *(cp - 1) == ',') {
|
||||||
|
char_u *end;
|
||||||
|
if (strtol((char *)cp, (char **)&end, 10) <= 0) {
|
||||||
|
if (cp != end) {
|
||||||
|
EMSG(_(e_positive));
|
||||||
|
} else {
|
||||||
|
EMSG(_(e_invarg));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ascii_isdigit(*cp)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*cp == ',' && cp > var && *(cp - 1) != ',') {
|
||||||
|
valcount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EMSG(_(e_invarg));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*array = (long *)xmalloc((unsigned)(valcount + 1) * sizeof(long));
|
||||||
|
(*array)[0] = valcount;
|
||||||
|
|
||||||
|
t = 1;
|
||||||
|
for (cp = var; *cp;) {
|
||||||
|
(*array)[t++] = atoi((char *)cp);
|
||||||
|
while (*cp && *cp != ',') {
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
if (*cp) {
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the number of screen spaces a tab will occupy.
|
||||||
|
// If "vts" is set then the tab widths are taken from that array,
|
||||||
|
// otherwise the value of ts is used.
|
||||||
|
int tabstop_padding(colnr_T col, long ts_arg, long *vts)
|
||||||
|
{
|
||||||
|
long ts = ts_arg == 0 ? 8 : ts_arg;
|
||||||
|
long tabcount;
|
||||||
|
colnr_T tabcol = 0;
|
||||||
|
int t;
|
||||||
|
long padding = 0;
|
||||||
|
|
||||||
|
if (vts == NULL || vts[0] == 0) {
|
||||||
|
return (int)ts - (col % (int)ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
tabcount = vts[0];
|
||||||
|
|
||||||
|
for (t = 1; t <= tabcount; t++) {
|
||||||
|
tabcol += vts[t];
|
||||||
|
if (tabcol > col) {
|
||||||
|
padding = (int)(tabcol - col);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t > tabcount) {
|
||||||
|
padding = vts[tabcount] - (int)((col - tabcol) % vts[tabcount]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the size of the tab that covers a particular column.
|
||||||
|
int tabstop_at(colnr_T col, long ts, long *vts)
|
||||||
|
{
|
||||||
|
int tabcount;
|
||||||
|
colnr_T tabcol = 0;
|
||||||
|
int t;
|
||||||
|
int tab_size = 0;
|
||||||
|
|
||||||
|
if (vts == 0 || vts[0] == 0) {
|
||||||
|
return (int)ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
tabcount = (int)vts[0];
|
||||||
|
for (t = 1; t <= tabcount; t++) {
|
||||||
|
tabcol += vts[t];
|
||||||
|
if (tabcol > col) {
|
||||||
|
tab_size = (int)vts[t];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t > tabcount) {
|
||||||
|
tab_size = (int)vts[tabcount];
|
||||||
|
}
|
||||||
|
|
||||||
|
return tab_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the column on which a tab starts.
|
||||||
|
colnr_T tabstop_start(colnr_T col, long ts, long *vts)
|
||||||
|
{
|
||||||
|
int tabcount;
|
||||||
|
colnr_T tabcol = 0;
|
||||||
|
int t;
|
||||||
|
int excess;
|
||||||
|
|
||||||
|
if (vts == 0 || vts[0] == 0) {
|
||||||
|
return (col / (int)ts) * (int)ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
tabcount = (int)vts[0];
|
||||||
|
for (t = 1; t <= tabcount; t++) {
|
||||||
|
tabcol += vts[t];
|
||||||
|
if (tabcol > col) {
|
||||||
|
return tabcol - (int)vts[t];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
excess = tabcol % vts[tabcount];
|
||||||
|
return excess + ((col - excess) / (int)vts[tabcount]) * (int)vts[tabcount];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the number of tabs and spaces necessary to get from one column
|
||||||
|
// to another.
|
||||||
|
void tabstop_fromto(colnr_T start_col,
|
||||||
|
colnr_T end_col,
|
||||||
|
long ts,
|
||||||
|
long *vts,
|
||||||
|
int *ntabs,
|
||||||
|
int *nspcs)
|
||||||
|
{
|
||||||
|
int spaces = end_col - start_col;
|
||||||
|
colnr_T tabcol = 0;
|
||||||
|
int padding = 0;
|
||||||
|
int tabcount;
|
||||||
|
int t;
|
||||||
|
|
||||||
|
if (vts == 0 || vts[0] == 0) {
|
||||||
|
int tabs = 0;
|
||||||
|
int initspc = (int)ts - (start_col % (int)ts);
|
||||||
|
if (spaces >= initspc) {
|
||||||
|
spaces -= initspc;
|
||||||
|
tabs++;
|
||||||
|
}
|
||||||
|
tabs += spaces / ts;
|
||||||
|
spaces -= (spaces / ts) * ts;
|
||||||
|
|
||||||
|
*ntabs = tabs;
|
||||||
|
*nspcs = spaces;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the padding needed to reach the next tabstop.
|
||||||
|
tabcount = (int)vts[0];
|
||||||
|
for (t = 1; t <= tabcount; t++) {
|
||||||
|
tabcol += vts[t];
|
||||||
|
if (tabcol > start_col) {
|
||||||
|
padding = (int)(tabcol - start_col);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t > tabcount) {
|
||||||
|
padding =
|
||||||
|
(int)vts[tabcount] - (int)((start_col - tabcol) % (int)vts[tabcount]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the space needed is less than the padding no tabs can be used.
|
||||||
|
if (spaces < padding) {
|
||||||
|
*ntabs = 0;
|
||||||
|
*nspcs = spaces;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ntabs = 1;
|
||||||
|
spaces -= padding;
|
||||||
|
|
||||||
|
// At least one tab has been used. See if any more will fit.
|
||||||
|
while (spaces != 0 && ++t <= tabcount) {
|
||||||
|
padding = (int)vts[t];
|
||||||
|
if (spaces < padding) {
|
||||||
|
*nspcs = spaces;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*ntabs += 1;
|
||||||
|
spaces -= padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ntabs += spaces / (int)vts[tabcount];
|
||||||
|
*nspcs = spaces % (int)vts[tabcount];
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if two tabstop arrays contain the same values.
|
||||||
|
bool tabstop_eq(long *ts1, long *ts2)
|
||||||
|
{
|
||||||
|
int t;
|
||||||
|
|
||||||
|
if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ts1 == ts2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ts1[0] != ts2[0]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (t = 1; t <= ts1[0]; t++) {
|
||||||
|
if (ts1[t] != ts2[t]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy a tabstop array, allocating space for the new array.
|
||||||
|
int *tabstop_copy(long *oldts)
|
||||||
|
{
|
||||||
|
long *newts;
|
||||||
|
int t;
|
||||||
|
|
||||||
|
if (oldts == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
newts = xmalloc((unsigned)(oldts[0] + 1) * sizeof(long));
|
||||||
|
for (t = 0; t <= oldts[0]; t++) {
|
||||||
|
newts[t] = oldts[t];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int *)newts;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a count of the number of tabstops.
|
||||||
|
int tabstop_count(long *ts)
|
||||||
|
{
|
||||||
|
return ts != NULL ? (int)ts[0] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the first tabstop, or 8 if there are no tabstops defined.
|
||||||
|
int tabstop_first(long *ts)
|
||||||
|
{
|
||||||
|
return ts != NULL ? (int)ts[1] : 8;
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the effective shiftwidth value for current buffer, using the
|
/// Return the effective shiftwidth value for current buffer, using the
|
||||||
/// 'tabstop' value when 'shiftwidth' is zero.
|
/// 'tabstop' value when 'shiftwidth' is zero.
|
||||||
int get_sw_value(buf_T *buf)
|
int get_sw_value(buf_T *buf)
|
||||||
|
@@ -824,6 +824,8 @@ enum {
|
|||||||
, BV_UDF
|
, BV_UDF
|
||||||
, BV_UL
|
, BV_UL
|
||||||
, BV_WM
|
, BV_WM
|
||||||
|
, BV_VSTS
|
||||||
|
, BV_VTS
|
||||||
, BV_COUNT // must be the last one
|
, BV_COUNT // must be the last one
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -2998,6 +2998,23 @@ return {
|
|||||||
varname='p_ut',
|
varname='p_ut',
|
||||||
defaults={if_true={vi=4000}}
|
defaults={if_true={vi=4000}}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
full_name='varsofttabstop', abbreviation='vsts',
|
||||||
|
short_desc=N_("list of numbers of spaces that <Tab> uses while editing"),
|
||||||
|
type='string', list='comma', scope={'buffer'},
|
||||||
|
vi_def=true,
|
||||||
|
varname='p_vsts',
|
||||||
|
defaults={if_true={vi=""}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
full_name='vartabstop', abbreviation='vts',
|
||||||
|
short_desc=N_("list of numbers of spaces that <Tab> in file uses"),
|
||||||
|
type='string', list='comma', scope={'buffer'},
|
||||||
|
vi_def=true,
|
||||||
|
varname='p_vts',
|
||||||
|
redraw={'current_buffer'},
|
||||||
|
defaults={if_true={vi=""}}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
full_name='verbose', abbreviation='vbs',
|
full_name='verbose', abbreviation='vbs',
|
||||||
short_desc=N_("give informative messages"),
|
short_desc=N_("give informative messages"),
|
||||||
|
@@ -3508,8 +3508,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
vcol_adjusted = vcol - MB_CHARLEN(p_sbr);
|
vcol_adjusted = vcol - MB_CHARLEN(p_sbr);
|
||||||
}
|
}
|
||||||
// tab amount depends on current column
|
// tab amount depends on current column
|
||||||
tab_len = (int)wp->w_buffer->b_p_ts
|
tab_len = tabstop_padding(vcol_adjusted,
|
||||||
- vcol_adjusted % (int)wp->w_buffer->b_p_ts - 1;
|
wp->w_buffer->b_p_ts,
|
||||||
|
wp->w_buffer->b_p_vts_array) - 1;
|
||||||
|
|
||||||
if (!wp->w_p_lbr || !wp->w_p_list) {
|
if (!wp->w_p_lbr || !wp->w_p_list) {
|
||||||
n_extra = tab_len;
|
n_extra = tab_len;
|
||||||
|
@@ -12,56 +12,88 @@ source view_util.vim
|
|||||||
|
|
||||||
let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
|
let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
|
||||||
|
|
||||||
function s:screen_lines(lnum, width) abort
|
func s:screen_lines(lnum, width) abort
|
||||||
return ScreenLines([a:lnum, a:lnum + 2], a:width)
|
return ScreenLines([a:lnum, a:lnum + 2], a:width)
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function! s:compare_lines(expect, actual)
|
func! s:compare_lines(expect, actual)
|
||||||
call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
|
call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function s:test_windows(...)
|
func s:test_windows(...)
|
||||||
call NewWindow(10, 20)
|
call NewWindow(10, 20)
|
||||||
setl ts=4 sw=4 sts=4 breakindent
|
setl ts=4 sw=4 sts=4 breakindent
|
||||||
put =s:input
|
put =s:input
|
||||||
exe get(a:000, 0, '')
|
exe get(a:000, 0, '')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function s:close_windows(...)
|
func s:close_windows(...)
|
||||||
call CloseWindow()
|
call CloseWindow()
|
||||||
exe get(a:000, 0, '')
|
exe get(a:000, 0, '')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent01()
|
func Test_breakindent01()
|
||||||
" simple breakindent test
|
" simple breakindent test
|
||||||
call s:test_windows('setl briopt=min:0')
|
call s:test_windows('setl briopt=min:0')
|
||||||
let lines=s:screen_lines(line('.'),8)
|
let lines = s:screen_lines(line('.'),8)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " abcd",
|
\ " abcd",
|
||||||
\ " qrst",
|
\ " qrst",
|
||||||
\ " GHIJ",
|
\ " GHIJ",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows()
|
call s:close_windows()
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent02()
|
func Test_breakindent01_vartabs()
|
||||||
|
" like 01 but with vartabs feature
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call s:test_windows('setl briopt=min:0 vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),8)
|
||||||
|
let expect = [
|
||||||
|
\ " abcd",
|
||||||
|
\ " qrst",
|
||||||
|
\ " GHIJ",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent02()
|
||||||
" simple breakindent test with showbreak set
|
" simple breakindent test with showbreak set
|
||||||
call s:test_windows('setl briopt=min:0 sbr=>>')
|
call s:test_windows('setl briopt=min:0 sbr=>>')
|
||||||
let lines=s:screen_lines(line('.'),8)
|
let lines = s:screen_lines(line('.'),8)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " abcd",
|
\ " abcd",
|
||||||
\ " >>qr",
|
\ " >>qr",
|
||||||
\ " >>EF",
|
\ " >>EF",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows('set sbr=')
|
call s:close_windows('set sbr=')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent03()
|
func Test_breakindent02_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" simple breakindent test with showbreak set
|
||||||
|
call s:test_windows('setl briopt=min:0 sbr=>> vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),8)
|
||||||
|
let expect = [
|
||||||
|
\ " abcd",
|
||||||
|
\ " >>qr",
|
||||||
|
\ " >>EF",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set sbr= vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent03()
|
||||||
" simple breakindent test with showbreak set and briopt including sbr
|
" simple breakindent test with showbreak set and briopt including sbr
|
||||||
call s:test_windows('setl briopt=sbr,min:0 sbr=++')
|
call s:test_windows('setl briopt=sbr,min:0 sbr=++')
|
||||||
let lines=s:screen_lines(line('.'),8)
|
let lines = s:screen_lines(line('.'),8)
|
||||||
let expect=[
|
let expect=[
|
||||||
\ " abcd",
|
\ " abcd",
|
||||||
\ "++ qrst",
|
\ "++ qrst",
|
||||||
@@ -70,77 +102,177 @@ function Test_breakindent03()
|
|||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
" clean up
|
" clean up
|
||||||
call s:close_windows('set sbr=')
|
call s:close_windows('set sbr=')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent04()
|
func Test_breakindent03_vartabs()
|
||||||
|
" simple breakindent test with showbreak set and briopt including sbr
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call s:test_windows('setl briopt=sbr,min:0 sbr=++ vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),8)
|
||||||
|
let expect = [
|
||||||
|
\ " abcd",
|
||||||
|
\ "++ qrst",
|
||||||
|
\ "++ GHIJ",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
" clean up
|
||||||
|
call s:close_windows('set sbr= vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent04()
|
||||||
" breakindent set with min width 18
|
" breakindent set with min width 18
|
||||||
call s:test_windows('setl sbr= briopt=min:18')
|
call s:test_windows('setl sbr= briopt=min:18')
|
||||||
let lines=s:screen_lines(line('.'),8)
|
let lines = s:screen_lines(line('.'),8)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " abcd",
|
\ " abcd",
|
||||||
\ " qrstuv",
|
\ " qrstuv",
|
||||||
\ " IJKLMN",
|
\ " IJKLMN",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
" clean up
|
" clean up
|
||||||
call s:close_windows('set sbr=')
|
call s:close_windows('set sbr=')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent05()
|
func Test_breakindent04_vartabs()
|
||||||
|
" breakindent set with min width 18
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call s:test_windows('setl sbr= briopt=min:18 vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),8)
|
||||||
|
let expect = [
|
||||||
|
\ " abcd",
|
||||||
|
\ " qrstuv",
|
||||||
|
\ " IJKLMN",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
" clean up
|
||||||
|
call s:close_windows('set sbr= vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent05()
|
||||||
" breakindent set and shift by 2
|
" breakindent set and shift by 2
|
||||||
call s:test_windows('setl briopt=shift:2,min:0')
|
call s:test_windows('setl briopt=shift:2,min:0')
|
||||||
let lines=s:screen_lines(line('.'),8)
|
let lines = s:screen_lines(line('.'),8)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " abcd",
|
\ " abcd",
|
||||||
\ " qr",
|
\ " qr",
|
||||||
\ " EF",
|
\ " EF",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows()
|
call s:close_windows()
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent06()
|
func Test_breakindent05_vartabs()
|
||||||
|
" breakindent set and shift by 2
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call s:test_windows('setl briopt=shift:2,min:0 vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),8)
|
||||||
|
let expect = [
|
||||||
|
\ " abcd",
|
||||||
|
\ " qr",
|
||||||
|
\ " EF",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent06()
|
||||||
" breakindent set and shift by -1
|
" breakindent set and shift by -1
|
||||||
call s:test_windows('setl briopt=shift:-1,min:0')
|
call s:test_windows('setl briopt=shift:-1,min:0')
|
||||||
let lines=s:screen_lines(line('.'),8)
|
let lines = s:screen_lines(line('.'),8)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " abcd",
|
\ " abcd",
|
||||||
\ " qrstu",
|
\ " qrstu",
|
||||||
\ " HIJKL",
|
\ " HIJKL",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows()
|
call s:close_windows()
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent07()
|
func Test_breakindent06_vartabs()
|
||||||
|
" breakindent set and shift by -1
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call s:test_windows('setl briopt=shift:-1,min:0 vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),8)
|
||||||
|
let expect = [
|
||||||
|
\ " abcd",
|
||||||
|
\ " qrstu",
|
||||||
|
\ " HIJKL",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent07()
|
||||||
" breakindent set and shift by 1, Number set sbr=? and briopt:sbr
|
" breakindent set and shift by 1, Number set sbr=? and briopt:sbr
|
||||||
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n')
|
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n')
|
||||||
let lines=s:screen_lines(line('.'),10)
|
let lines = s:screen_lines(line('.'),10)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 2 ab",
|
\ " 2 ab",
|
||||||
\ "? m",
|
\ "? m",
|
||||||
\ "? x",
|
\ "? x",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
" clean up
|
" clean up
|
||||||
call s:close_windows('set sbr= cpo-=n')
|
call s:close_windows('set sbr= cpo-=n')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent07a()
|
func Test_breakindent07_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" breakindent set and shift by 1, Number set sbr=? and briopt:sbr
|
||||||
|
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),10)
|
||||||
|
let expect = [
|
||||||
|
\ " 2 ab",
|
||||||
|
\ "? m",
|
||||||
|
\ "? x",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
" clean up
|
||||||
|
call s:close_windows('set sbr= cpo-=n vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent07a()
|
||||||
" breakindent set and shift by 1, Number set sbr=? and briopt:sbr
|
" breakindent set and shift by 1, Number set sbr=? and briopt:sbr
|
||||||
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4')
|
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4')
|
||||||
let lines=s:screen_lines(line('.'),10)
|
let lines = s:screen_lines(line('.'),10)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 2 ab",
|
\ " 2 ab",
|
||||||
\ " ? m",
|
\ " ? m",
|
||||||
\ " ? x",
|
\ " ? x",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
" clean up
|
" clean up
|
||||||
call s:close_windows('set sbr=')
|
call s:close_windows('set sbr=')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent08()
|
func Test_breakindent07a_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" breakindent set and shift by 1, Number set sbr=? and briopt:sbr
|
||||||
|
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),10)
|
||||||
|
let expect = [
|
||||||
|
\ " 2 ab",
|
||||||
|
\ " ? m",
|
||||||
|
\ " ? x",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
" clean up
|
||||||
|
call s:close_windows('set sbr= vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent08()
|
||||||
" breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
|
" breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
|
||||||
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4')
|
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4')
|
||||||
" make sure, cache is invalidated!
|
" make sure, cache is invalidated!
|
||||||
@@ -148,43 +280,96 @@ function Test_breakindent08()
|
|||||||
redraw!
|
redraw!
|
||||||
set ts=4
|
set ts=4
|
||||||
redraw!
|
redraw!
|
||||||
let lines=s:screen_lines(line('.'),10)
|
let lines = s:screen_lines(line('.'),10)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 2 ^Iabcd",
|
\ " 2 ^Iabcd",
|
||||||
\ "# opq",
|
\ "# opq",
|
||||||
\ "# BCD",
|
\ "# BCD",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows('set sbr= cpo-=n')
|
call s:close_windows('set sbr= cpo-=n')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent08a()
|
func Test_breakindent08_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
|
||||||
|
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4 vts=4')
|
||||||
|
" make sure, cache is invalidated!
|
||||||
|
set ts=8
|
||||||
|
redraw!
|
||||||
|
set ts=4
|
||||||
|
redraw!
|
||||||
|
let lines = s:screen_lines(line('.'),10)
|
||||||
|
let expect = [
|
||||||
|
\ " 2 ^Iabcd",
|
||||||
|
\ "# opq",
|
||||||
|
\ "# BCD",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set sbr= cpo-=n vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent08a()
|
||||||
" breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
|
" breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
|
||||||
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list')
|
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list')
|
||||||
let lines=s:screen_lines(line('.'),10)
|
let lines = s:screen_lines(line('.'),10)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 2 ^Iabcd",
|
\ " 2 ^Iabcd",
|
||||||
\ " # opq",
|
\ " # opq",
|
||||||
\ " # BCD",
|
\ " # BCD",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows('set sbr=')
|
call s:close_windows('set sbr=')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent09()
|
func Test_breakindent08a_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
|
||||||
|
call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),10)
|
||||||
|
let expect = [
|
||||||
|
\ " 2 ^Iabcd",
|
||||||
|
\ " # opq",
|
||||||
|
\ " # BCD",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set sbr= vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent09()
|
||||||
" breakindent set and shift by 1, Number and list set sbr=#
|
" breakindent set and shift by 1, Number and list set sbr=#
|
||||||
call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list')
|
call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list')
|
||||||
let lines=s:screen_lines(line('.'),10)
|
let lines = s:screen_lines(line('.'),10)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 2 ^Iabcd",
|
\ " 2 ^Iabcd",
|
||||||
\ " #op",
|
\ " #op",
|
||||||
\ " #AB",
|
\ " #AB",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows('set sbr=')
|
call s:close_windows('set sbr=')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent10()
|
func Test_breakindent09_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" breakindent set and shift by 1, Number and list set sbr=#
|
||||||
|
call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list vts=4')
|
||||||
|
let lines = s:screen_lines(line('.'),10)
|
||||||
|
let expect = [
|
||||||
|
\ " 2 ^Iabcd",
|
||||||
|
\ " #op",
|
||||||
|
\ " #AB",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set sbr= vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent10()
|
||||||
" breakindent set, Number set sbr=~
|
" breakindent set, Number set sbr=~
|
||||||
call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0')
|
call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0')
|
||||||
" make sure, cache is invalidated!
|
" make sure, cache is invalidated!
|
||||||
@@ -192,41 +377,91 @@ function Test_breakindent10()
|
|||||||
redraw!
|
redraw!
|
||||||
set ts=4
|
set ts=4
|
||||||
redraw!
|
redraw!
|
||||||
let lines=s:screen_lines(line('.'),10)
|
let lines = s:screen_lines(line('.'),10)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 2 ab",
|
\ " 2 ab",
|
||||||
\ "~ mn",
|
\ "~ mn",
|
||||||
\ "~ yz",
|
\ "~ yz",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows('set sbr= cpo-=n')
|
call s:close_windows('set sbr= cpo-=n')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent11()
|
func Test_breakindent10_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" breakindent set, Number set sbr=~
|
||||||
|
call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0 vts=4')
|
||||||
|
" make sure, cache is invalidated!
|
||||||
|
set ts=8
|
||||||
|
redraw!
|
||||||
|
set ts=4
|
||||||
|
redraw!
|
||||||
|
let lines = s:screen_lines(line('.'),10)
|
||||||
|
let expect = [
|
||||||
|
\ " 2 ab",
|
||||||
|
\ "~ mn",
|
||||||
|
\ "~ yz",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set sbr= cpo-=n vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent11()
|
||||||
" test strdisplaywidth()
|
" test strdisplaywidth()
|
||||||
call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4')
|
call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4')
|
||||||
let text=getline(2)
|
let text=getline(2)
|
||||||
let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times
|
let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times
|
||||||
call assert_equal(width, strdisplaywidth(text))
|
call assert_equal(width, strdisplaywidth(text))
|
||||||
call s:close_windows('set sbr=')
|
call s:close_windows('set sbr=')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent12()
|
func Test_breakindent11_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" test strdisplaywidth()
|
||||||
|
call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4 vts=4')
|
||||||
|
let text = getline(2)
|
||||||
|
let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times
|
||||||
|
call assert_equal(width, strdisplaywidth(text))
|
||||||
|
call s:close_windows('set sbr= vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent12()
|
||||||
" test breakindent with long indent
|
" test breakindent with long indent
|
||||||
let s:input="\t\t\t\t\t{"
|
let s:input="\t\t\t\t\t{"
|
||||||
call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-')
|
call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-')
|
||||||
let lines=s:screen_lines(2,16)
|
let lines = s:screen_lines(2,16)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 2 >--->--->--->",
|
\ " 2 >--->--->--->",
|
||||||
\ " ---{ ",
|
\ " ---{ ",
|
||||||
\ "~ ",
|
\ "~ ",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows('set nuw=4 listchars=')
|
call s:close_windows('set nuw=4 listchars=')
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent13()
|
func Test_breakindent12_vartabs()
|
||||||
let s:input=""
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" test breakindent with long indent
|
||||||
|
let s:input = "\t\t\t\t\t{"
|
||||||
|
call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>- vts=4')
|
||||||
|
let lines = s:screen_lines(2,16)
|
||||||
|
let expect = [
|
||||||
|
\ " 2 >--->--->--->",
|
||||||
|
\ " ---{ ",
|
||||||
|
\ "~ ",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set nuw=4 listchars= vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent13()
|
||||||
|
let s:input = ""
|
||||||
call s:test_windows('setl breakindent briopt=min:10 ts=8')
|
call s:test_windows('setl breakindent briopt=min:10 ts=8')
|
||||||
vert resize 20
|
vert resize 20
|
||||||
call setline(1, [" a\tb\tc\td\te", " z y x w v"])
|
call setline(1, [" a\tb\tc\td\te", " z y x w v"])
|
||||||
@@ -237,65 +472,149 @@ function Test_breakindent13()
|
|||||||
call assert_equal('d', @a)
|
call assert_equal('d', @a)
|
||||||
call assert_equal('w', @b)
|
call assert_equal('w', @b)
|
||||||
call s:close_windows()
|
call s:close_windows()
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent14()
|
func Test_breakindent13_vartabs()
|
||||||
let s:input=""
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let s:input = ""
|
||||||
|
call s:test_windows('setl breakindent briopt=min:10 ts=8 vts=8')
|
||||||
|
vert resize 20
|
||||||
|
call setline(1, [" a\tb\tc\td\te", " z y x w v"])
|
||||||
|
1
|
||||||
|
norm! fbgj"ayl
|
||||||
|
2
|
||||||
|
norm! fygj"byl
|
||||||
|
call assert_equal('d', @a)
|
||||||
|
call assert_equal('w', @b)
|
||||||
|
call s:close_windows('set vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent14()
|
||||||
|
let s:input = ""
|
||||||
call s:test_windows('setl breakindent briopt= ts=8')
|
call s:test_windows('setl breakindent briopt= ts=8')
|
||||||
vert resize 30
|
vert resize 30
|
||||||
norm! 3a1234567890
|
norm! 3a1234567890
|
||||||
norm! a abcde
|
norm! a abcde
|
||||||
exec "norm! 0\<C-V>tex"
|
exec "norm! 0\<C-V>tex"
|
||||||
let lines=s:screen_lines(line('.'),8)
|
let lines = s:screen_lines(line('.'),8)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ "e ",
|
\ "e ",
|
||||||
\ "~ ",
|
\ "~ ",
|
||||||
\ "~ ",
|
\ "~ ",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows()
|
call s:close_windows()
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent15()
|
func Test_breakindent14_vartabs()
|
||||||
let s:input=""
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let s:input = ""
|
||||||
|
call s:test_windows('setl breakindent briopt= ts=8 vts=8')
|
||||||
|
vert resize 30
|
||||||
|
norm! 3a1234567890
|
||||||
|
norm! a abcde
|
||||||
|
exec "norm! 0\<C-V>tex"
|
||||||
|
let lines = s:screen_lines(line('.'),8)
|
||||||
|
let expect = [
|
||||||
|
\ "e ",
|
||||||
|
\ "~ ",
|
||||||
|
\ "~ ",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent15()
|
||||||
|
let s:input = ""
|
||||||
call s:test_windows('setl breakindent briopt= ts=8 sw=8')
|
call s:test_windows('setl breakindent briopt= ts=8 sw=8')
|
||||||
vert resize 30
|
vert resize 30
|
||||||
norm! 4a1234567890
|
norm! 4a1234567890
|
||||||
exe "normal! >>\<C-V>3f0x"
|
exe "normal! >>\<C-V>3f0x"
|
||||||
let lines=s:screen_lines(line('.'),20)
|
let lines = s:screen_lines(line('.'),20)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 1234567890 ",
|
\ " 1234567890 ",
|
||||||
\ "~ ",
|
\ "~ ",
|
||||||
\ "~ ",
|
\ "~ ",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows()
|
call s:close_windows()
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
function Test_breakindent16()
|
func Test_breakindent15_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let s:input = ""
|
||||||
|
call s:test_windows('setl breakindent briopt= ts=8 sw=8 vts=8')
|
||||||
|
vert resize 30
|
||||||
|
norm! 4a1234567890
|
||||||
|
exe "normal! >>\<C-V>3f0x"
|
||||||
|
let lines = s:screen_lines(line('.'),20)
|
||||||
|
let expect = [
|
||||||
|
\ " 1234567890 ",
|
||||||
|
\ "~ ",
|
||||||
|
\ "~ ",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent16()
|
||||||
" Check that overlong lines are indented correctly.
|
" Check that overlong lines are indented correctly.
|
||||||
let s:input=""
|
let s:input = ""
|
||||||
call s:test_windows('setl breakindent briopt=min:0 ts=4')
|
call s:test_windows('setl breakindent briopt=min:0 ts=4')
|
||||||
call setline(1, "\t".repeat("1234567890", 10))
|
call setline(1, "\t".repeat("1234567890", 10))
|
||||||
resize 6
|
resize 6
|
||||||
norm! 1gg$
|
norm! 1gg$
|
||||||
redraw!
|
redraw!
|
||||||
let lines=s:screen_lines(1,10)
|
let lines = s:screen_lines(1,10)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 789012",
|
\ " 789012",
|
||||||
\ " 345678",
|
\ " 345678",
|
||||||
\ " 901234",
|
\ " 901234",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
let lines=s:screen_lines(4,10)
|
let lines = s:screen_lines(4,10)
|
||||||
let expect=[
|
let expect = [
|
||||||
\ " 567890",
|
\ " 567890",
|
||||||
\ " 123456",
|
\ " 123456",
|
||||||
\ " 7890 ",
|
\ " 7890 ",
|
||||||
\ ]
|
\ ]
|
||||||
call s:compare_lines(expect, lines)
|
call s:compare_lines(expect, lines)
|
||||||
call s:close_windows()
|
call s:close_windows()
|
||||||
endfunction
|
endfunc
|
||||||
|
|
||||||
|
func Test_breakindent16_vartabs()
|
||||||
|
if !has("vartabs")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" Check that overlong lines are indented correctly.
|
||||||
|
let s:input = ""
|
||||||
|
call s:test_windows('setl breakindent briopt=min:0 ts=4 vts=4')
|
||||||
|
call setline(1, "\t".repeat("1234567890", 10))
|
||||||
|
resize 6
|
||||||
|
norm! 1gg$
|
||||||
|
redraw!
|
||||||
|
let lines = s:screen_lines(1,10)
|
||||||
|
let expect = [
|
||||||
|
\ " 789012",
|
||||||
|
\ " 345678",
|
||||||
|
\ " 901234",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
let lines = s:screen_lines(4,10)
|
||||||
|
let expect = [
|
||||||
|
\ " 567890",
|
||||||
|
\ " 123456",
|
||||||
|
\ " 7890 ",
|
||||||
|
\ ]
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
call s:close_windows('set vts&')
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_breakindent17_vartabs()
|
func Test_breakindent17_vartabs()
|
||||||
if !has("vartabs")
|
if !has("vartabs")
|
||||||
|
257
src/nvim/testdir/test_vartabs.vim
Normal file
257
src/nvim/testdir/test_vartabs.vim
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
" Test for variable tabstops
|
||||||
|
|
||||||
|
if !has("vartabs")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
func! Test_vartabs()
|
||||||
|
new
|
||||||
|
%d
|
||||||
|
|
||||||
|
" Test normal operation of tabstops ...
|
||||||
|
set ts=4
|
||||||
|
call setline(1, join(split('aaaaa', '\zs'), "\t"))
|
||||||
|
retab 8
|
||||||
|
let expect = "a a\<tab>a a\<tab>a"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" ... and softtabstops
|
||||||
|
set ts=8 sts=6
|
||||||
|
exe "norm! Sb\<tab>b\<tab>b\<tab>b\<tab>b"
|
||||||
|
let expect = "b b\<tab> b\<tab> b\<tab>b"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Test variable tabstops.
|
||||||
|
set sts=0 vts=4,8,4,8
|
||||||
|
exe "norm! Sc\<tab>c\<tab>c\<tab>c\<tab>c\<tab>c"
|
||||||
|
retab 8
|
||||||
|
let expect = "c c\<tab> c\<tab>c\<tab>c\<tab>c"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
set et vts=4,8,4,8
|
||||||
|
exe "norm! Sd\<tab>d\<tab>d\<tab>d\<tab>d\<tab>d"
|
||||||
|
let expect = "d d d d d d"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Changing ts should have no effect if vts is in use.
|
||||||
|
call cursor(1, 1)
|
||||||
|
set ts=6
|
||||||
|
exe "norm! Se\<tab>e\<tab>e\<tab>e\<tab>e\<tab>e"
|
||||||
|
let expect = "e e e e e e"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Clearing vts should revert to using ts.
|
||||||
|
set vts=
|
||||||
|
exe "norm! Sf\<tab>f\<tab>f\<tab>f\<tab>f\<tab>f"
|
||||||
|
let expect = "f f f f f f"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Test variable softtabstops.
|
||||||
|
set noet ts=8 vsts=12,2,6
|
||||||
|
exe "norm! Sg\<tab>g\<tab>g\<tab>g\<tab>g\<tab>g"
|
||||||
|
let expect = "g\<tab> g g\<tab> g\<tab> g\<tab>g"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Variable tabstops and softtabstops combined.
|
||||||
|
set vsts=6,12,8 vts=4,6,8
|
||||||
|
exe "norm! Sh\<tab>h\<tab>h\<tab>h\<tab>h"
|
||||||
|
let expect = "h\<tab> h\<tab>\<tab>h\<tab>h\<tab>h"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Retab with a single value, not using vts.
|
||||||
|
set ts=8 sts=0 vts= vsts=
|
||||||
|
exe "norm! Si\<tab>i\<tab>i\<tab>i\<tab>i"
|
||||||
|
retab 4
|
||||||
|
let expect = "i\<tab>\<tab>i\<tab>\<tab>i\<tab>\<tab>i\<tab>\<tab>i"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Retab with a single value, using vts.
|
||||||
|
set ts=8 sts=0 vts=6 vsts=
|
||||||
|
exe "norm! Sj\<tab>j\<tab>j\<tab>j\<tab>j"
|
||||||
|
retab 4
|
||||||
|
let expect = "j\<tab> j\<tab>\<tab>j\<tab> j\<tab>\<tab>j"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Retab with multiple values, not using vts.
|
||||||
|
set ts=6 sts=0 vts= vsts=
|
||||||
|
exe "norm! Sk\<tab>k\<tab>k\<tab>k\<tab>k\<tab>k"
|
||||||
|
retab 4,8
|
||||||
|
let expect = "k\<tab> k\<tab>k k\<tab> k\<tab> k"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Retab with multiple values, using vts.
|
||||||
|
set ts=8 sts=0 vts=6 vsts=
|
||||||
|
exe "norm! Sl\<tab>l\<tab>l\<tab>l\<tab>l\<tab>l"
|
||||||
|
retab 4,8
|
||||||
|
let expect = "l\<tab> l\<tab>l l\<tab> l\<tab> l"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Check that global and local values are set.
|
||||||
|
set ts=4 vts=6 sts=8 vsts=10
|
||||||
|
call assert_equal(&ts, 4)
|
||||||
|
call assert_equal(&vts, '6')
|
||||||
|
call assert_equal(&sts, 8)
|
||||||
|
call assert_equal(&vsts, '10')
|
||||||
|
new
|
||||||
|
call assert_equal(&ts, 4)
|
||||||
|
call assert_equal(&vts, '6')
|
||||||
|
call assert_equal(&sts, 8)
|
||||||
|
call assert_equal(&vsts, '10')
|
||||||
|
bwipeout!
|
||||||
|
|
||||||
|
" Check that local values only are set.
|
||||||
|
setlocal ts=5 vts=7 sts=9 vsts=11
|
||||||
|
call assert_equal(&ts, 5)
|
||||||
|
call assert_equal(&vts, '7')
|
||||||
|
call assert_equal(&sts, 9)
|
||||||
|
call assert_equal(&vsts, '11')
|
||||||
|
new
|
||||||
|
call assert_equal(&ts, 4)
|
||||||
|
call assert_equal(&vts, '6')
|
||||||
|
call assert_equal(&sts, 8)
|
||||||
|
call assert_equal(&vsts, '10')
|
||||||
|
bwipeout!
|
||||||
|
|
||||||
|
" Check that global values only are set.
|
||||||
|
setglobal ts=6 vts=8 sts=10 vsts=12
|
||||||
|
call assert_equal(&ts, 5)
|
||||||
|
call assert_equal(&vts, '7')
|
||||||
|
call assert_equal(&sts, 9)
|
||||||
|
call assert_equal(&vsts, '11')
|
||||||
|
new
|
||||||
|
call assert_equal(&ts, 6)
|
||||||
|
call assert_equal(&vts, '8')
|
||||||
|
call assert_equal(&sts, 10)
|
||||||
|
call assert_equal(&vsts, '12')
|
||||||
|
bwipeout!
|
||||||
|
|
||||||
|
set ts& vts& sts& vsts& et&
|
||||||
|
bwipeout!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_vartabs_breakindent()
|
||||||
|
if !exists("+breakindent")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
new
|
||||||
|
%d
|
||||||
|
|
||||||
|
" Test normal operation of tabstops ...
|
||||||
|
set ts=4
|
||||||
|
call setline(1, join(split('aaaaa', '\zs'), "\t"))
|
||||||
|
retab 8
|
||||||
|
let expect = "a a\<tab>a a\<tab>a"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" ... and softtabstops
|
||||||
|
set ts=8 sts=6
|
||||||
|
exe "norm! Sb\<tab>b\<tab>b\<tab>b\<tab>b"
|
||||||
|
let expect = "b b\<tab> b\<tab> b\<tab>b"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Test variable tabstops.
|
||||||
|
set sts=0 vts=4,8,4,8
|
||||||
|
exe "norm! Sc\<tab>c\<tab>c\<tab>c\<tab>c\<tab>c"
|
||||||
|
retab 8
|
||||||
|
let expect = "c c\<tab> c\<tab>c\<tab>c\<tab>c"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
set et vts=4,8,4,8
|
||||||
|
exe "norm! Sd\<tab>d\<tab>d\<tab>d\<tab>d\<tab>d"
|
||||||
|
let expect = "d d d d d d"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Changing ts should have no effect if vts is in use.
|
||||||
|
call cursor(1, 1)
|
||||||
|
set ts=6
|
||||||
|
exe "norm! Se\<tab>e\<tab>e\<tab>e\<tab>e\<tab>e"
|
||||||
|
let expect = "e e e e e e"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Clearing vts should revert to using ts.
|
||||||
|
set vts=
|
||||||
|
exe "norm! Sf\<tab>f\<tab>f\<tab>f\<tab>f\<tab>f"
|
||||||
|
let expect = "f f f f f f"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Test variable softtabstops.
|
||||||
|
set noet ts=8 vsts=12,2,6
|
||||||
|
exe "norm! Sg\<tab>g\<tab>g\<tab>g\<tab>g\<tab>g"
|
||||||
|
let expect = "g\<tab> g g\<tab> g\<tab> g\<tab>g"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Variable tabstops and softtabstops combined.
|
||||||
|
set vsts=6,12,8 vts=4,6,8
|
||||||
|
exe "norm! Sh\<tab>h\<tab>h\<tab>h\<tab>h"
|
||||||
|
let expect = "h\<tab> h\<tab>\<tab>h\<tab>h\<tab>h"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Retab with a single value, not using vts.
|
||||||
|
set ts=8 sts=0 vts= vsts=
|
||||||
|
exe "norm! Si\<tab>i\<tab>i\<tab>i\<tab>i"
|
||||||
|
retab 4
|
||||||
|
let expect = "i\<tab>\<tab>i\<tab>\<tab>i\<tab>\<tab>i\<tab>\<tab>i"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Retab with a single value, using vts.
|
||||||
|
set ts=8 sts=0 vts=6 vsts=
|
||||||
|
exe "norm! Sj\<tab>j\<tab>j\<tab>j\<tab>j"
|
||||||
|
retab 4
|
||||||
|
let expect = "j\<tab> j\<tab>\<tab>j\<tab> j\<tab>\<tab>j"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Retab with multiple values, not using vts.
|
||||||
|
set ts=6 sts=0 vts= vsts=
|
||||||
|
exe "norm! Sk\<tab>k\<tab>k\<tab>k\<tab>k\<tab>k"
|
||||||
|
retab 4,8
|
||||||
|
let expect = "k\<tab> k\<tab>k k\<tab> k\<tab> k"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Retab with multiple values, using vts.
|
||||||
|
set ts=8 sts=0 vts=6 vsts=
|
||||||
|
exe "norm! Sl\<tab>l\<tab>l\<tab>l\<tab>l\<tab>l"
|
||||||
|
retab 4,8
|
||||||
|
let expect = "l\<tab> l\<tab>l l\<tab> l\<tab> l"
|
||||||
|
call assert_equal(expect, getline(1))
|
||||||
|
|
||||||
|
" Check that global and local values are set.
|
||||||
|
set ts=4 vts=6 sts=8 vsts=10
|
||||||
|
call assert_equal(&ts, 4)
|
||||||
|
call assert_equal(&vts, '6')
|
||||||
|
call assert_equal(&sts, 8)
|
||||||
|
call assert_equal(&vsts, '10')
|
||||||
|
new
|
||||||
|
call assert_equal(&ts, 4)
|
||||||
|
call assert_equal(&vts, '6')
|
||||||
|
call assert_equal(&sts, 8)
|
||||||
|
call assert_equal(&vsts, '10')
|
||||||
|
bwipeout!
|
||||||
|
|
||||||
|
" Check that local values only are set.
|
||||||
|
setlocal ts=5 vts=7 sts=9 vsts=11
|
||||||
|
call assert_equal(&ts, 5)
|
||||||
|
call assert_equal(&vts, '7')
|
||||||
|
call assert_equal(&sts, 9)
|
||||||
|
call assert_equal(&vsts, '11')
|
||||||
|
new
|
||||||
|
call assert_equal(&ts, 4)
|
||||||
|
call assert_equal(&vts, '6')
|
||||||
|
call assert_equal(&sts, 8)
|
||||||
|
call assert_equal(&vsts, '10')
|
||||||
|
bwipeout!
|
||||||
|
|
||||||
|
" Check that global values only are set.
|
||||||
|
setglobal ts=6 vts=8 sts=10 vsts=12
|
||||||
|
call assert_equal(&ts, 5)
|
||||||
|
call assert_equal(&vts, '7')
|
||||||
|
call assert_equal(&sts, 9)
|
||||||
|
call assert_equal(&vsts, '11')
|
||||||
|
new
|
||||||
|
call assert_equal(&ts, 6)
|
||||||
|
call assert_equal(&vts, '8')
|
||||||
|
call assert_equal(&sts, 10)
|
||||||
|
call assert_equal(&vsts, '12')
|
||||||
|
bwipeout!
|
||||||
|
|
||||||
|
bwipeout!
|
||||||
|
endfunc
|
@@ -24,8 +24,6 @@ describe('Ex cmds', function()
|
|||||||
pcall_err(command, ':menu 9999999999999999999999999999999999999999'))
|
pcall_err(command, ':menu 9999999999999999999999999999999999999999'))
|
||||||
eq('Vim(bdelete):E939: Positive count required',
|
eq('Vim(bdelete):E939: Positive count required',
|
||||||
pcall_err(command, ':bdelete 9999999999999999999999999999999999999999'))
|
pcall_err(command, ':bdelete 9999999999999999999999999999999999999999'))
|
||||||
eq('Vim(retab):E487: Argument must be positive',
|
|
||||||
pcall_err(command, ':retab 9999999999999999999999999999999999999999'))
|
|
||||||
assert_alive()
|
assert_alive()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
Reference in New Issue
Block a user