Patch 9.0.0751
Problem:    'scrolloff' does not work well with 'smoothscroll'.
Solution:   Make positioning the cursor a bit better.  Rename functions.
Files:      src/move.c, src/charset.c, src/proto/charset.pro,
            src/edit.c, src/ex_cmds.c, src/misc2.c, src/normal.c, src/ops.c,
            src/popupwin.c


*** ../vim-9.0.0750/src/move.c  2022-10-13 21:54:23.962227932 +0100
--- src/move.c  2022-10-14 19:26:23.502782783 +0100
***************
*** 1633,1639 ****
  
      if (curwin->w_cursor.lnum == curwin->w_topline && do_sms)
      {
!       long    so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so;
        int     scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
  
        // make sure the cursor is in the visible text
--- 1633,1639 ----
  
      if (curwin->w_cursor.lnum == curwin->w_topline && do_sms)
      {
!       long    so = get_scrolloff_value();
        int     scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
  
        // make sure the cursor is in the visible text
***************
*** 1684,1691 ****
        linenr_T    prev_topline = curwin->w_topline;
  
        if (do_sms)
!           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
--- 1684,1690 ----
        linenr_T    prev_topline = curwin->w_topline;
  
        if (do_sms)
!           size = linetabsize(curwin, curwin->w_topline);
  
        // diff mode: first consume "topfill"
        // 'smoothscroll': increase "w_skipcol" until it goes over the end of
***************
*** 1740,1747 ****
  # endif
                    curwin->w_skipcol = 0;
                    if (todo > 1 && do_sms)
!                       size = win_linetabsize(curwin, curwin->w_topline,
!                               ml_get(curwin->w_topline), (colnr_T)MAXCOL);
                }
            }
        }
--- 1739,1745 ----
  # endif
                    curwin->w_skipcol = 0;
                    if (todo > 1 && do_sms)
!                       size = linetabsize(curwin, curwin->w_topline);
                }
            }
        }
***************
*** 1784,1794 ****
      {
        int     width1 = curwin->w_width - curwin_col_off();
        int     width2 = width1 + curwin_col_off2();
!       long    so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so;
        int     scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
  
        // Make sure the cursor is in a visible part of the line, taking
        // 'scrolloff' into account, but using screen lines.
        validate_virtcol();
        if (curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols)
        {
--- 1782,1796 ----
      {
        int     width1 = curwin->w_width - curwin_col_off();
        int     width2 = width1 + curwin_col_off2();
!       long    so = get_scrolloff_value();
        int     scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
+       int     space_cols = (curwin->w_height - 1) * width2;
  
        // Make sure the cursor is in a visible part of the line, taking
        // 'scrolloff' into account, but using screen lines.
+       // If there are not enough screen lines put the cursor in the middle.
+       if (scrolloff_cols > space_cols / 2)
+           scrolloff_cols = space_cols / 2;
        validate_virtcol();
        if (curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols)
        {
***************
*** 1823,1833 ****
  
      int           width1 = curwin->w_width - curwin_col_off();
      int           width2 = width1 + curwin_col_off2();
!     long    so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so;
      int           scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
      int           scrolled = FALSE;
  
      validate_virtcol();
      while (curwin->w_skipcol > 0
                 && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols)
      {
--- 1825,1846 ----
  
      int           width1 = curwin->w_width - curwin_col_off();
      int           width2 = width1 + curwin_col_off2();
!     long    so = get_scrolloff_value();
      int           scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
      int           scrolled = FALSE;
  
      validate_virtcol();
+     if (curwin->w_cline_height == curwin->w_height)
+     {
+       // the line just fits in the window, don't scroll
+       if (curwin->w_skipcol != 0)
+       {
+           curwin->w_skipcol = 0;
+           redraw_later(UPD_NOT_VALID);
+       }
+       return;
+     }
+ 
      while (curwin->w_skipcol > 0
                 && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols)
      {
***************
*** 2691,2696 ****
--- 2704,2722 ----
            )
        return;
  
+     if (curwin->w_p_sms && !curwin->w_p_wrap)
+     {
+       // 'smoothscroll is active
+       if (curwin->w_cline_height == curwin->w_height)
+       {
+           // The cursor line just fits in the window, don't scroll.
+           curwin->w_skipcol = 0;
+           return;
+       }
+       // TODO: If the cursor line doesn't fit in the window then only adjust
+       // w_skipcol.
+     }
+ 
      /*
       * Narrow down the area where the cursor can be put by taking lines from
       * the top and the bottom until:
*** ../vim-9.0.0750/src/charset.c       2022-10-13 22:12:07.160673838 +0100
--- src/charset.c       2022-10-14 14:48:29.506975353 +0100
***************
*** 743,755 ****
   * Does not handle text properties, since "s" is not a buffer line.
   */
      int
! linetabsize(char_u *s)
  {
      return linetabsize_col(0, s);
  }
  
  /*
!  * Like linetabsize(), but "s" starts at column "startcol".
   */
      int
  linetabsize_col(int startcol, char_u *s)
--- 743,755 ----
   * Does not handle text properties, since "s" is not a buffer line.
   */
      int
! linetabsize_str(char_u *s)
  {
      return linetabsize_col(0, s);
  }
  
  /*
!  * Like linetabsize_str(), but "s" starts at column "startcol".
   */
      int
  linetabsize_col(int startcol, char_u *s)
***************
*** 772,778 ****
  }
  
  /*
!  * Like linetabsize(), but for a given window instead of the current one.
   */
      int
  win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len)
--- 772,778 ----
  }
  
  /*
!  * Like linetabsize_str(), but for a given window instead of the current one.
   */
      int
  win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len)
***************
*** 785,790 ****
--- 785,801 ----
      return (int)cts.cts_vcol;
  }
  
+ /*
+  * Return the number of cells line "lnum" of window "wp" will take on the
+  * screen, taking into account the size of a tab and text properties.
+  */
+   int
+ linetabsize(win_T *wp, linenr_T lnum)
+ {
+     return win_linetabsize(wp, lnum,
+                      ml_get_buf(wp->w_buffer, lnum, FALSE), (colnr_T)MAXCOL);
+ }
+ 
      void
  win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
  {
*** ../vim-9.0.0750/src/proto/charset.pro       2022-09-10 20:00:31.121468657 
+0100
--- src/proto/charset.pro       2022-10-14 14:44:22.646987951 +0100
***************
*** 15,23 ****
  int vim_strsize(char_u *s);
  int vim_strnsize(char_u *s, int len);
  int chartabsize(char_u *p, colnr_T col);
! int linetabsize(char_u *s);
  int linetabsize_col(int startcol, char_u *s);
  int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len);
  void win_linetabsize_cts(chartabsize_T *cts, colnr_T len);
  int vim_isIDc(int c);
  int vim_isNormalIDc(int c);
--- 15,24 ----
  int vim_strsize(char_u *s);
  int vim_strnsize(char_u *s, int len);
  int chartabsize(char_u *p, colnr_T col);
! int linetabsize_str(char_u *s);
  int linetabsize_col(int startcol, char_u *s);
  int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len);
+ int linetabsize(win_T *wp, linenr_T lnum);
  void win_linetabsize_cts(chartabsize_T *cts, colnr_T len);
  int vim_isIDc(int c);
  int vim_isNormalIDc(int c);
*** ../vim-9.0.0750/src/edit.c  2022-10-13 22:12:07.164673822 +0100
--- src/edit.c  2022-10-14 14:45:07.154983652 +0100
***************
*** 237,243 ****
        if (startln)
            Insstart.col = 0;
      }
!     Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
      Insstart_blank_vcol = MAXCOL;
      if (!did_ai)
        ai_col = 0;
--- 237,243 ----
        if (startln)
            Insstart.col = 0;
      }
!     Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline());
      Insstart_blank_vcol = MAXCOL;
      if (!did_ai)
        ai_col = 0;
***************
*** 2372,2378 ****
            // Don't update the original insert position when moved to the
            // right, except when nothing was inserted yet.
            update_Insstart_orig = FALSE;
!       Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
  
        if (u_save_cursor() == OK)
        {
--- 2372,2378 ----
            // Don't update the original insert position when moved to the
            // right, except when nothing was inserted yet.
            update_Insstart_orig = FALSE;
!       Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline());
  
        if (u_save_cursor() == OK)
        {
*** ../vim-9.0.0750/src/ex_cmds.c       2022-10-04 16:23:39.010042185 +0100
--- src/ex_cmds.c       2022-10-14 14:45:29.902981847 +0100
***************
*** 256,262 ****
        ;
      save = *last;
      *last = NUL;
!     len = linetabsize(line);          // get line length
      if (has_tab != NULL)              // check for embedded TAB
        *has_tab = (vim_strchr(first, TAB) != NULL);
      *last = save;
--- 256,262 ----
        ;
      save = *last;
      *last = NUL;
!     len = linetabsize_str(line);      // get line length on screen
      if (has_tab != NULL)              // check for embedded TAB
        *has_tab = (vim_strchr(first, TAB) != NULL);
      *last = save;
*** ../vim-9.0.0750/src/misc2.c 2022-09-26 19:50:07.463112932 +0100
--- src/misc2.c 2022-10-14 14:45:57.334979979 +0100
***************
*** 150,156 ****
  
            if ((addspaces || finetune) && !VIsual_active)
            {
!               curwin->w_curswant = linetabsize(line) + one_more;
                if (curwin->w_curswant > 0)
                    --curwin->w_curswant;
            }
--- 150,156 ----
  
            if ((addspaces || finetune) && !VIsual_active)
            {
!               curwin->w_curswant = linetabsize_str(line) + one_more;
                if (curwin->w_curswant > 0)
                    --curwin->w_curswant;
            }
***************
*** 166,172 ****
                && wcol >= (colnr_T)width
                && width > 0)
        {
!           csize = linetabsize(line);
            if (csize > 0)
                csize--;
  
--- 166,172 ----
                && wcol >= (colnr_T)width
                && width > 0)
        {
!           csize = linetabsize_str(line);
            if (csize > 0)
                csize--;
  
*** ../vim-9.0.0750/src/normal.c        2022-10-13 22:12:07.168673806 +0100
--- src/normal.c        2022-10-14 14:46:25.242978430 +0100
***************
*** 2266,2272 ****
      static int
  nv_screengo(oparg_T *oap, int dir, long dist)
  {
!     int               linelen = linetabsize(ml_get_curline());
      int               retval = OK;
      int               atend = FALSE;
      int               n;
--- 2266,2272 ----
      static int
  nv_screengo(oparg_T *oap, int dir, long dist)
  {
!     int               linelen = linetabsize_str(ml_get_curline());
      int               retval = OK;
      int               atend = FALSE;
      int               n;
***************
*** 2343,2349 ****
                }
                --curwin->w_cursor.lnum;
  
!               linelen = linetabsize(ml_get_curline());
                if (linelen > width1)
                    curwin->w_curswant += (((linelen - width1 - 1) / width2)
                                                                + 1) * width2;
--- 2343,2349 ----
                }
                --curwin->w_cursor.lnum;
  
!               linelen = linetabsize_str(ml_get_curline());
                if (linelen > width1)
                    curwin->w_curswant += (((linelen - width1 - 1) / width2)
                                                                + 1) * width2;
***************
*** 2383,2389 ****
                // clipped to column 0.
                if (curwin->w_curswant >= width1)
                    curwin->w_curswant -= width2;
!               linelen = linetabsize(ml_get_curline());
            }
        }
        }
--- 2383,2389 ----
                // clipped to column 0.
                if (curwin->w_curswant >= width1)
                    curwin->w_curswant -= width2;
!               linelen = linetabsize_str(ml_get_curline());
            }
        }
        }
***************
*** 6005,6011 ****
        {
            oap->motion_type = MCHAR;
            oap->inclusive = FALSE;
!           i = linetabsize(ml_get_curline());
            if (cap->count0 > 0 && cap->count0 <= 100)
                coladvance((colnr_T)(i * cap->count0 / 100));
            else
--- 6005,6011 ----
        {
            oap->motion_type = MCHAR;
            oap->inclusive = FALSE;
!           i = linetabsize_str(ml_get_curline());
            if (cap->count0 > 0 && cap->count0 <= 100)
                coladvance((colnr_T)(i * cap->count0 / 100));
            else
*** ../vim-9.0.0750/src/ops.c   2022-10-08 17:55:29.231208875 +0100
--- src/ops.c   2022-10-14 14:46:33.474978034 +0100
***************
*** 3261,3267 ****
                col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
                        (int)curwin->w_virtcol + 1);
                col_print(buf2, sizeof(buf2), (int)STRLEN(p),
!                                   linetabsize(p));
  
                if (char_count_cursor == byte_count_cursor
                        && char_count == byte_count)
--- 3261,3267 ----
                col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
                        (int)curwin->w_virtcol + 1);
                col_print(buf2, sizeof(buf2), (int)STRLEN(p),
!                                                          linetabsize_str(p));
  
                if (char_count_cursor == byte_count_cursor
                        && char_count == byte_count)
*** ../vim-9.0.0750/src/popupwin.c      2022-10-07 14:31:04.320852668 +0100
--- src/popupwin.c      2022-10-14 14:49:47.334976190 +0100
***************
*** 1403,1410 ****
        // "margin_width" is added to "len" where it matters.
        if (wp->w_width < maxwidth)
            wp->w_width = maxwidth;
!       len = win_linetabsize(wp, lnum, ml_get_buf(wp->w_buffer, lnum, FALSE),
!                                                             (colnr_T)MAXCOL);
        wp->w_width = w_width;
  
        if (wp->w_p_wrap)
--- 1403,1409 ----
        // "margin_width" is added to "len" where it matters.
        if (wp->w_width < maxwidth)
            wp->w_width = maxwidth;
!       len = linetabsize(wp, lnum);
        wp->w_width = w_width;
  
        if (wp->w_p_wrap)
*** ../vim-9.0.0750/src/version.c       2022-10-14 17:04:05.891675444 +0100
--- src/version.c       2022-10-14 20:07:07.147512335 +0100
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     751,
  /**/

-- 
ARTHUR: Go on, Bors, chop its head off.
BORS:   Right.  Silly little bleeder.  One rabbit stew coming up.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// 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/20221014192140.024C31C11B0%40moolenaar.net.

Raspunde prin e-mail lui