summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-05-19 15:19:57 +0200
committerBram Moolenaar <Bram@vim.org>2019-05-19 15:19:57 +0200
commit338dfdad3844ebb1ce1d56c421d1f698c086eb0c (patch)
tree92afa870c4fd44c0de47468149d64c42708c2aa8
parentdc6855af974f2ef553aceee619fadcb858e25d39 (diff)
downloadvim-git-338dfdad3844ebb1ce1d56c421d1f698c086eb0c.tar.gz
patch 8.1.1351: text property wrong after :substitutev8.1.1351
Problem: Text property wrong after :substitute. Solution: Save for undo before changing any text properties.
-rw-r--r--src/change.c2
-rw-r--r--src/edit.c2
-rw-r--r--src/ex_cmds.c12
-rw-r--r--src/misc1.c2
-rw-r--r--src/ops.c2
-rw-r--r--src/proto/textprop.pro2
-rw-r--r--src/testdir/test_textprop.vim13
-rw-r--r--src/textprop.c19
-rw-r--r--src/version.c2
9 files changed, 45 insertions, 11 deletions
diff --git a/src/change.c b/src/change.c
index 33db0c1b8..fa8c42538 100644
--- a/src/change.c
+++ b/src/change.c
@@ -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);
diff --git a/src/edit.c b/src/edit.c
index 483ef4abc..be195fc1a 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -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
}
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 3c9166d42..964c4556c 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -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
diff --git a/src/misc1.c b/src/misc1.c
index f83e80795..1eac5189a 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -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;
diff --git a/src/ops.c b/src/ops.c
index 480516b30..975a56f37 100644
--- 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
}
diff --git a/src/proto/textprop.pro b/src/proto/textprop.pro
index 4d37174ae..0114b4fad 100644
--- a/src/proto/textprop.pro
+++ b/src/proto/textprop.pro
@@ -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);
diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim
index d1897a236..eb30c04c6 100644
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -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
diff --git a/src/textprop.c b/src/textprop.c
index 94b4d6b82..aa3e83b35 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -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;
}
/*
diff --git a/src/version.c b/src/version.c
index ac0793198..8bf07e3e9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -768,6 +768,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1351,
+/**/
1350,
/**/
1349,