]> granicus.if.org Git - vim/commitdiff
patch 8.2.0324: text property not updated correctly when inserting/deleting v8.2.0324
authorBram Moolenaar <Bram@vim.org>
Wed, 26 Feb 2020 21:06:00 +0000 (22:06 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 26 Feb 2020 21:06:00 +0000 (22:06 +0100)
Problem:    Text property not updated correctly when inserting/deleting.
Solution:   Use the right column when deleting. Make zero-width text
            properties respect start_incl and end_incl. (Axel Forsman,
            closes #5696, closes #5679)

src/change.c
src/testdir/test_listener.vim
src/testdir/test_textprop.vim
src/textprop.c
src/version.c

index e5ac97bd5455101d1560b1561851c5d54507c6b0..3ee719812f0d20f0af8a5e86a15aa7de53529729 100644 (file)
@@ -1301,7 +1301,7 @@ del_bytes(
 #endif
 
     // mark the buffer as changed and prepare for displaying
-    inserted_bytes(lnum, curwin->w_cursor.col, -count);
+    inserted_bytes(lnum, col, -count);
 
     return OK;
 }
index a263abadd2d0b731ba11a42e44a801a8fbb67b1b..9c9ba7fe43dd8e33db42485032a2efa4d22f5760 100644 (file)
@@ -326,3 +326,16 @@ func Test_listener_cleared_newbuf()
   bwipe!
   delfunc Listener
 endfunc
+
+func Test_col_after_deletion_moved_cur()
+       func Listener(bufnr, start, end, added, changes)
+    call assert_equal([#{lnum: 1, end: 2, added: 0, col: 2}], a:changes)
+       endfunc
+       new
+       call setline(1, ['foo'])
+       let lid = listener_add('Listener')
+       call feedkeys("lD", 'xt')
+  call listener_flush()
+       bwipe!
+       delfunc Listener
+endfunc
index 32001b3622b576ff5a30a606c1721a369a1e2c8b..6dbaa5350f86c04f4198536ffb13fa65d791852f 100644 (file)
@@ -6,8 +6,6 @@ CheckFeature textprop
 
 source screendump.vim
 
-" test length zero
-
 func Test_proptype_global()
   call prop_type_add('comment', {'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1})
   let proptypes = prop_type_list()
@@ -233,13 +231,20 @@ func Test_prop_add()
 
   " Prop without length or end column is zero length
   call prop_clear(1)
-  call prop_add(1, 5, {'type': 'two'})
-  let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 'end': 1}]
+  call prop_type_add('included', {'start_incl': 1, 'end_incl': 1})
+  call prop_add(1, 5, #{type: 'included'})
+  let expected = [#{col: 5, length: 0, type: 'included', id: 0, start: 1, end: 1}]
+  call assert_equal(expected, prop_list(1))
+
+  " Inserting text makes the prop bigger.
+  exe "normal 5|ixx\<Esc>"
+  let expected = [#{col: 5, length: 2, type: 'included', id: 0, start: 1, end: 1}]
   call assert_equal(expected, prop_list(1))
 
   call assert_fails("call prop_add(1, 5, {'type': 'two', 'bufnr': 234343})", 'E158:')
 
   call DeletePropTypes()
+  call prop_type_delete('included')
   bwipe!
 endfunc
 
index 4ddb42e9d393dcec40e2c4c2a3bd97cde1a5a8ce..3ad84a24245411b3aea7bb50f0fd943a7335c5ba 100644 (file)
@@ -1232,7 +1232,6 @@ adjust_prop_columns(
 {
     int                proplen;
     char_u     *props;
-    textprop_T tmp_prop;
     proptype_T  *pt;
     int                dirty = FALSE;
     int                ri, wi;
@@ -1249,62 +1248,80 @@ adjust_prop_columns(
     wi = 0; // write index
     for (ri = 0; ri < proplen; ++ri)
     {
-       int start_incl;
-
-       mch_memmove(&tmp_prop, props + ri * sizeof(textprop_T),
-                                                          sizeof(textprop_T));
-       pt = text_prop_type_by_id(curbuf, tmp_prop.tp_type);
-       start_incl = (flags & APC_SUBSTITUTE) ||
-                      (pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL));
-
-       if (bytes_added > 0
-               && (tmp_prop.tp_col >= col + (start_incl ? 2 : 1)))
+       textprop_T      prop;
+       int             start_incl, end_incl;
+       int             can_drop;
+
+       mch_memmove(&prop, props + ri * sizeof(textprop_T), sizeof(textprop_T));
+       pt = text_prop_type_by_id(curbuf, prop.tp_type);
+       start_incl = (pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL))
+                                                  || (flags & APC_SUBSTITUTE);
+       end_incl = (pt != NULL && (pt->pt_flags & PT_FLAG_INS_END_INCL));
+       // Do not drop zero-width props if they later can increase in size
+       can_drop = !(start_incl || end_incl);
+
+       if (bytes_added > 0)
        {
-           tmp_prop.tp_col += bytes_added;
-           // Save for undo if requested and not done yet.
-           if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
-               u_savesub(lnum);
-           dirty = TRUE;
+           if (col + 1 <= prop.tp_col
+                             - (start_incl || (prop.tp_len == 0 && end_incl)))
+           {
+               // Change is entirely before the text property: Only shift
+               prop.tp_col += bytes_added;
+               // Save for undo if requested and not done yet.
+               if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
+                   u_savesub(lnum);
+               dirty = TRUE;
+           }
+           else if (col + 1 < prop.tp_col + prop.tp_len + end_incl)
+           {
+               // Insertion was inside text property
+               prop.tp_len += bytes_added;
+               // Save for undo if requested and not done yet.
+               if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
+                   u_savesub(lnum);
+               dirty = TRUE;
+           }
        }
-       else if (bytes_added <= 0 && (tmp_prop.tp_col > col + 1))
+       else if (prop.tp_col > col + 1)
        {
            int len_changed = FALSE;
 
-           if (tmp_prop.tp_col + bytes_added < col + 1)
+           if (prop.tp_col + bytes_added < col + 1)
            {
-               tmp_prop.tp_len += (tmp_prop.tp_col - 1 - col) + bytes_added;
-               tmp_prop.tp_col = col + 1;
+               prop.tp_len += (prop.tp_col - 1 - col) + bytes_added;
+               prop.tp_col = col + 1;
                len_changed = TRUE;
            }
            else
-               tmp_prop.tp_col += bytes_added;
+               prop.tp_col += bytes_added;
            // Save for undo if requested and not done yet.
            if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
                u_savesub(lnum);
            dirty = TRUE;
-           if (len_changed && tmp_prop.tp_len <= 0)
-               continue;  // drop this text property
+           if (len_changed && prop.tp_len <= 0)
+           {
+               prop.tp_len = 0;
+               if (can_drop)
+                   continue;  // drop this text property
+           }
        }
-       else if (tmp_prop.tp_len > 0
-               && tmp_prop.tp_col + tmp_prop.tp_len > col
-                      + ((pt != NULL && (pt->pt_flags & PT_FLAG_INS_END_INCL))
-                                                                     ? 0 : 1))
+       else if (prop.tp_len > 0 && prop.tp_col + prop.tp_len > col)
        {
-           int after = col - bytes_added
-                                    - (tmp_prop.tp_col - 1 + tmp_prop.tp_len);
+           int after = col - bytes_added - (prop.tp_col - 1 + prop.tp_len);
+
            if (after > 0)
-               tmp_prop.tp_len += bytes_added + after;
+               prop.tp_len += bytes_added + after;
            else
-               tmp_prop.tp_len += bytes_added;
+               prop.tp_len += bytes_added;
            // Save for undo if requested and not done yet.
            if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
                u_savesub(lnum);
            dirty = TRUE;
-           if (tmp_prop.tp_len <= 0)
+           if (prop.tp_len <= 0 && can_drop)
                continue;  // drop this text property
        }
-       mch_memmove(props + wi * sizeof(textprop_T), &tmp_prop,
-                                                          sizeof(textprop_T));
+
+       mch_memmove(props + wi * sizeof(textprop_T), &prop, sizeof(textprop_T));
        ++wi;
     }
     if (dirty)
index f95526c0a91ef7a9920b160e3c36b3e6f65de411..3f644312452be327f085669438e50db02fdcdb1d 100644 (file)
@@ -738,6 +738,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    324,
 /**/
     323,
 /**/