# HG changeset patch # User Bram Moolenaar # Date 1600195503 -7200 # Node ID 0416105e103bf53508e6de2ae0306ea6c4127bec # Parent 4575b886c258c4167e22534bae6f9be72fa53d6d patch 8.2.1688: increment/decrement removes text property Commit: https://github.com/vim/vim/commit/c8f12c9856df58c760fe54d81b2ec5ed4dcaffd6 Author: Bram Moolenaar Date: Tue Sep 15 20:34:10 2020 +0200 patch 8.2.1688: increment/decrement removes text property Problem: Increment/decrement removes text property. Solution: Insert the new number before deleting the old one. (closes https://github.com/vim/vim/issues/6962) diff --git a/src/ops.c b/src/ops.c --- a/src/ops.c +++ b/src/ops.c @@ -2636,6 +2636,9 @@ do_addsub( } else { + pos_T save_pos; + int i; + if (col > 0 && ptr[col - 1] == '-' && (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1)) @@ -2734,7 +2737,9 @@ do_addsub( */ if (c == '-') --length; - while (todel-- > 0) + + save_pos = curwin->w_cursor; + for (i = 0; i < todel; ++i) { if (c < 0x100 && isalpha(c)) { @@ -2743,10 +2748,10 @@ do_addsub( else hexupper = FALSE; } - // del_char() will mark line needing displaying - (void)del_char(FALSE); + inc_cursor(); c = gchar_cursor(); } + curwin->w_cursor = save_pos; /* * Prepare the leading characters in buf1[]. @@ -2776,7 +2781,6 @@ do_addsub( */ if (pre == 'b' || pre == 'B') { - int i; int bit = 0; int bits = sizeof(uvarnumber_T) * 8; @@ -2809,9 +2813,33 @@ do_addsub( while (length-- > 0) *ptr++ = '0'; *ptr = NUL; + STRCAT(buf1, buf2); + + // Insert just after the first character to be removed, so that any + // text properties will be adjusted. Then delete the old number + // afterwards. + save_pos = curwin->w_cursor; + if (todel > 0) + inc_cursor(); ins_str(buf1); // insert the new number vim_free(buf1); + + // del_char() will also mark line needing displaying + if (todel > 0) + { + int bytes_after = (int)STRLEN(ml_get_curline()) + - curwin->w_cursor.col; + + // Delete the one character before the insert. + curwin->w_cursor = save_pos; + (void)del_char(FALSE); + curwin->w_cursor.col = STRLEN(ml_get_curline()) - bytes_after; + --todel; + } + while (todel-- > 0) + (void)del_char(FALSE); + endpos = curwin->w_cursor; if (did_change && curwin->w_cursor.col) --curwin->w_cursor.col; diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -1273,7 +1273,7 @@ func Test_prop_func_invalid_args() call assert_fails("call prop_type_list([])", 'E715:') endfunc -func Test_split_join() +func Test_prop_split_join() new call prop_type_add('test', {'highlight': 'ErrorMsg'}) call setline(1, 'just some text') @@ -1294,4 +1294,24 @@ func Test_split_join() call prop_type_delete('test') endfunc +func Test_prop_increment_decrement() + new + call prop_type_add('test', {'highlight': 'ErrorMsg'}) + call setline(1, 'its 998 times') + call prop_add(1, 5, {'length': 3, 'type': 'test'}) + + exe "normal! 0f9\" + eval getline(1)->assert_equal('its 999 times') + eval prop_list(1)->assert_equal([ + \ #{id: 0, col: 5, end: 1, type: 'test', length: 3, start: 1}]) + + exe "normal! 0f9\" + eval getline(1)->assert_equal('its 1000 times') + eval prop_list(1)->assert_equal([ + \ #{id: 0, col: 5, end: 1, type: 'test', length: 4, start: 1}]) + + bwipe! + call prop_type_delete('test') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1688, +/**/ 1687, /**/ 1686,