]> granicus.if.org Git - vim/commitdiff
patch 8.1.1351: text property wrong after :substitute v8.1.1351
authorBram Moolenaar <Bram@vim.org>
Sun, 19 May 2019 13:19:57 +0000 (15:19 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 19 May 2019 13:19:57 +0000 (15:19 +0200)
Problem:    Text property wrong after :substitute.
Solution:   Save for undo before changing any text properties.

src/change.c
src/edit.c
src/ex_cmds.c
src/misc1.c
src/ops.c
src/proto/textprop.pro
src/testdir/test_textprop.vim
src/textprop.c
src/version.c

index 33db0c1b806c7cb2c87da861fd269d379bc37b92..fa8c42538fa2f42334071c4ca1fc53ada808f263 100644 (file)
@@ -684,7 +684,7 @@ inserted_bytes(linenr_T lnum, colnr_T col, int added UNUSED)
 {
 #ifdef FEAT_TEXT_PROP
     if (curbuf->b_has_textprop && added != 0)
-       adjust_prop_columns(lnum, col, added);
+       adjust_prop_columns(lnum, col, added, FALSE);
 #endif
 
     changed_bytes(lnum, col);
index 483ef4abcb5e785d9047292b0a985d0ddac264e9..be195fc1ae76bcc304e91a95ebf35f59da0e70c8 100644 (file)
@@ -4104,7 +4104,7 @@ replace_do_bs(int limit_col)
 
            --text_prop_frozen;
            adjust_prop_columns(curwin->w_cursor.lnum, curwin->w_cursor.col,
-                                                 (int)(len_now - len_before));
+                                          (int)(len_now - len_before), FALSE);
        }
 #endif
     }
index 3c9166d42400160e0aab014db1cdc5467143fda4..964c4556c95798cfc71262e73c68e443faeec777 100644 (file)
@@ -5187,6 +5187,9 @@ do_sub(exarg_T *eap)
            int         do_again;       /* do it again after joining lines */
            int         skip_match = FALSE;
            linenr_T    sub_firstlnum;  /* nr of first sub line */
+#ifdef FEAT_TEXT_PROP
+           int         save_for_undo = TRUE;
+#endif
 
            /*
             * The new text is build up step by step, to avoid too much
@@ -5603,9 +5606,14 @@ do_sub(exarg_T *eap)
                    p1 = sub_firstline;
 #ifdef FEAT_TEXT_PROP
                    if (curbuf->b_has_textprop)
-                       adjust_prop_columns(lnum, regmatch.startpos[0].col,
+                   {
+                       // When text properties are changed, need to save for
+                       // undo first, unless done already.
+                       if (adjust_prop_columns(lnum, regmatch.startpos[0].col,
                              sublen - 1 - (regmatch.endpos[0].col
-                                                 - regmatch.startpos[0].col));
+                                  - regmatch.startpos[0].col), save_for_undo))
+                           save_for_undo = FALSE;
+                   }
 #endif
                }
                else
index f83e807954143263a39036fbce6ac0c61545fd3c..1eac5189aeda2b1ca33329d356d89341ac84a069 100644 (file)
@@ -441,7 +441,7 @@ set_indent(
            // the old indent, when decreasing indent it behaves like spaces
            // were deleted at the new indent.
            adjust_prop_columns(curwin->w_cursor.lnum,
-                       (colnr_T)(added > 0 ? (p - oldline) : ind_len), added);
+                (colnr_T)(added > 0 ? (p - oldline) : ind_len), added, FALSE);
        }
 #endif
        retval = TRUE;
index 480516b30f6690f2420e1cc9d7b6947cd3d0657b..975a56f372ba7c1b96ccb680317172a843677a22 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -1937,7 +1937,7 @@ op_delete(oparg_T *oap)
 
 #ifdef FEAT_TEXT_PROP
            if (curbuf->b_has_textprop && n != 0)
-               adjust_prop_columns(lnum, bd.textcol, -n);
+               adjust_prop_columns(lnum, bd.textcol, -n, FALSE);
 #endif
        }
 
index 4d37174aef81d009a471ed0ed3fe6a9d254ffaed..0114b4fadcabf61a4c640f7f6ebac85218aa0909 100644 (file)
@@ -13,7 +13,7 @@ void f_prop_type_get(typval_T *argvars, typval_T *rettv);
 void f_prop_type_list(typval_T *argvars, typval_T *rettv);
 void clear_global_prop_types(void);
 void clear_buf_prop_types(buf_T *buf);
-void adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added);
+int adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added, int save_for_undo);
 void adjust_props_for_split(linenr_T lnum_props, linenr_T lnum_top, int kept, int deleted);
 void adjust_props_for_join(linenr_T lnum, textprop_T **prop_line, int *prop_length, long col, int removed);
 void join_prop_lines(linenr_T lnum, char_u *newp, textprop_T **prop_lines, int *prop_lengths, int count);
index d1897a236e25d6a1faaf4b1209c0dad18a4d2713..eb30c04c6c9d5430f4daf99a318a4a73fb21fe46 100644 (file)
@@ -608,6 +608,19 @@ func Test_prop_undo()
   let expected[0].length = 2
   call assert_equal(expected, prop_list(1))
 
+  " substitute a word, then undo
+  call setline(1, 'the number 123 is highlighted.')
+  call prop_add(1, 12, {'length': 3, 'type': 'comment'})
+  let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
+  call assert_equal(expected, prop_list(1))
+  set ul&
+  1s/number/foo
+  let expected[0].col = 9
+  call assert_equal(expected, prop_list(1))
+  undo
+  let expected[0].col = 12
+  call assert_equal(expected, prop_list(1))
+
   bwipe!
   call prop_type_delete('comment')
 endfunc
index 94b4d6b82be62f99c41230f76b8b39a04ba2cf24..aa3e83b3549255c08a582e4ec76d73dc52acddec 100644 (file)
@@ -957,13 +957,17 @@ clear_buf_prop_types(buf_T *buf)
  * shift by "bytes_added" (can be negative).
  * Note that "col" is zero-based, while tp_col is one-based.
  * Only for the current buffer.
+ * When "save_for_undo" is TRUE then call u_savesub() before making changes to
+ * the line.
  * Caller is expected to check b_has_textprop and "bytes_added" being non-zero.
+ * Returns TRUE when props were changed.
  */
-    void
+    int
 adjust_prop_columns(
        linenr_T    lnum,
        colnr_T     col,
-       int         bytes_added)
+       int         bytes_added,
+       int         save_for_undo)
 {
     int                proplen;
     char_u     *props;
@@ -974,11 +978,11 @@ adjust_prop_columns(
     size_t     textlen;
 
     if (text_prop_frozen > 0)
-       return;
+       return FALSE;
 
     proplen = get_text_props(curbuf, lnum, &props, TRUE);
     if (proplen == 0)
-       return;
+       return FALSE;
     textlen = curbuf->b_ml.ml_line_len - proplen * sizeof(textprop_T);
 
     wi = 0; // write index
@@ -1001,6 +1005,9 @@ adjust_prop_columns(
            }
            else
                tmp_prop.tp_col += bytes_added;
+           // Save for undo if requested and not done yet.
+           if (save_for_undo && !dirty)
+               u_savesub(lnum);
            dirty = TRUE;
            if (tmp_prop.tp_len <= 0)
                continue;  // drop this text property
@@ -1016,6 +1023,9 @@ adjust_prop_columns(
                tmp_prop.tp_len += bytes_added + after;
            else
                tmp_prop.tp_len += bytes_added;
+           // Save for undo if requested and not done yet.
+           if (save_for_undo && !dirty)
+               u_savesub(lnum);
            dirty = TRUE;
            if (tmp_prop.tp_len <= 0)
                continue;  // drop this text property
@@ -1034,6 +1044,7 @@ adjust_prop_columns(
        curbuf->b_ml.ml_flags |= ML_LINE_DIRTY;
        curbuf->b_ml.ml_line_len = newlen;
     }
+    return dirty;
 }
 
 /*
index ac07931988e529be3c1afbeb8da5c015c29d6d30..8bf07e3e99a7c811135a9ec0ce8cd204d4143b22 100644 (file)
@@ -767,6 +767,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1351,
 /**/
     1350,
 /**/