1
0
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:
LemonBoy
2022-05-13 21:56:28 +01:00
committed by Bram Moolenaar
parent 31ad32a325
commit 4b93674159
3 changed files with 49 additions and 20 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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,
/**/ /**/