mirror of
https://github.com/zoriya/vim.git
synced 2025-12-19 21:55:18 +00:00
patch 8.1.0542: shiftwidth() does not take 'vartabstop' into account
Problem: shiftwidth() does not take 'vartabstop' into account.
Solution: Use the cursor position or a position explicitly passed.
Also make >> and << work better with 'vartabstop'. (Christian
Brabandt)
This commit is contained in:
@@ -476,6 +476,10 @@ SHIFTING LINES LEFT OR RIGHT *shift-left-right*
|
|||||||
*<*
|
*<*
|
||||||
<{motion} Shift {motion} lines one 'shiftwidth' leftwards.
|
<{motion} Shift {motion} lines one 'shiftwidth' leftwards.
|
||||||
|
|
||||||
|
If the 'vartabstop' feature is enabled, and 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.
|
||||||
|
|
||||||
@@ -487,6 +491,10 @@ SHIFTING LINES LEFT OR RIGHT *shift-left-right*
|
|||||||
*>*
|
*>*
|
||||||
>{motion} Shift {motion} lines one 'shiftwidth' rightwards.
|
>{motion} Shift {motion} lines one 'shiftwidth' rightwards.
|
||||||
|
|
||||||
|
If the 'vartabstop' feature is enabled, and 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.
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -2386,7 +2385,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([{list}]) Number effective value of 'shiftwidth'
|
shiftwidth([{col}]) Number effective value of 'shiftwidth'
|
||||||
simplify({filename}) String simplify filename as much as possible
|
simplify({filename}) String simplify filename as much as possible
|
||||||
sin({expr}) Float sine of {expr}
|
sin({expr}) Float sine of {expr}
|
||||||
sinh({expr}) Float hyperbolic sine of {expr}
|
sinh({expr}) Float hyperbolic sine of {expr}
|
||||||
@@ -7639,19 +7638,17 @@ shellescape({string} [, {special}]) *shellescape()*
|
|||||||
< See also |::S|.
|
< See also |::S|.
|
||||||
|
|
||||||
|
|
||||||
shiftwidth([{list}]) *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. This function was introduced with patch
|
'tabstop' value. This function was introduced with patch
|
||||||
7.3.694 in 2012, everybody should have it by now.
|
7.3.694 in 2012, everybody should have it by now (however it
|
||||||
|
did not allow for the optional {col} argument until 8.1.542).
|
||||||
|
|
||||||
When there is one argument {list} this is used as position
|
When there is one argument {col} this is used as column number
|
||||||
|List| for which to return the 'shiftwidth' value (actually
|
for which to return the 'shiftwidth' value. This matters for the
|
||||||
only the column number is relevant). This matters for the
|
'vartabstop' feature. If the 'vartabstop' setting is enabled and
|
||||||
'vartabstop' feature. For the {list} arguments see |cursor()|
|
no {col} argument is given, column 1 will be assumed.
|
||||||
function. If the 'vartabstop' setting is enabled and no
|
|
||||||
{list} argument is given, the current cursor position is
|
|
||||||
taken into account.
|
|
||||||
|
|
||||||
|
|
||||||
simplify({filename}) *simplify()*
|
simplify({filename}) *simplify()*
|
||||||
|
|||||||
@@ -262,7 +262,6 @@ static int ins_ctrl_ey(int tc);
|
|||||||
#ifdef FEAT_SMARTINDENT
|
#ifdef FEAT_SMARTINDENT
|
||||||
static void ins_try_si(int c);
|
static void ins_try_si(int c);
|
||||||
#endif
|
#endif
|
||||||
static colnr_T get_nolist_virtcol(void);
|
|
||||||
#if defined(FEAT_EVAL)
|
#if defined(FEAT_EVAL)
|
||||||
static char_u *do_insert_char_pre(int c);
|
static char_u *do_insert_char_pre(int c);
|
||||||
#endif
|
#endif
|
||||||
@@ -10681,9 +10680,14 @@ 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
|
colnr_T
|
||||||
get_nolist_virtcol(void)
|
get_nolist_virtcol(void)
|
||||||
{
|
{
|
||||||
|
// 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)
|
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();
|
||||||
|
|||||||
@@ -835,7 +835,7 @@ static struct fst
|
|||||||
{"sha256", 1, 1, f_sha256},
|
{"sha256", 1, 1, f_sha256},
|
||||||
#endif
|
#endif
|
||||||
{"shellescape", 1, 2, f_shellescape},
|
{"shellescape", 1, 2, f_shellescape},
|
||||||
{"shiftwidth", 0, 0, f_shiftwidth},
|
{"shiftwidth", 0, 1, f_shiftwidth},
|
||||||
{"simplify", 1, 1, f_simplify},
|
{"simplify", 1, 1, f_simplify},
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
{"sin", 1, 1, f_sin},
|
{"sin", 1, 1, f_sin},
|
||||||
@@ -11241,6 +11241,21 @@ f_shellescape(typval_T *argvars, typval_T *rettv)
|
|||||||
static void
|
static void
|
||||||
f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv)
|
f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
{
|
{
|
||||||
|
rettv->vval.v_number = 0;
|
||||||
|
|
||||||
|
if (argvars[0].v_type != VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
long col;
|
||||||
|
|
||||||
|
col = (long)get_tv_number_chk(argvars, NULL);
|
||||||
|
if (col < 0)
|
||||||
|
return; // type error; errmsg already given
|
||||||
|
#ifdef FEAT_VARTABS
|
||||||
|
rettv->vval.v_number = get_sw_value_col(curbuf, col);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
rettv->vval.v_number = get_sw_value(curbuf);
|
rettv->vval.v_number = get_sw_value(curbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8143,6 +8143,7 @@ nv_g_cmd(cmdarg_T *cap)
|
|||||||
do
|
do
|
||||||
i = gchar_cursor();
|
i = gchar_cursor();
|
||||||
while (VIM_ISWHITE(i) && oneright() == OK);
|
while (VIM_ISWHITE(i) && oneright() == OK);
|
||||||
|
curwin->w_valid &= ~VALID_WCOL;
|
||||||
}
|
}
|
||||||
curwin->w_set_curswant = TRUE;
|
curwin->w_set_curswant = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ shift_line(
|
|||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
int i, j;
|
int i, j;
|
||||||
int p_sw = (int)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 */
|
||||||
|
|
||||||
@@ -386,7 +386,7 @@ shift_block(oparg_T *oap, int amount)
|
|||||||
int total;
|
int total;
|
||||||
char_u *newp, *oldp;
|
char_u *newp, *oldp;
|
||||||
int oldcol = curwin->w_cursor.col;
|
int oldcol = curwin->w_cursor.col;
|
||||||
int p_sw = (int)get_sw_value(curbuf);
|
int p_sw = (int)get_sw_value_indent(curbuf);
|
||||||
#ifdef FEAT_VARTABS
|
#ifdef FEAT_VARTABS
|
||||||
int *p_vts = curbuf->b_p_vts_array;
|
int *p_vts = curbuf->b_p_vts_array;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
43
src/option.c
43
src/option.c
@@ -13113,7 +13113,48 @@ tabstop_first(int *ts)
|
|||||||
long
|
long
|
||||||
get_sw_value(buf_T *buf)
|
get_sw_value(buf_T *buf)
|
||||||
{
|
{
|
||||||
return buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts;
|
return get_sw_value_col(buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = 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 UNUSED)
|
||||||
|
{
|
||||||
|
return buf->b_p_sw ? buf->b_p_sw :
|
||||||
|
#ifdef FEAT_VARTABS
|
||||||
|
tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array);
|
||||||
|
#else
|
||||||
|
buf->b_p_ts;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -46,4 +46,5 @@ int bracketed_paste(paste_mode_T mode, int drop, garray_T *gap);
|
|||||||
void ins_scroll(void);
|
void ins_scroll(void);
|
||||||
void ins_horscroll(void);
|
void ins_horscroll(void);
|
||||||
int ins_copychar(linenr_T lnum);
|
int ins_copychar(linenr_T lnum);
|
||||||
|
colnr_T get_nolist_virtcol(void);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ int *tabstop_copy(int *oldts);
|
|||||||
int tabstop_count(int *ts);
|
int tabstop_count(int *ts);
|
||||||
int tabstop_first(int *ts);
|
int tabstop_first(int *ts);
|
||||||
long get_sw_value(buf_T *buf);
|
long get_sw_value(buf_T *buf);
|
||||||
|
long get_sw_value_indent(buf_T *buf);
|
||||||
|
long get_sw_value_pos(buf_T *buf, pos_T *pos);
|
||||||
|
long get_sw_value_col(buf_T *buf, colnr_T col);
|
||||||
long get_sts_value(void);
|
long get_sts_value(void);
|
||||||
void find_mps_values(int *initc, int *findc, int *backwards, int switchit);
|
void find_mps_values(int *initc, int *findc, int *backwards, int switchit);
|
||||||
unsigned int get_bkc_value(buf_T *buf);
|
unsigned int get_bkc_value(buf_T *buf);
|
||||||
|
|||||||
@@ -297,6 +297,71 @@ func Test_vartabs_linebreak()
|
|||||||
set nolist listchars&vim
|
set nolist listchars&vim
|
||||||
endfunc
|
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()
|
func Test_vartabs_failures()
|
||||||
call assert_fails('set vts=8,')
|
call assert_fails('set vts=8,')
|
||||||
call assert_fails('set vsts=8,')
|
call assert_fails('set vsts=8,')
|
||||||
|
|||||||
@@ -792,6 +792,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
542,
|
||||||
/**/
|
/**/
|
||||||
541,
|
541,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user