Patch 9.0.0646
Problem:    with 'smoothscroll' set CTRL-E does not work properly when
            'foldmethod' is set to "indent". (Yee Cheng Chin)
Solution:   Merge the code for scroling with folds and 'smoothscroll'.
            (closes #11262)
Files:      src/move.c, src/testdir/test_scroll_opt.vim


*** ../vim-9.0.0645/src/move.c  2022-10-03 12:11:10.090375611 +0100
--- src/move.c  2022-10-03 14:02:21.822947844 +0100
***************
*** 984,991 ****
  
  /*
   * Return the difference in column offset for the second screen line of a
!  * wrapped line.  It's 8 if 'number' or 'relativenumber' is on and 'n' is in
!  * 'cpoptions'.
   */
      int
  win_col_off2(win_T *wp)
--- 984,991 ----
  
  /*
   * Return the difference in column offset for the second screen line of a
!  * wrapped line.  It's positive if 'number' or 'relativenumber' is on and 'n'
!  * is in 'cpoptions'.
   */
      int
  win_col_off2(win_T *wp)
***************
*** 1463,1469 ****
      if (curwin->w_p_wrap && curwin->w_p_sms)
      {
        width1 = curwin->w_width - curwin_col_off();
!       width2 = width1 - curwin_col_off2();
      }
  
  #ifdef FEAT_FOLDING
--- 1463,1469 ----
      if (curwin->w_p_wrap && curwin->w_p_sms)
      {
        width1 = curwin->w_width - curwin_col_off();
!       width2 = width1 + curwin_col_off2();
      }
  
  #ifdef FEAT_FOLDING
***************
*** 1601,1624 ****
      long      line_count,
      int               byfold UNUSED)  // TRUE: count a closed fold as one line
  {
! #if defined(FEAT_FOLDING) || defined(FEAT_DIFF)
!     linenr_T  lnum;
  
!     if (
  # ifdef FEAT_FOLDING
!           (byfold && hasAnyFolding(curwin))
! #  ifdef FEAT_DIFF
!           ||
! #  endif
  # endif
  # ifdef FEAT_DIFF
!           curwin->w_p_diff
  # endif
            )
      {
!       // count each sequence of folded lines as one logical line
!       lnum = curwin->w_topline;
!       while (line_count--)
        {
  # ifdef FEAT_DIFF
            if (curwin->w_topfill > 0)
--- 1601,1631 ----
      long      line_count,
      int               byfold UNUSED)  // TRUE: count a closed fold as one line
  {
!     int               do_smoothscroll = curwin->w_p_wrap && curwin->w_p_sms;
  
!     if (do_smoothscroll
  # ifdef FEAT_FOLDING
!           || (byfold && hasAnyFolding(curwin))
  # endif
  # ifdef FEAT_DIFF
!           || curwin->w_p_diff
  # endif
            )
      {
!       int         width1 = curwin->w_width - curwin_col_off();
!       int         width2 = width1 + curwin_col_off2();
!       int         size = 0;
!       linenr_T    prev_topline = curwin->w_topline;
! 
!       if (do_smoothscroll)
!           size = win_linetabsize(curwin, curwin->w_topline,
!                                  ml_get(curwin->w_topline), (colnr_T)MAXCOL);
! 
!       // diff mode: first consume "topfill"
!       // 'smoothscroll': increase "w_skipcol" until it goes over the end of
!       // the line, then advance to the next line.
!       // folding: count each sequence of folded lines as one logical line.
!       for (int todo = line_count; todo > 0; --todo)
        {
  # ifdef FEAT_DIFF
            if (curwin->w_topfill > 0)
***************
*** 1626,1679 ****
            else
  # endif
            {
  # ifdef FEAT_FOLDING
                if (byfold)
                    (void)hasFolding(lnum, NULL, &lnum);
  # endif
!               if (lnum >= curbuf->b_ml.ml_line_count)
!                   break;
!               ++lnum;
! # ifdef FEAT_DIFF
!               curwin->w_topfill = diff_check_fill(curwin, lnum);
! # endif
!           }
!       }
!       // approximate w_botline
!       curwin->w_botline += lnum - curwin->w_topline;
!       curwin->w_topline = lnum;
!     }
!     else
! #endif
!     if (curwin->w_p_wrap && curwin->w_p_sms)
!     {
!       int off1 = curwin_col_off();
!       int off2 = off1 + curwin_col_off2();
!       int add;
!       int size = win_linetabsize(curwin, curwin->w_topline,
!                                  ml_get(curwin->w_topline), (colnr_T)MAXCOL);
!       linenr_T prev_topline = curwin->w_topline;
  
!       // 'smoothscroll': increase "w_skipcol" until it goes over the end of
!       // the line, then advance to the next line.
!       for (int todo = line_count; todo > 0; --todo)
!       {
!           add = curwin->w_width - (curwin->w_skipcol > 0 ? off2 : off1);
!           curwin->w_skipcol += add;
!           if (curwin->w_skipcol >= size)
!           {
!               if (curwin->w_topline == curbuf->b_ml.ml_line_count)
                {
!                   curwin->w_skipcol -= add;
!                   break;
                }
-               ++curwin->w_topline;
-               ++curwin->w_botline;    // approximate w_botline
-               curwin->w_skipcol = 0;
-               if (todo > 1)
-                   size = win_linetabsize(curwin, curwin->w_topline,
-                                  ml_get(curwin->w_topline), (colnr_T)MAXCOL);
            }
        }
        if (curwin->w_topline == prev_topline)
            // need to redraw even though w_topline didn't change
            redraw_later(UPD_NOT_VALID);
--- 1633,1686 ----
            else
  # endif
            {
+               linenr_T lnum = curwin->w_topline;
+ 
  # ifdef FEAT_FOLDING
                if (byfold)
+                   // for a closed fold: go to the last line in the fold
                    (void)hasFolding(lnum, NULL, &lnum);
  # endif
!               if (lnum == curwin->w_topline
!                                       && curwin->w_p_wrap && curwin->w_p_sms)
!               {
!                   // 'smoothscroll': increase "w_skipcol" until it goes over
!                   // the end of the line, then advance to the next line.
!                   int add = curwin->w_skipcol > 0 ? width2 : width1;
!                   curwin->w_skipcol += add;
!                   if (curwin->w_skipcol >= size)
!                   {
!                       if (lnum == curbuf->b_ml.ml_line_count)
!                       {
!                           // at the last screen line, can't scroll further
!                           curwin->w_skipcol -= add;
!                           break;
!                       }
!                       ++lnum;
!                   }
!               }
!               else
!               {
!                   if (lnum >= curbuf->b_ml.ml_line_count)
!                       break;
!                   ++lnum;
!               }
  
!               if (lnum > curwin->w_topline)
                {
!                   // approximate w_botline
!                   curwin->w_botline += lnum - curwin->w_topline;
!                   curwin->w_topline = lnum;
! # ifdef FEAT_DIFF
!                   curwin->w_topfill = diff_check_fill(curwin, lnum);
! # endif
!                   curwin->w_skipcol = 0;
!                   if (todo > 1 && do_smoothscroll)
!                       size = win_linetabsize(curwin, curwin->w_topline,
!                               ml_get(curwin->w_topline), (colnr_T)MAXCOL);
                }
            }
        }
+ 
        if (curwin->w_topline == prev_topline)
            // need to redraw even though w_topline didn't change
            redraw_later(UPD_NOT_VALID);
*** ../vim-9.0.0645/src/testdir/test_scroll_opt.vim     2022-10-03 
12:11:10.090375611 +0100
--- src/testdir/test_scroll_opt.vim     2022-10-03 14:00:10.659513637 +0100
***************
*** 88,93 ****
--- 88,108 ----
    call term_sendkeys(buf, "\<C-Y>")
    call VerifyScreenDump(buf, 'Test_smoothscroll_8', {})
  
+   if has('folding')
+     call term_sendkeys(buf, ":set foldmethod=indent\<CR>")
+     " move the cursor so we can reuse the same dumps
+     call term_sendkeys(buf, "5G")
+     call term_sendkeys(buf, "\<C-E>")
+     call VerifyScreenDump(buf, 'Test_smoothscroll_1', {})
+     call term_sendkeys(buf, "\<C-E>")
+     call VerifyScreenDump(buf, 'Test_smoothscroll_2', {})
+     call term_sendkeys(buf, "7G")
+     call term_sendkeys(buf, "\<C-Y>")
+     call VerifyScreenDump(buf, 'Test_smoothscroll_7', {})
+     call term_sendkeys(buf, "\<C-Y>")
+     call VerifyScreenDump(buf, 'Test_smoothscroll_8', {})
+   endif
+ 
    call StopVimInTerminal(buf)
  endfunc
  
*** ../vim-9.0.0645/src/version.c       2022-10-03 12:11:10.090375611 +0100
--- src/version.c       2022-10-03 14:04:30.250427982 +0100
***************
*** 701,702 ****
--- 701,704 ----
  {   /* Add new patch number below this line */
+ /**/
+     646,
  /**/

-- 
Place mark here ->[ ]<- if you want a dirty monitor.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221003130635.5CC381C09A3%40moolenaar.net.

Raspunde prin e-mail lui