Skip to content

Commit 338dfda

Browse files
committed
patch 8.1.1351: text property wrong after :substitute
Problem: Text property wrong after :substitute. Solution: Save for undo before changing any text properties.
1 parent dc6855a commit 338dfda

9 files changed

Lines changed: 45 additions & 11 deletions

File tree

src/change.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ inserted_bytes(linenr_T lnum, colnr_T col, int added UNUSED)
684684
{
685685
#ifdef FEAT_TEXT_PROP
686686
if (curbuf->b_has_textprop && added != 0)
687-
adjust_prop_columns(lnum, col, added);
687+
adjust_prop_columns(lnum, col, added, FALSE);
688688
#endif
689689

690690
changed_bytes(lnum, col);

src/edit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4104,7 +4104,7 @@ replace_do_bs(int limit_col)
41044104

41054105
--text_prop_frozen;
41064106
adjust_prop_columns(curwin->w_cursor.lnum, curwin->w_cursor.col,
4107-
(int)(len_now - len_before));
4107+
(int)(len_now - len_before), FALSE);
41084108
}
41094109
#endif
41104110
}

src/ex_cmds.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5187,6 +5187,9 @@ do_sub(exarg_T *eap)
51875187
int do_again; /* do it again after joining lines */
51885188
int skip_match = FALSE;
51895189
linenr_T sub_firstlnum; /* nr of first sub line */
5190+
#ifdef FEAT_TEXT_PROP
5191+
int save_for_undo = TRUE;
5192+
#endif
51905193

51915194
/*
51925195
* The new text is build up step by step, to avoid too much
@@ -5603,9 +5606,14 @@ do_sub(exarg_T *eap)
56035606
p1 = sub_firstline;
56045607
#ifdef FEAT_TEXT_PROP
56055608
if (curbuf->b_has_textprop)
5606-
adjust_prop_columns(lnum, regmatch.startpos[0].col,
5609+
{
5610+
// When text properties are changed, need to save for
5611+
// undo first, unless done already.
5612+
if (adjust_prop_columns(lnum, regmatch.startpos[0].col,
56075613
sublen - 1 - (regmatch.endpos[0].col
5608-
- regmatch.startpos[0].col));
5614+
- regmatch.startpos[0].col), save_for_undo))
5615+
save_for_undo = FALSE;
5616+
}
56095617
#endif
56105618
}
56115619
else

src/misc1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ set_indent(
441441
// the old indent, when decreasing indent it behaves like spaces
442442
// were deleted at the new indent.
443443
adjust_prop_columns(curwin->w_cursor.lnum,
444-
(colnr_T)(added > 0 ? (p - oldline) : ind_len), added);
444+
(colnr_T)(added > 0 ? (p - oldline) : ind_len), added, FALSE);
445445
}
446446
#endif
447447
retval = TRUE;

src/ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,7 @@ op_delete(oparg_T *oap)
19371937

19381938
#ifdef FEAT_TEXT_PROP
19391939
if (curbuf->b_has_textprop && n != 0)
1940-
adjust_prop_columns(lnum, bd.textcol, -n);
1940+
adjust_prop_columns(lnum, bd.textcol, -n, FALSE);
19411941
#endif
19421942
}
19431943

src/proto/textprop.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void f_prop_type_get(typval_T *argvars, typval_T *rettv);
1313
void f_prop_type_list(typval_T *argvars, typval_T *rettv);
1414
void clear_global_prop_types(void);
1515
void clear_buf_prop_types(buf_T *buf);
16-
void adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added);
16+
int adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added, int save_for_undo);
1717
void adjust_props_for_split(linenr_T lnum_props, linenr_T lnum_top, int kept, int deleted);
1818
void adjust_props_for_join(linenr_T lnum, textprop_T **prop_line, int *prop_length, long col, int removed);
1919
void join_prop_lines(linenr_T lnum, char_u *newp, textprop_T **prop_lines, int *prop_lengths, int count);

src/testdir/test_textprop.vim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,19 @@ func Test_prop_undo()
608608
let expected[0].length = 2
609609
call assert_equal(expected, prop_list(1))
610610

611+
" substitute a word, then undo
612+
call setline(1, 'the number 123 is highlighted.')
613+
call prop_add(1, 12, {'length': 3, 'type': 'comment'})
614+
let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
615+
call assert_equal(expected, prop_list(1))
616+
set ul&
617+
1s/number/foo
618+
let expected[0].col = 9
619+
call assert_equal(expected, prop_list(1))
620+
undo
621+
let expected[0].col = 12
622+
call assert_equal(expected, prop_list(1))
623+
611624
bwipe!
612625
call prop_type_delete('comment')
613626
endfunc

src/textprop.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -957,13 +957,17 @@ clear_buf_prop_types(buf_T *buf)
957957
* shift by "bytes_added" (can be negative).
958958
* Note that "col" is zero-based, while tp_col is one-based.
959959
* Only for the current buffer.
960+
* When "save_for_undo" is TRUE then call u_savesub() before making changes to
961+
* the line.
960962
* Caller is expected to check b_has_textprop and "bytes_added" being non-zero.
963+
* Returns TRUE when props were changed.
961964
*/
962-
void
965+
int
963966
adjust_prop_columns(
964967
linenr_T lnum,
965968
colnr_T col,
966-
int bytes_added)
969+
int bytes_added,
970+
int save_for_undo)
967971
{
968972
int proplen;
969973
char_u *props;
@@ -974,11 +978,11 @@ adjust_prop_columns(
974978
size_t textlen;
975979

976980
if (text_prop_frozen > 0)
977-
return;
981+
return FALSE;
978982

979983
proplen = get_text_props(curbuf, lnum, &props, TRUE);
980984
if (proplen == 0)
981-
return;
985+
return FALSE;
982986
textlen = curbuf->b_ml.ml_line_len - proplen * sizeof(textprop_T);
983987

984988
wi = 0; // write index
@@ -1001,6 +1005,9 @@ adjust_prop_columns(
10011005
}
10021006
else
10031007
tmp_prop.tp_col += bytes_added;
1008+
// Save for undo if requested and not done yet.
1009+
if (save_for_undo && !dirty)
1010+
u_savesub(lnum);
10041011
dirty = TRUE;
10051012
if (tmp_prop.tp_len <= 0)
10061013
continue; // drop this text property
@@ -1016,6 +1023,9 @@ adjust_prop_columns(
10161023
tmp_prop.tp_len += bytes_added + after;
10171024
else
10181025
tmp_prop.tp_len += bytes_added;
1026+
// Save for undo if requested and not done yet.
1027+
if (save_for_undo && !dirty)
1028+
u_savesub(lnum);
10191029
dirty = TRUE;
10201030
if (tmp_prop.tp_len <= 0)
10211031
continue; // drop this text property
@@ -1034,6 +1044,7 @@ adjust_prop_columns(
10341044
curbuf->b_ml.ml_flags |= ML_LINE_DIRTY;
10351045
curbuf->b_ml.ml_line_len = newlen;
10361046
}
1047+
return dirty;
10371048
}
10381049

10391050
/*

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,8 @@ static char *(features[]) =
767767

768768
static int included_patches[] =
769769
{ /* Add new patch number below this line */
770+
/**/
771+
1351,
770772
/**/
771773
1350,
772774
/**/

0 commit comments

Comments
 (0)