From 06ff540e1ca25f4c26670f184d4087f6e3188064 Mon Sep 17 00:00:00 2001
From: zeertzjq <zeertzjq@outlook.com>
Date: Wed, 6 Dec 2023 07:16:02 +0800
Subject: [PATCH] vim-patch:9.0.2151: 'breakindent' is not drawn after diff
 filler lines (#26412)

Problem:  'breakindent' is not drawn after diff filler lines.
Solution: Correct check for whether 'breakindent' should be drawn.

closes: vim/vim#13624

https://github.com/vim/vim/commit/588f20decebebedba3ad733f4f443a597e9747c3

Cherry-pick Test_diff_with_syntax() change from patch 9.0.1257.
---
 src/nvim/drawline.c                |  4 +--
 test/functional/ui/diff_spec.lua   | 39 ++++++++++++++++++-----
 test/old/testdir/test_diffmode.vim | 50 +++++++++++++++++++++---------
 3 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index e0887ed1d0..77bd05eb55 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -704,8 +704,8 @@ static void handle_breakindent(win_T *wp, winlinevars_T *wlv)
   if (wlv->draw_state == WL_BRI - 1 && wlv->n_extra == 0) {
     wlv->draw_state = WL_BRI;
     // if wlv->need_showbreak is set, breakindent also applies
-    if (wp->w_p_bri && (wlv->row != wlv->startrow || wlv->need_showbreak)
-        && wlv->filler_lines == 0) {
+    if (wp->w_p_bri && (wlv->row > wlv->startrow + wlv->filler_lines
+                        || wlv->need_showbreak)) {
       wlv->char_attr = 0;
       if (wlv->diff_hlf != (hlf_T)0) {
         wlv->char_attr = win_hl_attr(wp, (int)wlv->diff_hlf);
diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua
index 92b7235885..bcd1fc4090 100644
--- a/test/functional/ui/diff_spec.lua
+++ b/test/functional/ui/diff_spec.lua
@@ -11,6 +11,8 @@ local exec = helpers.exec
 local eq = helpers.eq
 local meths = helpers.meths
 
+before_each(clear)
+
 describe('Diff mode screen', function()
   local fname = 'Xtest-functional-diff-screen-1'
   local fname_2 = fname .. '.2'
@@ -21,7 +23,6 @@ describe('Diff mode screen', function()
   end
 
   setup(function()
-    clear()
     os.remove(fname)
     os.remove(fname_2)
   end)
@@ -32,7 +33,6 @@ describe('Diff mode screen', function()
   end)
 
   before_each(function()
-    clear()
     feed(':e ' .. fname_2 .. '<cr>')
     feed(':vnew ' .. fname .. '<cr>')
     feed(':diffthis<cr>')
@@ -1347,7 +1347,6 @@ end)
 
 it('win_update redraws lines properly', function()
   local screen
-  clear()
   screen = Screen.new(50, 10)
   screen:attach()
   screen:set_default_attr_ids({
@@ -1419,7 +1418,6 @@ end)
 
 -- oldtest: Test_diff_rnu()
 it('diff updates line numbers below filler lines', function()
-  clear()
   local screen = Screen.new(40, 14)
   screen:attach()
   screen:set_default_attr_ids({
@@ -1496,7 +1494,6 @@ end)
 
 -- oldtest: Test_diff_with_scroll_and_change()
 it('Align the filler lines when changing text in diff mode', function()
-  clear()
   local screen = Screen.new(40, 20)
   screen:attach()
   screen:set_default_attr_ids({
@@ -1588,7 +1585,6 @@ it('Align the filler lines when changing text in diff mode', function()
 end)
 
 it("diff mode doesn't restore invalid 'foldcolumn' value #21647", function()
-  clear()
   local screen = Screen.new(60, 6)
   screen:set_default_attr_ids({
     [0] = {foreground = Screen.colors.Blue, bold = true};
@@ -1609,7 +1605,6 @@ end)
 
 -- oldtest: Test_diff_binary()
 it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', function()
-  clear()
   local screen = Screen.new(40, 20)
   screen:set_default_attr_ids({
     [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray};
@@ -1734,3 +1729,33 @@ it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', fun
                                             |
   ]])
 end)
+
+-- oldtest: Test_diff_breakindent_after_filler()
+it("diff mode draws 'breakindent' correctly after filler lines", function()
+  local screen = Screen.new(45, 8)
+  screen:attach()
+  screen:set_default_attr_ids({
+    [1] = {background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue};
+    [2] = {background = Screen.colors.LightBlue};
+    [3] = {background = Screen.colors.LightCyan, bold = true, foreground = Screen.colors.Blue};
+    [4] = {foreground = Screen.colors.Blue, bold = true};
+  })
+  exec([[
+    set laststatus=0 diffopt+=followwrap breakindent
+    call setline(1, ['a', '  ' .. repeat('c', 50)])
+    vnew
+    call setline(1, ['a', 'b', '  ' .. repeat('c', 50)])
+    windo diffthis
+    norm! G$
+  ]])
+  screen:expect([[
+    {1:  }a                   │{1:  }a                   |
+    {1:  }{2:b                   }│{1:  }{3:--------------------}|
+    {1:  }  cccccccccccccccccc│{1:  }  cccccccccccccccccc|
+    {1:  }  cccccccccccccccccc│{1:  }  cccccccccccccccccc|
+    {1:  }  cccccccccccccc    │{1:  }  ccccccccccccc^c    |
+    {4:~                     }│{4:~                     }|
+    {4:~                     }│{4:~                     }|
+                                                 |
+  ]])
+end)
diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim
index fd94f4a7b2..89a38bcf51 100644
--- a/test/old/testdir/test_diffmode.vim
+++ b/test/old/testdir/test_diffmode.vim
@@ -1083,18 +1083,19 @@ endfunc
 func Test_diff_with_cursorline_breakindent()
   CheckScreendump
 
-  call writefile([
-	\ 'hi CursorLine ctermbg=red ctermfg=white',
-	\ 'set noequalalways wrap diffopt=followwrap cursorline breakindent',
-	\ '50vnew',
-	\ 'call setline(1, ["  ","  ","  ","  "])',
-	\ 'exe "norm 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>"',
-	\ 'vnew',
-	\ 'call setline(1, ["  ","  ","  ","  "])',
-	\ 'exe "norm 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>"',
-	\ 'windo diffthis',
-	\ '2wincmd w',
-	\ ], 'Xtest_diff_cursorline_breakindent', 'D')
+  let lines =<< trim END
+    hi CursorLine ctermbg=red ctermfg=white
+    set noequalalways wrap diffopt=followwrap cursorline breakindent
+    50vnew
+    call setline(1, ['  ', '  ', '  ', '  '])
+    exe "norm! 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>"
+    vnew
+    call setline(1, ['  ', '  ', '  ', '  '])
+    exe "norm! 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>"
+    windo diffthis
+    2wincmd w
+  END
+  call writefile(lines, 'Xtest_diff_cursorline_breakindent', 'D')
   let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {})
 
   call term_sendkeys(buf, "gg0")
@@ -1110,11 +1111,30 @@ func Test_diff_with_cursorline_breakindent()
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_diff_breakindent_after_filler()
+  CheckScreendump
+
+  let lines =<< trim END
+    set laststatus=0 diffopt+=followwrap breakindent
+    call setline(1, ['a', '  ' .. repeat('c', 50)])
+    vnew
+    call setline(1, ['a', 'b', '  ' .. repeat('c', 50)])
+    windo diffthis
+    norm! G$
+  END
+  call writefile(lines, 'Xtest_diff_breakindent_after_filler', 'D')
+  let buf = RunVimInTerminal('-S Xtest_diff_breakindent_after_filler', #{rows: 8, cols: 45})
+  call VerifyScreenDump(buf, 'Test_diff_breakindent_after_filler', {})
+
+  " clean up
+  call StopVimInTerminal(buf)
+endfunc
+
 func Test_diff_with_syntax()
   CheckScreendump
 
   let lines =<< trim END
-  	void doNothing() {
+	void doNothing() {
 	   int x = 0;
 	   char *s = "hello";
 	   return 5;
@@ -1122,7 +1142,7 @@ func Test_diff_with_syntax()
   END
   call writefile(lines, 'Xprogram1.c', 'D')
   let lines =<< trim END
-  	void doSomething() {
+	void doSomething() {
 	   int x = 0;
 	   char *s = "there";
 	   return 5;
@@ -1131,7 +1151,7 @@ func Test_diff_with_syntax()
   call writefile(lines, 'Xprogram2.c', 'D')
 
   let lines =<< trim END
-  	edit Xprogram1.c
+	edit Xprogram1.c
 	diffsplit Xprogram2.c
   END
   call writefile(lines, 'Xtest_diff_syntax', 'D')