]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1530: cursor moves to wrong line when 'foldmethod' is "diff" v9.0.1530
authorLuuk van Baal <luukvbaal@gmail.com>
Tue, 9 May 2023 15:01:17 +0000 (16:01 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 9 May 2023 15:01:17 +0000 (16:01 +0100)
Problem:    Cursor moves to wrong line when 'foldmethod' is "diff". (Rick
            Howe)
Solution:   Adjust logic for scrolling. (Luuk van Baal, closes #12364,
            closes #12218)

src/move.c
src/testdir/dumps/Test_normal_j_below_botline.dump [new file with mode: 0644]
src/testdir/test_normal.vim
src/version.c

index d35bd693d67b248bbe4ea8cc68aa48823e489440..3e5f6d52ce2045c08358ca9c27ce1417b6b28c06 100644 (file)
@@ -1752,22 +1752,6 @@ scrolldown(
     }
 }
 
-/*
- * Return TRUE if scrollup() will scroll by screen line rather than text line.
- */
-    static int
-scrolling_screenlines(int byfold UNUSED)
-{
-    return (curwin->w_p_wrap && curwin->w_p_sms)
-# ifdef FEAT_FOLDING
-       || (byfold && hasAnyFolding(curwin))
-# endif
-# ifdef FEAT_DIFF
-       || (curwin->w_p_diff && !curwin->w_p_wrap)
-# endif
-       ;
-}
-
 /*
  * Scroll the current window up by "line_count" logical lines.  "CTRL-E"
  */
@@ -1778,7 +1762,14 @@ scrollup(
 {
     int                do_sms = curwin->w_p_wrap && curwin->w_p_sms;
 
-    if (scrolling_screenlines(byfold))
+    if (do_sms
+# ifdef FEAT_FOLDING
+           || (byfold && hasAnyFolding(curwin))
+# endif
+# ifdef FEAT_DIFF
+           || (curwin->w_p_diff && !curwin->w_p_wrap)
+# endif
+       )
     {
        int         width1 = curwin->w_width - curwin_col_off();
        int         width2 = width1 + curwin_col_off2();
@@ -2466,7 +2457,6 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
 {
     int                used;
     int                scrolled = 0;
-    int                min_scrolled = 1;
     int                extra = 0;
     int                i;
     linenr_T   line_count;
@@ -2483,6 +2473,7 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
     int                old_empty_rows = curwin->w_empty_rows;
     linenr_T   cln;                // Cursor Line Number
     long       so = get_scrolloff_value();
+    int                do_sms = curwin->w_p_wrap && curwin->w_p_sms;
 
     cln = curwin->w_cursor.lnum;
     if (set_topbot)
@@ -2504,7 +2495,7 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
                break;
            if (used + loff.height > curwin->w_height)
            {
-               if (curwin->w_p_sms && curwin->w_p_wrap)
+               if (do_sms)
                {
                    // 'smoothscroll' and 'wrap' are set.  The above line is
                    // too long to show in its entirety, so we show just a part
@@ -2565,15 +2556,9 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
        scrolled = used;
        if (cln == curwin->w_botline)
            scrolled -= curwin->w_empty_rows;
-       min_scrolled = scrolled;
-       if (curwin->w_p_sms && curwin->w_p_wrap)
+       if (do_sms)
        {
-           // 'smoothscroll' and 'wrap' are set
-           if (cln > curwin->w_botline)
-               // add screen lines below w_botline
-               for (linenr_T lnum = curwin->w_botline + 1; lnum <= cln; ++lnum)
-                   min_scrolled += PLINES_NOFILL(lnum);
-
+           // 'smoothscroll' and 'wrap' are set.
            // Calculate how many screen lines the current top line of window
            // occupies. If it is occupying more than the entire window, we
            // need to scroll the additional clipped lines to scroll past the
@@ -2598,7 +2583,6 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
            if (top_plines > curwin->w_height)
            {
                scrolled += (top_plines - curwin->w_height);
-               min_scrolled += (top_plines - curwin->w_height);
            }
        }
     }
@@ -2725,22 +2709,12 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
      */
     if (line_count >= curwin->w_height && line_count > min_scroll)
        scroll_cursor_halfway(FALSE, TRUE);
-    else
+    else if (line_count > 0)
     {
-       // With 'smoothscroll' scroll at least the height of the cursor line,
-       // unless it would move the cursor.
-       if (curwin->w_p_wrap && curwin->w_p_sms && line_count < min_scrolled
-               && (curwin->w_cursor.lnum < curwin->w_topline
-                   || (curwin->w_virtcol - curwin->w_skipcol >=
-                                         curwin->w_width - curwin_col_off())))
-           line_count = min_scrolled;
-       if (line_count > 0)
-       {
-           if (scrolling_screenlines(TRUE))
-               scrollup(scrolled, TRUE);  // TODO
-           else
-               scrollup(line_count, TRUE);
-       }
+       if (do_sms)
+           scrollup(scrolled, TRUE);  // TODO
+       else
+           scrollup(line_count, TRUE);
     }
 
     /*
diff --git a/src/testdir/dumps/Test_normal_j_below_botline.dump b/src/testdir/dumps/Test_normal_j_below_botline.dump
new file mode 100644 (file)
index 0000000..e736b64
--- /dev/null
@@ -0,0 +1,19 @@
+| +0#af5f00255#ffffff0@1|2| |2+0#0000000&@35
+| +0#af5f00255&@3|2+0#0000000&@35
+| +0#af5f00255&@3|2+0#0000000&@35
+| +0#af5f00255&@3|2+0#0000000&@35
+| +0#af5f00255&@3|2+0#0000000&@35
+| +0#af5f00255&@3|2+0#0000000&@19| @15
+| +0#af5f00255&@1|3| |3+0#0000000&@35
+| +0#af5f00255&@3|3+0#0000000&@35
+| +0#af5f00255&@3|3+0#0000000&@35
+| +0#af5f00255&@3|3+0#0000000&@35
+| +0#af5f00255&@3|3+0#0000000&@35
+| +0#af5f00255&@3|3+0#0000000&@19| @15
+| +0#af5f00255&@1|4| >4+0#0000000&@35
+| +0#af5f00255&@3|4+0#0000000&@35
+| +0#af5f00255&@3|4+0#0000000&@35
+| +0#af5f00255&@3|4+0#0000000&@35
+| +0#af5f00255&@3|4+0#0000000&@35
+| +0#af5f00255&@3|4+0#0000000&@19| @15
+@22|4|,|1| @10|1|6|%| 
index 470b41cb08dc7407ec723f89500d72a5cac527e3..a3d9454d2c01ec9cd48d56dccfae8f60b9255c40 100644 (file)
@@ -3980,4 +3980,22 @@ func Test_mouse_shape_after_cancelling_gr()
   call delete('Xmouseshapes')
 endfunc
 
+" Test that "j" does not skip lines when scrolling below botline and
+" 'foldmethod' is not "manual".
+func Test_normal_j_below_botline()
+  CheckScreendump
+
+  let lines =<< trim END
+    set number foldmethod=diff scrolloff=0
+    call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
+    norm Lj
+  END
+  call writefile(lines, 'XNormalJBelowBotline', 'D')
+  let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
+
+  call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 1745dcd030ff73a213fb948595c6494e0806eb76..310803cb82938f69bba0f21803500b9f96525706 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1530,
 /**/
     1529,
 /**/