changeset 14764:f562b9fbd0d3 v8.1.0394

patch 8.1.0394: diffs are not always updated correctly commit https://github.com/vim/vim/commit/e3521d9cbb786806eaff106707851d37d2c0ecef Author: Bram Moolenaar <Bram@vim.org> Date: Sun Sep 16 14:10:31 2018 +0200 patch 8.1.0394: diffs are not always updated correctly Problem: Diffs are not always updated correctly. Solution: When using internal diff update for any changes properly.
author Christian Brabandt <cb@256bit.org>
date Sun, 16 Sep 2018 14:15:05 +0200
parents bbd166434756
children 0b9111b6ec9b
files src/diff.c src/main.c src/misc1.c src/proto/diff.pro src/structs.h src/version.c
diffstat 6 files changed, 35 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/diff.c
+++ b/src/diff.c
@@ -292,6 +292,16 @@ diff_mark_adjust_tp(
     linenr_T	lnum_deleted = line1;	/* lnum of remaining deletion */
     int		check_unchanged;
 
+    if (diff_internal())
+    {
+	// Will udpate diffs before redrawing.  Set _invalid to update the
+	// diffs themselves, set _update to also update folds properly just
+	// before redrawing.
+	tp->tp_diff_invalid = TRUE;
+	tp->tp_diff_update = TRUE;
+	return;
+    }
+
     if (line2 == MAXLNUM)
     {
 	/* mark_adjust(99, MAXLNUM, 9, 0): insert lines */
@@ -640,7 +650,7 @@ diff_check_sanity(tabpage_T *tp, diff_T 
  */
     static void
 diff_redraw(
-    int		dofold)	    /* also recompute the folds */
+    int		dofold)	    // also recompute the folds
 {
     win_T	*wp;
     int		n;
@@ -863,7 +873,7 @@ theend:
  * Note that if the internal diff failed for one of the buffers, the external
  * diff will be used anyway.
  */
-    static int
+    int
 diff_internal(void)
 {
     return (diff_flags & DIFF_INTERNAL) != 0 && *p_dex == NUL;
@@ -887,9 +897,9 @@ diff_internal_failed(void)
 
 /*
  * Completely update the diffs for the buffers involved.
- * This uses the ordinary "diff" command.
- * The buffers are written to a file, also for unmodified buffers (the file
- * could have been produced by autocommands, e.g. the netrw plugin).
+ * When using the external "diff" command the buffers are written to a file,
+ * also for unmodified buffers (the file could have been produced by
+ * autocommands, e.g. the netrw plugin).
  */
     void
 ex_diffupdate(exarg_T *eap)	// "eap" can be NULL
--- a/src/main.c
+++ b/src/main.c
@@ -1200,6 +1200,15 @@ main_loop(
 	    }
 
 #if defined(FEAT_DIFF)
+	    // Updating diffs from changed() does not always work properly,
+	    // esp. updating folds.  Do an update just before redrawing if
+	    // needed.
+	    if (curtab->tp_diff_update || curtab->tp_diff_invalid)
+	    {
+		ex_diffupdate(NULL);
+		curtab->tp_diff_update = FALSE;
+	    }
+
 	    /* Scroll-binding for diff mode may have been postponed until
 	     * here.  Avoids doing it for every change. */
 	    if (diff_need_scrollbind)
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -3093,7 +3093,7 @@ changed_lines(
     changed_lines_buf(curbuf, lnum, lnume, xtra);
 
 #ifdef FEAT_DIFF
-    if (xtra == 0 && curwin->w_p_diff)
+    if (xtra == 0 && curwin->w_p_diff && !diff_internal())
     {
 	/* When the number of lines doesn't change then mark_adjust() isn't
 	 * called and other diff buffers still need to be marked for
@@ -3173,6 +3173,11 @@ changed_common(
     /* mark the buffer as modified */
     changed();
 
+#ifdef FEAT_DIFF
+    if (curwin->w_p_diff && diff_internal())
+	curtab->tp_diff_update = TRUE;
+#endif
+
     /* set the '. mark */
     if (!cmdmod.keepjumps)
     {
--- a/src/proto/diff.pro
+++ b/src/proto/diff.pro
@@ -4,6 +4,7 @@ void diff_buf_adjust(win_T *win);
 void diff_buf_add(buf_T *buf);
 void diff_invalidate(buf_T *buf);
 void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after);
+int diff_internal(void);
 void ex_diffupdate(exarg_T *eap);
 void ex_diffpatch(exarg_T *eap);
 void ex_diffsplit(exarg_T *eap);
--- a/src/structs.h
+++ b/src/structs.h
@@ -2509,7 +2509,8 @@ struct tabpage_S
 #ifdef FEAT_DIFF
     diff_T	    *tp_first_diff;
     buf_T	    *(tp_diffbuf[DB_COUNT]);
-    int		    tp_diff_invalid;	/* list of diffs is outdated */
+    int		    tp_diff_invalid;	// list of diffs is outdated
+    int		    tp_diff_update;	// update diffs before redrawing
 #endif
     frame_T	    *(tp_snapshot[SNAP_COUNT]);  /* window layout snapshots */
 #ifdef FEAT_EVAL
--- a/src/version.c
+++ b/src/version.c
@@ -795,6 +795,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    394,
+/**/
     393,
 /**/
     392,