• R/O
  • SSH

vim: 提交

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

修訂36ec10251b2b78bf65a39fbff1ca4f4bf84da5d8 (tree)
時間2020-02-27 06:15:04
作者Bram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.2.0324: text property not updated correctly when inserting/deleting

Commit: https://github.com/vim/vim/commit/12f20038714928bfecdeee31ed1f927324542034
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Feb 26 22:06:00 2020 +0100

patch 8.2.0324: text property not updated correctly when inserting/deleting
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)

Change Summary

差異

diff -r ffe25b424609 -r 36ec10251b2b src/change.c
--- a/src/change.c Wed Feb 26 21:30:04 2020 +0100
+++ b/src/change.c Wed Feb 26 22:15:04 2020 +0100
@@ -1301,7 +1301,7 @@
13011301 #endif
13021302
13031303 // mark the buffer as changed and prepare for displaying
1304- inserted_bytes(lnum, curwin->w_cursor.col, -count);
1304+ inserted_bytes(lnum, col, -count);
13051305
13061306 return OK;
13071307 }
diff -r ffe25b424609 -r 36ec10251b2b src/testdir/test_listener.vim
--- a/src/testdir/test_listener.vim Wed Feb 26 21:30:04 2020 +0100
+++ b/src/testdir/test_listener.vim Wed Feb 26 22:15:04 2020 +0100
@@ -326,3 +326,16 @@
326326 bwipe!
327327 delfunc Listener
328328 endfunc
329+
330+func Test_col_after_deletion_moved_cur()
331+ func Listener(bufnr, start, end, added, changes)
332+ call assert_equal([#{lnum: 1, end: 2, added: 0, col: 2}], a:changes)
333+ endfunc
334+ new
335+ call setline(1, ['foo'])
336+ let lid = listener_add('Listener')
337+ call feedkeys("lD", 'xt')
338+ call listener_flush()
339+ bwipe!
340+ delfunc Listener
341+endfunc
diff -r ffe25b424609 -r 36ec10251b2b src/testdir/test_textprop.vim
--- a/src/testdir/test_textprop.vim Wed Feb 26 21:30:04 2020 +0100
+++ b/src/testdir/test_textprop.vim Wed Feb 26 22:15:04 2020 +0100
@@ -6,8 +6,6 @@
66
77 source screendump.vim
88
9-" test length zero
10-
119 func Test_proptype_global()
1210 call prop_type_add('comment', {'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1})
1311 let proptypes = prop_type_list()
@@ -233,13 +231,20 @@
233231
234232 " Prop without length or end column is zero length
235233 call prop_clear(1)
236- call prop_add(1, 5, {'type': 'two'})
237- let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 'end': 1}]
234+ call prop_type_add('included', {'start_incl': 1, 'end_incl': 1})
235+ call prop_add(1, 5, #{type: 'included'})
236+ let expected = [#{col: 5, length: 0, type: 'included', id: 0, start: 1, end: 1}]
237+ call assert_equal(expected, prop_list(1))
238+
239+ " Inserting text makes the prop bigger.
240+ exe "normal 5|ixx\<Esc>"
241+ let expected = [#{col: 5, length: 2, type: 'included', id: 0, start: 1, end: 1}]
238242 call assert_equal(expected, prop_list(1))
239243
240244 call assert_fails("call prop_add(1, 5, {'type': 'two', 'bufnr': 234343})", 'E158:')
241245
242246 call DeletePropTypes()
247+ call prop_type_delete('included')
243248 bwipe!
244249 endfunc
245250
diff -r ffe25b424609 -r 36ec10251b2b src/textprop.c
--- a/src/textprop.c Wed Feb 26 21:30:04 2020 +0100
+++ b/src/textprop.c Wed Feb 26 22:15:04 2020 +0100
@@ -1232,7 +1232,6 @@
12321232 {
12331233 int proplen;
12341234 char_u *props;
1235- textprop_T tmp_prop;
12361235 proptype_T *pt;
12371236 int dirty = FALSE;
12381237 int ri, wi;
@@ -1249,62 +1248,80 @@
12491248 wi = 0; // write index
12501249 for (ri = 0; ri < proplen; ++ri)
12511250 {
1252- int start_incl;
1251+ textprop_T prop;
1252+ int start_incl, end_incl;
1253+ int can_drop;
12531254
1254- mch_memmove(&tmp_prop, props + ri * sizeof(textprop_T),
1255- sizeof(textprop_T));
1256- pt = text_prop_type_by_id(curbuf, tmp_prop.tp_type);
1257- start_incl = (flags & APC_SUBSTITUTE) ||
1258- (pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL));
1255+ mch_memmove(&prop, props + ri * sizeof(textprop_T), sizeof(textprop_T));
1256+ pt = text_prop_type_by_id(curbuf, prop.tp_type);
1257+ start_incl = (pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL))
1258+ || (flags & APC_SUBSTITUTE);
1259+ end_incl = (pt != NULL && (pt->pt_flags & PT_FLAG_INS_END_INCL));
1260+ // Do not drop zero-width props if they later can increase in size
1261+ can_drop = !(start_incl || end_incl);
12591262
1260- if (bytes_added > 0
1261- && (tmp_prop.tp_col >= col + (start_incl ? 2 : 1)))
1263+ if (bytes_added > 0)
12621264 {
1263- tmp_prop.tp_col += bytes_added;
1265+ if (col + 1 <= prop.tp_col
1266+ - (start_incl || (prop.tp_len == 0 && end_incl)))
1267+ {
1268+ // Change is entirely before the text property: Only shift
1269+ prop.tp_col += bytes_added;
1270+ // Save for undo if requested and not done yet.
1271+ if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
1272+ u_savesub(lnum);
1273+ dirty = TRUE;
1274+ }
1275+ else if (col + 1 < prop.tp_col + prop.tp_len + end_incl)
1276+ {
1277+ // Insertion was inside text property
1278+ prop.tp_len += bytes_added;
1279+ // Save for undo if requested and not done yet.
1280+ if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
1281+ u_savesub(lnum);
1282+ dirty = TRUE;
1283+ }
1284+ }
1285+ else if (prop.tp_col > col + 1)
1286+ {
1287+ int len_changed = FALSE;
1288+
1289+ if (prop.tp_col + bytes_added < col + 1)
1290+ {
1291+ prop.tp_len += (prop.tp_col - 1 - col) + bytes_added;
1292+ prop.tp_col = col + 1;
1293+ len_changed = TRUE;
1294+ }
1295+ else
1296+ prop.tp_col += bytes_added;
12641297 // Save for undo if requested and not done yet.
12651298 if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
12661299 u_savesub(lnum);
12671300 dirty = TRUE;
1301+ if (len_changed && prop.tp_len <= 0)
1302+ {
1303+ prop.tp_len = 0;
1304+ if (can_drop)
1305+ continue; // drop this text property
1306+ }
12681307 }
1269- else if (bytes_added <= 0 && (tmp_prop.tp_col > col + 1))
1308+ else if (prop.tp_len > 0 && prop.tp_col + prop.tp_len > col)
12701309 {
1271- int len_changed = FALSE;
1310+ int after = col - bytes_added - (prop.tp_col - 1 + prop.tp_len);
12721311
1273- if (tmp_prop.tp_col + bytes_added < col + 1)
1274- {
1275- tmp_prop.tp_len += (tmp_prop.tp_col - 1 - col) + bytes_added;
1276- tmp_prop.tp_col = col + 1;
1277- len_changed = TRUE;
1278- }
1312+ if (after > 0)
1313+ prop.tp_len += bytes_added + after;
12791314 else
1280- tmp_prop.tp_col += bytes_added;
1315+ prop.tp_len += bytes_added;
12811316 // Save for undo if requested and not done yet.
12821317 if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
12831318 u_savesub(lnum);
12841319 dirty = TRUE;
1285- if (len_changed && tmp_prop.tp_len <= 0)
1320+ if (prop.tp_len <= 0 && can_drop)
12861321 continue; // drop this text property
12871322 }
1288- else if (tmp_prop.tp_len > 0
1289- && tmp_prop.tp_col + tmp_prop.tp_len > col
1290- + ((pt != NULL && (pt->pt_flags & PT_FLAG_INS_END_INCL))
1291- ? 0 : 1))
1292- {
1293- int after = col - bytes_added
1294- - (tmp_prop.tp_col - 1 + tmp_prop.tp_len);
1295- if (after > 0)
1296- tmp_prop.tp_len += bytes_added + after;
1297- else
1298- tmp_prop.tp_len += bytes_added;
1299- // Save for undo if requested and not done yet.
1300- if ((flags & APC_SAVE_FOR_UNDO) && !dirty)
1301- u_savesub(lnum);
1302- dirty = TRUE;
1303- if (tmp_prop.tp_len <= 0)
1304- continue; // drop this text property
1305- }
1306- mch_memmove(props + wi * sizeof(textprop_T), &tmp_prop,
1307- sizeof(textprop_T));
1323+
1324+ mch_memmove(props + wi * sizeof(textprop_T), &prop, sizeof(textprop_T));
13081325 ++wi;
13091326 }
13101327 if (dirty)
diff -r ffe25b424609 -r 36ec10251b2b src/version.c
--- a/src/version.c Wed Feb 26 21:30:04 2020 +0100
+++ b/src/version.c Wed Feb 26 22:15:04 2020 +0100
@@ -739,6 +739,8 @@
739739 static int included_patches[] =
740740 { /* Add new patch number below this line */
741741 /**/
742+ 324,
743+/**/
742744 323,
743745 /**/
744746 322,
Show on old repository browser