patch 8.2.4960: text properties that cross lines not updated for deleted line v8.2.4960
authorPaul Ollis <paul@cleversheep.org>
Sun, 15 May 2022 21:24:55 +0000 (22:24 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 15 May 2022 21:24:55 +0000 (22:24 +0100)
Problem:    Text properties that cross line boundary are not correctly updated
            for a deleted line.
Solution:   Correct computing location of text property entry. (Paul Ollis,
            closes #10431, closes #10430)

src/memline.c
src/testdir/test_textprop.vim
src/version.c

index e098aef552280966ff72cbfad948e327a308fb79..2cdd2277dcbe48b568ab9bbd9a08df3853c17e61 100644 (file)
@@ -3501,8 +3501,9 @@ ml_replace_len(
 #ifdef FEAT_PROP_POPUP
 /*
  * Adjust text properties in line "lnum" for a deleted line.
- * When "above" is true this is the line above the deleted line.
- * "del_props" are the properties of the deleted line.
+ * When "above" is true this is the line above the deleted line, otherwise this
+ * is the line below the deleted line.
+ * "del_props[del_props_len]" are the properties of the deleted line.
  */
     static void
 adjust_text_props_for_delete(
@@ -3569,7 +3570,7 @@ adjust_text_props_for_delete(
                                                           : TP_FLAG_CONT_PREV;
                textprop_T  prop_this;
 
-               mch_memmove(&prop_this, text + textlen + done_del,
+               mch_memmove(&prop_this, text + textlen + done_this,
                                                           sizeof(textprop_T));
                if ((prop_this.tp_flags & flag)
                        && prop_del.tp_id == prop_this.tp_id
@@ -3577,7 +3578,7 @@ adjust_text_props_for_delete(
                {
                    found = TRUE;
                    prop_this.tp_flags &= ~flag;
-                   mch_memmove(text + textlen + done_del, &prop_this,
+                   mch_memmove(text + textlen + done_this, &prop_this,
                                                           sizeof(textprop_T));
                    break;
                }
index 8e12041427be0be0d7d3c1322354d5f0bf45570e..3203305e8c0174bed6231f27df92678879f607c9 100644 (file)
@@ -1645,6 +1645,57 @@ def Test_prop_add_delete_line()
   bwipe!
 enddef
 
+" This test is to detect a regression related to #10430. It is not an attempt
+" fully cover deleting lines in the presence of multi-line properties.
+def Test_delete_line_within_multiline_prop()
+  new
+  setline(1, '# Top.')
+  append(1, ['some_text = """', 'A string.', '"""', '# Bottom.'])
+  prop_type_add('Identifier', {'highlight': 'ModeMsg', 'priority': 0, 'combine': 0, 'start_incl': 0, 'end_incl': 0})
+  prop_type_add('String', {'highlight': 'MoreMsg', 'priority': 0, 'combine': 0, 'start_incl': 0, 'end_incl': 0})
+  prop_add(2, 1, {'type': 'Identifier', 'end_lnum': 2, 'end_col': 9})
+  prop_add(2, 13, {'type': 'String', 'end_lnum': 4, 'end_col': 4})
+
+  # The property for line 3 should extend into the previous and next lines.
+  var props = prop_list(3)
+  var prop = props[0]
+  assert_equal(1, len(props))
+  assert_equal(0, prop['start'])
+  assert_equal(0, prop['end'])
+
+  # This deletion should run without raising an exception.
+  try
+    :2 del
+  catch
+    assert_report('Line delete should have workd, but it raised an error.')
+  endtry
+
+  # The property for line 2 (was 3) should no longer extend into the previous
+  # line.
+  props = prop_list(2)
+  prop = props[0]
+  assert_equal(1, len(props))
+  assert_equal(1, prop['start'], 'Property was not changed to start within the line.')
+
+  # This deletion should run without raising an exception.
+  try
+    :3 del
+  catch
+    assert_report('Line delete should have workd, but it raised an error.')
+  endtry
+
+  # The property for line 2 (originally 3) should no longer extend into the next
+  # line.
+  props = prop_list(2)
+  prop = props[0]
+  assert_equal(1, len(props))
+  assert_equal(1, prop['end'], 'Property was not changed to end within the line.')
+
+  prop_type_delete('Identifier')
+  prop_type_delete('String')
+  bwip!
+enddef
+
 func Test_prop_in_linebreak()
   CheckRunVimInTerminal
 
index dca2f92092c6af148c6ee52efd184f4755b09986..52144c56c5e67d065c3d9f7e18d567b234777f8d 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4960,
 /**/
     4959,
 /**/