diff src/undo.c @ 20581:e529690f27bc v8.2.0844

patch 8.2.0844: text properties crossing lines not handled correctly Commit: https://github.com/vim/vim/commit/a9d4b84d97fb74061eeb42c1433e111fb58825dc Author: Bram Moolenaar <Bram@vim.org> Date: Sat May 30 14:46:52 2020 +0200 patch 8.2.0844: text properties crossing lines not handled correctly Problem: Text properties crossing lines not handled correctly. Solution: When saving for undo include an extra line when needed and do not adjust properties when undoing. (Axel Forsman, closes #5875)
author Bram Moolenaar <Bram@vim.org>
date Sat, 30 May 2020 15:00:03 +0200
parents 06a1dd50463e
children 0b55c9a14ea1
line wrap: on
line diff
--- a/src/undo.c
+++ b/src/undo.c
@@ -376,6 +376,27 @@ u_save_line(undoline_T *ul, linenr_T lnu
 }
 
 /*
+ * return TRUE if line "lnum" has text property "flags".
+ */
+    static int
+has_prop_w_flags(linenr_T lnum, int flags)
+{
+    char_u  *props;
+    int	    i;
+    int	    proplen = get_text_props(curbuf, lnum, &props, FALSE);
+
+    for (i = 0; i < proplen; ++i)
+    {
+	textprop_T prop;
+
+	mch_memmove(&prop, props + i * sizeof prop, sizeof prop);
+	if (prop.tp_flags & flags)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+/*
  * Common code for various ways to save text before a change.
  * "top" is the line above the first changed line.
  * "bot" is the line below the last changed line.
@@ -450,6 +471,23 @@ u_savecommon(
     u_check(FALSE);
 #endif
 
+#ifdef FEAT_PROP_POPUP
+    // Include the line above if a text property continues from it.
+    // Include the line below if a text property continues to it.
+    if (bot - top > 1)
+    {
+	if (top > 0 && has_prop_w_flags(top + 1, TP_FLAG_CONT_PREV))
+	    --top;
+	if (bot <= curbuf->b_ml.ml_line_count
+			       && has_prop_w_flags(bot - 1, TP_FLAG_CONT_NEXT))
+	{
+	    ++bot;
+	    if (newbot != 0)
+		++newbot;
+	}
+    }
+#endif
+
     size = bot - top - 1;
 
     /*
@@ -2745,7 +2783,7 @@ u_undoredo(int undo)
 		// dummy empty line will be inserted
 		if (curbuf->b_ml.ml_line_count == 1)
 		    empty_buffer = TRUE;
-		ml_delete(lnum, FALSE);
+		ml_delete_flags(lnum, ML_DEL_UNDO);
 	    }
 	}
 	else
@@ -2767,8 +2805,8 @@ u_undoredo(int undo)
 		    ml_replace_len((linenr_T)1, uep->ue_array[i].ul_line,
 					  uep->ue_array[i].ul_len, TRUE, TRUE);
 		else
-		    ml_append(lnum, uep->ue_array[i].ul_line,
-				      (colnr_T)uep->ue_array[i].ul_len, FALSE);
+		    ml_append_flags(lnum, uep->ue_array[i].ul_line,
+			     (colnr_T)uep->ue_array[i].ul_len, ML_APPEND_UNDO);
 		vim_free(uep->ue_array[i].ul_line);
 	    }
 	    vim_free((char_u *)uep->ue_array);