mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #13851 from VVKot/vim-8.1.0105
vim-patch:8.1.{0105,0114,0116,0126,0138,0154,0479,0542,0936}
This commit is contained in:
commit
63c2a7af2d
@ -445,6 +445,9 @@ SHIFTING LINES LEFT OR RIGHT *shift-left-right*
|
|||||||
*<*
|
*<*
|
||||||
<{motion} Shift {motion} lines one 'shiftwidth' leftwards.
|
<{motion} Shift {motion} lines one 'shiftwidth' leftwards.
|
||||||
|
|
||||||
|
If the 'shiftwidth' option is set to zero, the amount
|
||||||
|
of indent is calculated at the first non-blank
|
||||||
|
character in the line.
|
||||||
*<<*
|
*<<*
|
||||||
<< Shift [count] lines one 'shiftwidth' leftwards.
|
<< Shift [count] lines one 'shiftwidth' leftwards.
|
||||||
|
|
||||||
@ -455,6 +458,9 @@ SHIFTING LINES LEFT OR RIGHT *shift-left-right*
|
|||||||
*>*
|
*>*
|
||||||
>{motion} Shift {motion} lines one 'shiftwidth' rightwards.
|
>{motion} Shift {motion} lines one 'shiftwidth' rightwards.
|
||||||
|
|
||||||
|
If the 'shiftwidth' option is set to zero, the amount
|
||||||
|
of indent is calculated at the first non-blank
|
||||||
|
character in the line.
|
||||||
*>>*
|
*>>*
|
||||||
>> Shift [count] lines one 'shiftwidth' rightwards.
|
>> Shift [count] lines one 'shiftwidth' rightwards.
|
||||||
|
|
||||||
@ -934,6 +940,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
|
||||||
|
@ -2308,7 +2308,6 @@ perleval({expr}) any evaluate |perl| expression
|
|||||||
pow({x}, {y}) Float {x} to the power of {y}
|
pow({x}, {y}) Float {x} to the power of {y}
|
||||||
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
|
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
|
||||||
printf({fmt}, {expr1}...) String format text
|
printf({fmt}, {expr1}...) String format text
|
||||||
prompt_addtext({buf}, {expr}) none add text to a prompt buffer
|
|
||||||
prompt_setcallback({buf}, {expr}) none set prompt callback function
|
prompt_setcallback({buf}, {expr}) none set prompt callback function
|
||||||
prompt_setinterrupt({buf}, {text}) none set prompt interrupt function
|
prompt_setinterrupt({buf}, {text}) none set prompt interrupt function
|
||||||
prompt_setprompt({buf}, {text}) none set prompt text
|
prompt_setprompt({buf}, {text}) none set prompt text
|
||||||
@ -2393,7 +2392,7 @@ sha256({string}) String SHA256 checksum of {string}
|
|||||||
shellescape({string} [, {special}])
|
shellescape({string} [, {special}])
|
||||||
String escape {string} for use as shell
|
String escape {string} for use as shell
|
||||||
command argument
|
command argument
|
||||||
shiftwidth() Number effective value of 'shiftwidth'
|
shiftwidth([{col}]) Number effective value of 'shiftwidth'
|
||||||
sign_define({name} [, {dict}]) Number define or update a sign
|
sign_define({name} [, {dict}]) Number define or update a sign
|
||||||
sign_getdefined([{name}]) List get a list of defined signs
|
sign_getdefined([{name}]) List get a list of defined signs
|
||||||
sign_getplaced([{expr} [, {dict}]])
|
sign_getplaced([{expr} [, {dict}]])
|
||||||
@ -7899,7 +7898,7 @@ shellescape({string} [, {special}]) *shellescape()*
|
|||||||
< See also |::S|.
|
< See also |::S|.
|
||||||
|
|
||||||
|
|
||||||
shiftwidth() *shiftwidth()*
|
shiftwidth([{col}]) *shiftwidth()*
|
||||||
Returns the effective value of 'shiftwidth'. This is the
|
Returns the effective value of 'shiftwidth'. This is the
|
||||||
'shiftwidth' value unless it is zero, in which case it is the
|
'shiftwidth' value unless it is zero, in which case it is the
|
||||||
'tabstop' value. To be backwards compatible in indent
|
'tabstop' value. To be backwards compatible in indent
|
||||||
@ -7915,6 +7914,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,17 @@ 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);
|
||||||
|
XFREE_CLEAR(buf->b_p_vts_array);
|
||||||
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 +5386,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 +5397,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,12 +880,20 @@ 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 (;;) {
|
||||||
ind_len++;
|
tab_pad = tabstop_padding(ind_col,
|
||||||
|
curbuf->b_p_ts,
|
||||||
if (p != NULL) {
|
curbuf->b_p_vts_array);
|
||||||
*p++ = TAB;
|
if (todo < tab_pad) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
todo -= tab_pad;
|
||||||
|
ind_len++;
|
||||||
|
ind_col += tab_pad;
|
||||||
|
if (p != NULL) {
|
||||||
|
*p++ = TAB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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,20 @@ 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
|
||||||
&& curwin->w_cursor.col > 0
|
|| tabstop_count(curbuf->b_p_vsts_array))
|
||||||
&& (*(get_cursor_pos_ptr() - 1) == TAB
|
&& curwin->w_cursor.col > 0
|
||||||
|| (*(get_cursor_pos_ptr() - 1) == ' '
|
&& (*(get_cursor_pos_ptr() - 1) == TAB
|
||||||
&& (!*inserted_space_p
|
|| (*(get_cursor_pos_ptr() - 1) == ' '
|
||||||
|| arrow_used)))))) {
|
&& (!*inserted_space_p || arrow_used)))))) {
|
||||||
int ts;
|
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 +8203,14 @@ 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) {
|
||||||
|
ts = (int)get_sw_value(curbuf);
|
||||||
|
want_vcol = (want_vcol / ts) * ts;
|
||||||
|
} else {
|
||||||
|
want_vcol = tabstop_start(want_vcol,
|
||||||
|
get_sts_value(),
|
||||||
|
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 +8675,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,16 +8701,22 @@ 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)get_sw_value(curbuf);
|
||||||
} else if (curbuf->b_p_sts != 0) { // use "softtabstop" when set
|
temp -= get_nolist_virtcol() % temp;
|
||||||
temp = get_sts_value();
|
} else if (tabstop_count(curbuf->b_p_vsts_array) > 0
|
||||||
} else { // otherwise use "tabstop"
|
|| curbuf->b_p_sts != 0) {
|
||||||
temp = (int)curbuf->b_p_ts;
|
// use 'softtabstop' when set
|
||||||
|
temp = tabstop_padding(get_nolist_virtcol(),
|
||||||
|
get_sts_value(),
|
||||||
|
curbuf->b_p_vsts_array);
|
||||||
|
} else {
|
||||||
|
// otherwise use 'tabstop'
|
||||||
|
temp = tabstop_padding(get_nolist_virtcol(),
|
||||||
|
curbuf->b_p_ts,
|
||||||
|
curbuf->b_p_vts_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
temp -= get_nolist_virtcol() % temp;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
* replace mode. Insert the rest with ins_str(); it will not delete any
|
* replace mode. Insert the rest with ins_str(); it will not delete any
|
||||||
@ -8716,7 +8737,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;
|
||||||
@ -9133,10 +9156,16 @@ static void ins_try_si(int c)
|
|||||||
* Get the value that w_virtcol would have when 'list' is off.
|
* Get the value that w_virtcol would have when 'list' is off.
|
||||||
* Unless 'cpo' contains the 'L' flag.
|
* Unless 'cpo' contains the 'L' flag.
|
||||||
*/
|
*/
|
||||||
static colnr_T get_nolist_virtcol(void)
|
colnr_T get_nolist_virtcol(void)
|
||||||
{
|
{
|
||||||
if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL)
|
// check validity of cursor in current buffer
|
||||||
|
if (curwin->w_buffer == NULL || curwin->w_buffer->b_ml.ml_mfp == NULL
|
||||||
|
|| curwin->w_cursor.lnum > curwin->w_buffer->b_ml.ml_line_count) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL) {
|
||||||
return getvcol_nolist(&curwin->w_cursor);
|
return getvcol_nolist(&curwin->w_cursor);
|
||||||
|
}
|
||||||
validate_virtcol();
|
validate_virtcol();
|
||||||
return curwin->w_virtcol;
|
return curwin->w_virtcol;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ return {
|
|||||||
setwinvar={args=3},
|
setwinvar={args=3},
|
||||||
sha256={args=1},
|
sha256={args=1},
|
||||||
shellescape={args={1, 2}},
|
shellescape={args={1, 2}},
|
||||||
shiftwidth={},
|
shiftwidth={args={0, 1}},
|
||||||
sign_define={args={1, 2}},
|
sign_define={args={1, 2}},
|
||||||
sign_getdefined={args={0, 1}},
|
sign_getdefined={args={0, 1}},
|
||||||
sign_getplaced={args={0, 2}},
|
sign_getplaced={args={0, 2}},
|
||||||
|
@ -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",
|
||||||
@ -8848,6 +8849,18 @@ static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
*/
|
*/
|
||||||
static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||||
{
|
{
|
||||||
|
rettv->vval.v_number = 0;
|
||||||
|
|
||||||
|
if (argvars[0].v_type != VAR_UNKNOWN) {
|
||||||
|
long col;
|
||||||
|
|
||||||
|
col = (long)tv_get_number_chk(argvars, NULL);
|
||||||
|
if (col < 0) {
|
||||||
|
return; // type error; errmsg already given
|
||||||
|
}
|
||||||
|
rettv->vval.v_number = get_sw_value_col(curbuf, col);
|
||||||
|
return;
|
||||||
|
}
|
||||||
rettv->vval.v_number = get_sw_value(curbuf);
|
rettv->vval.v_number = get_sw_value(curbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_vts_array = NULL;
|
||||||
|
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,24 @@ 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_vts_array)) {
|
||||||
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_vts_array and new_ts_str are freshly
|
||||||
|
// allocated, or new_vts_array points to an existing array and new_ts_str
|
||||||
|
// is null.
|
||||||
|
if (new_vts_array == NULL) {
|
||||||
|
new_vts_array = 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 +769,12 @@ 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++;
|
curbuf->b_p_ts, new_vts_array, &t, &s);
|
||||||
}
|
num_tabs = t;
|
||||||
num_tabs += num_spaces / new_ts;
|
num_spaces = s;
|
||||||
num_spaces -= (num_spaces / new_ts) * new_ts;
|
|
||||||
}
|
}
|
||||||
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 +827,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_vts_array) == 1
|
||||||
|
&& curbuf->b_p_ts == tabstop_first(new_vts_array)) {
|
||||||
|
// not changed
|
||||||
|
} else if (tabstop_count(curbuf->b_p_vts_array) > 0
|
||||||
|
&& tabstop_eq(curbuf->b_p_vts_array, new_vts_array)) {
|
||||||
|
// 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_vts_array) > 1) {
|
||||||
|
set_string_option_direct("vts", -1, new_ts_str,
|
||||||
|
OPT_FREE | OPT_LOCAL, 0);
|
||||||
|
curbuf->b_p_vts_array = new_vts_array;
|
||||||
|
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_vts_array);
|
||||||
|
xfree(new_vts_array);
|
||||||
|
}
|
||||||
|
xfree(new_ts_str);
|
||||||
|
}
|
||||||
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 = ' ';
|
||||||
|
@ -6777,9 +6777,10 @@ static void nv_g_cmd(cmdarg_T *cap)
|
|||||||
}
|
}
|
||||||
coladvance((colnr_T)i);
|
coladvance((colnr_T)i);
|
||||||
if (flag) {
|
if (flag) {
|
||||||
do
|
do {
|
||||||
i = gchar_cursor();
|
i = gchar_cursor();
|
||||||
while (ascii_iswhite(i) && oneright());
|
} while (ascii_iswhite(i) && oneright());
|
||||||
|
curwin->w_valid &= ~VALID_WCOL;
|
||||||
}
|
}
|
||||||
curwin->w_set_curswant = true;
|
curwin->w_set_curswant = true;
|
||||||
break;
|
break;
|
||||||
|
@ -288,7 +288,7 @@ void shift_line(
|
|||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
int i, j;
|
int i, j;
|
||||||
int p_sw = get_sw_value(curbuf);
|
int p_sw = (int)get_sw_value_indent(curbuf);
|
||||||
|
|
||||||
count = get_indent(); // get current indent
|
count = get_indent(); // get current indent
|
||||||
|
|
||||||
@ -332,8 +332,9 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
const int oldstate = State;
|
const int oldstate = State;
|
||||||
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);
|
int p_sw = (int)get_sw_value_indent(curbuf);
|
||||||
const int p_ts = (int)curbuf->b_p_ts;
|
long *p_vts = curbuf->b_p_vts_array;
|
||||||
|
const long p_ts = curbuf->b_p_ts;
|
||||||
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,14 +3061,17 @@ 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;
|
||||||
|
@ -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,67 @@ 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))) {
|
||||||
|
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 +5752,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 +6005,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 +6085,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 +6714,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 +6734,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 +6751,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 +6775,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 +6789,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 +6820,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,17 +7073,308 @@ 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] == NUL || (var[0] == '0' && var[1] == NUL)) {
|
||||||
|
*array = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cp = var; *cp != NUL; 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[0] == ',' && cp > var && cp[-1] != ',' && cp[1] != NUL) {
|
||||||
|
valcount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EMSG(_(e_invarg));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*array = (long *)xmalloc((unsigned)(valcount + 1) * sizeof(long));
|
||||||
|
(*array)[0] = valcount;
|
||||||
|
|
||||||
|
t = 1;
|
||||||
|
for (cp = var; *cp != NUL;) {
|
||||||
|
(*array)[t++] = atoi((char *)cp);
|
||||||
|
while (*cp != NUL && *cp != ',') {
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
if (*cp != NUL) {
|
||||||
|
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 == NULL || 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 == NULL || 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_arg,
|
||||||
|
long *vts,
|
||||||
|
int *ntabs,
|
||||||
|
int *nspcs)
|
||||||
|
{
|
||||||
|
int spaces = end_col - start_col;
|
||||||
|
colnr_T tabcol = 0;
|
||||||
|
int padding = 0;
|
||||||
|
int tabcount;
|
||||||
|
int t;
|
||||||
|
long ts = ts_arg == 0 ? curbuf->b_p_ts : ts_arg;
|
||||||
|
|
||||||
|
if (vts == NULL || vts[0] == 0) {
|
||||||
|
int tabs = 0;
|
||||||
|
int initspc = 0;
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
long result = buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts;
|
long result = get_sw_value_col(buf, 0);
|
||||||
assert(result >= 0 && result <= INT_MAX);
|
assert(result >= 0 && result <= INT_MAX);
|
||||||
return (int)result;
|
return (int)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Idem, using the first non-black in the current line.
|
||||||
|
long get_sw_value_indent(buf_T *buf)
|
||||||
|
{
|
||||||
|
pos_T pos = curwin->w_cursor;
|
||||||
|
|
||||||
|
pos.col = (colnr_T)getwhitecols_curline();
|
||||||
|
return get_sw_value_pos(buf, &pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idem, using "pos".
|
||||||
|
long get_sw_value_pos(buf_T *buf, pos_T *pos)
|
||||||
|
{
|
||||||
|
pos_T save_cursor = curwin->w_cursor;
|
||||||
|
long sw_value;
|
||||||
|
|
||||||
|
curwin->w_cursor = *pos;
|
||||||
|
sw_value = get_sw_value_col(buf, get_nolist_virtcol());
|
||||||
|
curwin->w_cursor = save_cursor;
|
||||||
|
return sw_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idem, using virtual column "col".
|
||||||
|
long get_sw_value_col(buf_T *buf, colnr_T col)
|
||||||
|
{
|
||||||
|
return buf->b_p_sw ? buf->b_p_sw
|
||||||
|
: tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array);
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the effective softtabstop value for the current buffer,
|
/// Return the effective softtabstop value for the current buffer,
|
||||||
/// using the effective shiftwidth value when 'softtabstop' is negative.
|
/// using the shiftwidth value when 'softtabstop' is negative.
|
||||||
int get_sts_value(void)
|
int get_sts_value(void)
|
||||||
{
|
{
|
||||||
long result = curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
|
long result = curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
|
||||||
|
@ -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"),
|
||||||
|
@ -3441,8 +3441,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
// TODO: is passing p for start of the line OK?
|
// TODO: is passing p for start of the line OK?
|
||||||
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1;
|
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1;
|
||||||
if (c == TAB && n_extra + col > grid->Columns) {
|
if (c == TAB && n_extra + col > grid->Columns) {
|
||||||
n_extra = (int)wp->w_buffer->b_p_ts
|
n_extra = tabstop_padding(vcol, wp->w_buffer->b_p_ts,
|
||||||
- vcol % (int)wp->w_buffer->b_p_ts - 1;
|
wp->w_buffer->b_p_vts_array) - 1;
|
||||||
}
|
}
|
||||||
c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' ';
|
c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' ';
|
||||||
c_final = NUL;
|
c_final = NUL;
|
||||||
@ -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;
|
||||||
@ -3542,6 +3543,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
xfree(p_extra_free);
|
xfree(p_extra_free);
|
||||||
p_extra_free = p;
|
p_extra_free = p;
|
||||||
for (i = 0; i < tab_len; i++) {
|
for (i = 0; i < tab_len; i++) {
|
||||||
|
if (*p == NUL) {
|
||||||
|
tab_len = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
int lcs = wp->w_p_lcs_chars.tab2;
|
int lcs = wp->w_p_lcs_chars.tab2;
|
||||||
|
|
||||||
// if tab3 is given, need to change the char
|
// if tab3 is given, need to change the char
|
||||||
|
@ -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")
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
" Various tests for inserting a Tab.
|
||||||
|
|
||||||
" Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set.
|
" Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set.
|
||||||
" Also test that dv_ works correctly
|
" Also test that dv_ works correctly
|
||||||
@ -43,3 +44,47 @@ func Test_smarttab()
|
|||||||
enew!
|
enew!
|
||||||
set expandtab& smartindent& copyindent& ts& sw& sts&
|
set expandtab& smartindent& copyindent& ts& sw& sts&
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_softtabstop()
|
||||||
|
new
|
||||||
|
set sts=0 sw=0
|
||||||
|
exe "normal ix\<Tab>x\<Esc>"
|
||||||
|
call assert_equal("x\tx", getline(1))
|
||||||
|
|
||||||
|
call setline(1, '')
|
||||||
|
set sts=4
|
||||||
|
exe "normal ix\<Tab>x\<Esc>"
|
||||||
|
call assert_equal("x x", getline(1))
|
||||||
|
|
||||||
|
call setline(1, '')
|
||||||
|
set sts=-1 sw=4
|
||||||
|
exe "normal ix\<Tab>x\<Esc>"
|
||||||
|
call assert_equal("x x", getline(1))
|
||||||
|
|
||||||
|
call setline(1, 'x ')
|
||||||
|
set sts=0 sw=0 backspace=start
|
||||||
|
exe "normal A\<BS>x\<Esc>"
|
||||||
|
call assert_equal("x x", getline(1))
|
||||||
|
|
||||||
|
call setline(1, 'x ')
|
||||||
|
set sts=4
|
||||||
|
exe "normal A\<BS>x\<Esc>"
|
||||||
|
call assert_equal("x x", getline(1))
|
||||||
|
|
||||||
|
call setline(1, 'x ')
|
||||||
|
set sts=-1 sw=4
|
||||||
|
exe "normal A\<BS>x\<Esc>"
|
||||||
|
call assert_equal("x x", getline(1))
|
||||||
|
|
||||||
|
call setline(1, 'x')
|
||||||
|
set sts=-1 sw=0 smarttab
|
||||||
|
exe "normal I\<Tab>\<Esc>"
|
||||||
|
call assert_equal("\tx", getline(1))
|
||||||
|
|
||||||
|
call setline(1, 'x')
|
||||||
|
exe "normal I\<Tab>\<BS>\<Esc>"
|
||||||
|
call assert_equal("x", getline(1))
|
||||||
|
|
||||||
|
set sts=0 sw=0 backspace& nosmarttab
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
374
src/nvim/testdir/test_vartabs.vim
Normal file
374
src/nvim/testdir/test_vartabs.vim
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
" Test for variable tabstops
|
||||||
|
|
||||||
|
if !has("vartabs")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
source view_util.vim
|
||||||
|
func s:compare_lines(expect, actual)
|
||||||
|
call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
func Test_vartabs_linebreak()
|
||||||
|
if winwidth(0) < 40
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
new
|
||||||
|
40vnew
|
||||||
|
%d
|
||||||
|
setl linebreak vartabstop=10,20,30,40
|
||||||
|
call setline(1, "\tx\tx\tx\tx")
|
||||||
|
|
||||||
|
let expect = [' x ',
|
||||||
|
\ 'x x ',
|
||||||
|
\ 'x ']
|
||||||
|
let lines = ScreenLines([1, 3], winwidth(0))
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
setl list listchars=tab:>-
|
||||||
|
let expect = ['>---------x>------------------ ',
|
||||||
|
\ 'x>------------------x>------------------',
|
||||||
|
\ 'x ']
|
||||||
|
let lines = ScreenLines([1, 3], winwidth(0))
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
setl linebreak vartabstop=40
|
||||||
|
let expect = ['>---------------------------------------',
|
||||||
|
\ 'x>--------------------------------------',
|
||||||
|
\ 'x>--------------------------------------',
|
||||||
|
\ 'x>--------------------------------------',
|
||||||
|
\ 'x ']
|
||||||
|
let lines = ScreenLines([1, 5], winwidth(0))
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
|
||||||
|
" cleanup
|
||||||
|
bw!
|
||||||
|
bw!
|
||||||
|
set nolist listchars&vim
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_vartabs_shiftwidth()
|
||||||
|
"return
|
||||||
|
if winwidth(0) < 40
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
new
|
||||||
|
40vnew
|
||||||
|
%d
|
||||||
|
" setl varsofttabstop=10,20,30,40
|
||||||
|
setl shiftwidth=0 vartabstop=10,20,30,40
|
||||||
|
call setline(1, "x")
|
||||||
|
|
||||||
|
" Check without any change.
|
||||||
|
let expect = ['x ']
|
||||||
|
let lines = ScreenLines(1, winwidth(0))
|
||||||
|
call s:compare_lines(expect, lines)
|
||||||
|
" Test 1:
|
||||||
|
" shiftwidth depends on the indent, first check with cursor at the end of the
|
||||||
|
" line (which is the same as the start of the line, since there is only one
|
||||||
|
" character).
|
||||||
|
norm! $>>
|
||||||
|
let expect1 = [' x ']
|
||||||
|
let lines = ScreenLines(1, winwidth(0))
|
||||||
|
call s:compare_lines(expect1, lines)
|
||||||
|
call assert_equal(10, shiftwidth())
|
||||||
|
call assert_equal(10, shiftwidth(1))
|
||||||
|
call assert_equal(20, shiftwidth(virtcol('.')))
|
||||||
|
norm! $>>
|
||||||
|
let expect2 = [' x ', '~ ']
|
||||||
|
let lines = ScreenLines([1, 2], winwidth(0))
|
||||||
|
call s:compare_lines(expect2, lines)
|
||||||
|
call assert_equal(20, shiftwidth(virtcol('.')-2))
|
||||||
|
call assert_equal(30, shiftwidth(virtcol('.')))
|
||||||
|
norm! $>>
|
||||||
|
let expect3 = [' ', ' x ', '~ ']
|
||||||
|
let lines = ScreenLines([1, 3], winwidth(0))
|
||||||
|
call s:compare_lines(expect3, lines)
|
||||||
|
call assert_equal(30, shiftwidth(virtcol('.')-2))
|
||||||
|
call assert_equal(40, shiftwidth(virtcol('.')))
|
||||||
|
norm! $>>
|
||||||
|
let expect4 = [' ', ' ', ' x ']
|
||||||
|
let lines = ScreenLines([1, 3], winwidth(0))
|
||||||
|
call assert_equal(40, shiftwidth(virtcol('.')))
|
||||||
|
call s:compare_lines(expect4, lines)
|
||||||
|
|
||||||
|
" Test 2: Put the cursor at the first column, result should be the same
|
||||||
|
call setline(1, "x")
|
||||||
|
norm! 0>>
|
||||||
|
let lines = ScreenLines(1, winwidth(0))
|
||||||
|
call s:compare_lines(expect1, lines)
|
||||||
|
norm! 0>>
|
||||||
|
let lines = ScreenLines([1, 2], winwidth(0))
|
||||||
|
call s:compare_lines(expect2, lines)
|
||||||
|
norm! 0>>
|
||||||
|
let lines = ScreenLines([1, 3], winwidth(0))
|
||||||
|
call s:compare_lines(expect3, lines)
|
||||||
|
norm! 0>>
|
||||||
|
let lines = ScreenLines([1, 3], winwidth(0))
|
||||||
|
call s:compare_lines(expect4, lines)
|
||||||
|
|
||||||
|
" cleanup
|
||||||
|
bw!
|
||||||
|
bw!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_vartabs_failures()
|
||||||
|
call assert_fails('set vts=8,')
|
||||||
|
call assert_fails('set vsts=8,')
|
||||||
|
call assert_fails('set vts=8,,8')
|
||||||
|
call assert_fails('set vsts=8,,8')
|
||||||
|
call assert_fails('set vts=8,,8,')
|
||||||
|
call assert_fails('set vsts=8,,8,')
|
||||||
|
call assert_fails('set vts=,8')
|
||||||
|
call assert_fails('set vsts=,8')
|
||||||
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user