diff options
-rw-r--r-- | src/change.c | 2 | ||||
-rw-r--r-- | src/edit.c | 2 | ||||
-rw-r--r-- | src/ex_cmds.c | 12 | ||||
-rw-r--r-- | src/misc1.c | 2 | ||||
-rw-r--r-- | src/ops.c | 2 | ||||
-rw-r--r-- | src/proto/textprop.pro | 2 | ||||
-rw-r--r-- | src/testdir/test_textprop.vim | 13 | ||||
-rw-r--r-- | src/textprop.c | 19 | ||||
-rw-r--r-- | src/version.c | 2 |
9 files changed, 45 insertions, 11 deletions
diff --git a/src/change.c b/src/change.c index 33db0c1b80..fa8c42538f 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 483ef4abcb..be195fc1ae 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 3c9166d424..964c4556c9 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 f83e807954..1eac5189ae 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; @@ -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 4d37174aef..0114b4fadc 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 d1897a236e..eb30c04c6c 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 94b4d6b82b..aa3e83b354 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 ac07931988..8bf07e3e99 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, |