From cd38bb4d83c942c4bad596835c6766cbf32e5195 Mon Sep 17 00:00:00 2001
From: Bram Moolenaar <Bram@vim.org>
Date: Sun, 26 Jun 2022 14:04:07 +0100
Subject: [PATCH] patch 8.2.5163: crash when deleting buffers in diff mode

Problem:    Crash when deleting buffers in diff mode.
Solution:   Recompute diffs later.  Skip window without a valid buffer.
---
 src/diff.c                    | 10 ++++++++--
 src/testdir/test_diffmode.vim | 12 ++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/diff.c b/src/diff.c
index f996904..8569a9f 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -107,7 +107,12 @@ diff_buf_delete(buf_T *buf)
 	    tp->tp_diffbuf[i] = NULL;
 	    tp->tp_diff_invalid = TRUE;
 	    if (tp == curtab)
-		diff_redraw(TRUE);
+	    {
+		// don't redraw right away, more might change or buffer state
+		// is invalid right now
+		need_diff_redraw = TRUE;
+		redraw_later(VALID);
+	    }
 	}
     }
 }
@@ -655,7 +660,8 @@ diff_redraw(
 
     need_diff_redraw = FALSE;
     FOR_ALL_WINDOWS(wp)
-	if (wp->w_p_diff)
+	// when closing windows or wiping buffers skip invalid window
+	if (wp->w_p_diff && buf_valid(wp->w_buffer))
 	{
 	    redraw_win_later(wp, SOME_VALID);
 #ifdef FEAT_FOLDING
diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim
index 61edbe2..5b48a75 100644
--- a/src/testdir/test_diffmode.vim
+++ b/src/testdir/test_diffmode.vim
@@ -827,3 +827,15 @@ func Test_diff_maintains_change_mark()
   bwipe!
   bwipe!
 endfunc
+ 
+" This was trying to update diffs for a buffer being closed
+func Test_diff_only()
+  silent! lfile
+  set diff
+  lopen
+  norm o
+  silent! norm o
+
+  set nodiff
+  %bwipe!
+endfunc
-- 
2.27.0

