]> granicus.if.org Git - vim/commitdiff
patch 8.2.1688: increment/decrement removes text property v8.2.1688
authorBram Moolenaar <Bram@vim.org>
Tue, 15 Sep 2020 18:34:10 +0000 (20:34 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 15 Sep 2020 18:34:10 +0000 (20:34 +0200)
Problem:    Increment/decrement removes text property.
Solution:   Insert the new number before deleting the old one. (closes #6962)

src/ops.c
src/testdir/test_textprop.vim
src/version.c

index a681df0dc39c0f66ee480efa9a8f3306339347bd..2988a185b4d947525b5f867cd8549b768bff2d16 100644 (file)
--- 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;
index ff7102f6aba41618b5cf440602384f5a3a85652f..ae84cf974e597569b661af8d2ed76fa322f6e5ca 100644 (file)
@@ -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\<C-A>"
+  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\<C-A>"
+  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
index 0d0eaa5ec95c508306936c8db59357a45deaa28a..23006e1ed51511942ddbcc8bc791b230ee103e23 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1688,
 /**/
     1687,
 /**/