forked from aniani/vim
patch 8.2.4950: text properties position wrong after shifting text
Problem: Text properties position wrong after shifting text. Solution: Adjust the text properties when shifting a block of text. (closes #10418)
This commit is contained in:
43
src/ops.c
43
src/ops.c
@@ -286,8 +286,9 @@ shift_block(oparg_T *oap, int amount)
|
|||||||
struct block_def bd;
|
struct block_def bd;
|
||||||
int incr;
|
int incr;
|
||||||
colnr_T ws_vcol;
|
colnr_T ws_vcol;
|
||||||
int i = 0, j = 0;
|
int added;
|
||||||
int len;
|
unsigned new_line_len; // the length of the line after the
|
||||||
|
// block shift
|
||||||
#ifdef FEAT_RIGHTLEFT
|
#ifdef FEAT_RIGHTLEFT
|
||||||
int old_p_ri = p_ri;
|
int old_p_ri = p_ri;
|
||||||
|
|
||||||
@@ -308,6 +309,8 @@ shift_block(oparg_T *oap, int amount)
|
|||||||
|
|
||||||
if (!left)
|
if (!left)
|
||||||
{
|
{
|
||||||
|
int tabs = 0, spaces = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1. Get start vcol
|
* 1. Get start vcol
|
||||||
* 2. Total ws vcols
|
* 2. Total ws vcols
|
||||||
@@ -343,29 +346,29 @@ shift_block(oparg_T *oap, int amount)
|
|||||||
#ifdef FEAT_VARTABS
|
#ifdef FEAT_VARTABS
|
||||||
if (!curbuf->b_p_et)
|
if (!curbuf->b_p_et)
|
||||||
tabstop_fromto(ws_vcol, ws_vcol + total,
|
tabstop_fromto(ws_vcol, ws_vcol + total,
|
||||||
ts_val, curbuf->b_p_vts_array, &i, &j);
|
ts_val, curbuf->b_p_vts_array, &tabs, &spaces);
|
||||||
else
|
else
|
||||||
j = total;
|
spaces = total;
|
||||||
#else
|
#else
|
||||||
if (!curbuf->b_p_et)
|
if (!curbuf->b_p_et)
|
||||||
i = ((ws_vcol % ts_val) + total) / ts_val; // number of tabs
|
tabs = ((ws_vcol % ts_val) + total) / ts_val; // number of tabs
|
||||||
if (i)
|
if (tabs > 0)
|
||||||
j = ((ws_vcol % ts_val) + total) % ts_val; // number of spp
|
spaces = ((ws_vcol % ts_val) + total) % ts_val; // number of spp
|
||||||
else
|
else
|
||||||
j = total;
|
spaces = total;
|
||||||
#endif
|
#endif
|
||||||
// if we're splitting a TAB, allow for it
|
// if we're splitting a TAB, allow for it
|
||||||
bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
|
bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
|
||||||
len = (int)STRLEN(bd.textstart) + 1;
|
|
||||||
newp = alloc(bd.textcol + i + j + len);
|
new_line_len = bd.textcol + tabs + spaces + (int)STRLEN(bd.textstart);
|
||||||
|
newp = alloc(new_line_len + 1);
|
||||||
if (newp == NULL)
|
if (newp == NULL)
|
||||||
return;
|
return;
|
||||||
vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + len));
|
|
||||||
mch_memmove(newp, oldp, (size_t)bd.textcol);
|
mch_memmove(newp, oldp, (size_t)bd.textcol);
|
||||||
vim_memset(newp + bd.textcol, TAB, (size_t)i);
|
vim_memset(newp + bd.textcol, TAB, (size_t)tabs);
|
||||||
vim_memset(newp + bd.textcol + i, ' ', (size_t)j);
|
vim_memset(newp + bd.textcol + tabs, ' ', (size_t)spaces);
|
||||||
// the end
|
// Note that STRMOVE() copies the trailing NUL.
|
||||||
mch_memmove(newp + bd.textcol + i + j, bd.textstart, (size_t)len);
|
STRMOVE(newp + bd.textcol + tabs + spaces, bd.textstart);
|
||||||
}
|
}
|
||||||
else // left
|
else // left
|
||||||
{
|
{
|
||||||
@@ -376,8 +379,6 @@ shift_block(oparg_T *oap, int amount)
|
|||||||
colnr_T verbatim_copy_width;// the (displayed) width of this part
|
colnr_T verbatim_copy_width;// the (displayed) width of this part
|
||||||
// of line
|
// of line
|
||||||
unsigned fill; // nr of spaces that replace a TAB
|
unsigned fill; // nr of spaces that replace a TAB
|
||||||
unsigned new_line_len; // the length of the line after the
|
|
||||||
// block shift
|
|
||||||
size_t block_space_width;
|
size_t block_space_width;
|
||||||
size_t shift_amount;
|
size_t shift_amount;
|
||||||
char_u *non_white = bd.textstart;
|
char_u *non_white = bd.textstart;
|
||||||
@@ -448,18 +449,20 @@ shift_block(oparg_T *oap, int amount)
|
|||||||
// - the rest of the line, pointed to by non_white.
|
// - the rest of the line, pointed to by non_white.
|
||||||
new_line_len = (unsigned)(verbatim_copy_end - oldp)
|
new_line_len = (unsigned)(verbatim_copy_end - oldp)
|
||||||
+ fill
|
+ fill
|
||||||
+ (unsigned)STRLEN(non_white) + 1;
|
+ (unsigned)STRLEN(non_white);
|
||||||
|
|
||||||
newp = alloc(new_line_len);
|
newp = alloc(new_line_len + 1);
|
||||||
if (newp == NULL)
|
if (newp == NULL)
|
||||||
return;
|
return;
|
||||||
mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
|
mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
|
||||||
vim_memset(newp + (verbatim_copy_end - oldp), ' ', (size_t)fill);
|
vim_memset(newp + (verbatim_copy_end - oldp), ' ', (size_t)fill);
|
||||||
|
// Note that STRMOVE() copies the trailing NUL.
|
||||||
STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
|
STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
|
||||||
}
|
}
|
||||||
// replace the line
|
// replace the line
|
||||||
|
added = new_line_len - (int)STRLEN(oldp);
|
||||||
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
|
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
|
||||||
changed_bytes(curwin->w_cursor.lnum, bd.textcol);
|
inserted_bytes(curwin->w_cursor.lnum, bd.textcol, added);
|
||||||
State = oldstate;
|
State = oldstate;
|
||||||
curwin->w_cursor.col = oldcol;
|
curwin->w_cursor.col = oldcol;
|
||||||
#ifdef FEAT_RIGHTLEFT
|
#ifdef FEAT_RIGHTLEFT
|
||||||
|
@@ -1933,5 +1933,29 @@ func Test_prop_spell()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_prop_shift_block()
|
||||||
|
new
|
||||||
|
call AddPropTypes()
|
||||||
|
|
||||||
|
call setline(1, ['some highlighted text']->repeat(2))
|
||||||
|
call prop_add(1, 10, #{type: 'one', length: 11})
|
||||||
|
call prop_add(2, 10, #{type: 'two', length: 11})
|
||||||
|
|
||||||
|
call cursor(1, 1)
|
||||||
|
call feedkeys("5l\<c-v>>", 'nxt')
|
||||||
|
call cursor(2, 1)
|
||||||
|
call feedkeys("5l\<c-v><", 'nxt')
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 1, 'id': 0, 'col': 8, 'type_bufnr': 0, 'end': 1, 'type': 'one',
|
||||||
|
\ 'length': 11, 'start' : 1},
|
||||||
|
\ {'lnum': 2, 'id': 0, 'col': 6, 'type_bufnr': 0, 'end': 1, 'type': 'two',
|
||||||
|
\ 'length': 11, 'start' : 1}
|
||||||
|
\ ]
|
||||||
|
call assert_equal(expected, prop_list(1, #{end_lnum: 2}))
|
||||||
|
|
||||||
|
call DeletePropTypes()
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -746,6 +746,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 */
|
||||||
|
/**/
|
||||||
|
4950,
|
||||||
/**/
|
/**/
|
||||||
4949,
|
4949,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user