]> granicus.if.org Git - vim/commitdiff
patch 9.0.0751: 'scrolloff' does not work well with 'smoothscroll' v9.0.0751
authorBram Moolenaar <Bram@vim.org>
Fri, 14 Oct 2022 19:09:04 +0000 (20:09 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 14 Oct 2022 19:09:04 +0000 (20:09 +0100)
Problem:    'scrolloff' does not work well with 'smoothscroll'.
Solution:   Make positioning the cursor a bit better.  Rename functions.

src/charset.c
src/edit.c
src/ex_cmds.c
src/misc2.c
src/move.c
src/normal.c
src/ops.c
src/popupwin.c
src/proto/charset.pro
src/version.c

index c4db9f8cae3a31cf06b52b29ee14b8b5a84e4d25..0e930776c76c3522801754b607407cdb493d8ec7 100644 (file)
@@ -743,13 +743,13 @@ win_chartabsize(win_T *wp, char_u *p, colnr_T col)
  * Does not handle text properties, since "s" is not a buffer line.
  */
     int
-linetabsize(char_u *s)
+linetabsize_str(char_u *s)
 {
     return linetabsize_col(0, s);
 }
 
 /*
- * Like linetabsize(), but "s" starts at column "startcol".
+ * Like linetabsize_str(), but "s" starts at column "startcol".
  */
     int
 linetabsize_col(int startcol, char_u *s)
@@ -772,7 +772,7 @@ linetabsize_col(int startcol, char_u *s)
 }
 
 /*
- * Like linetabsize(), but for a given window instead of the current one.
+ * 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,6 +785,17 @@ win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len)
     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)
 {
index 1aaac6277277b2a427a516596081166dc1b3b66b..555b83bc319943314121363d1183569e0d990712 100644 (file)
@@ -237,7 +237,7 @@ edit(
        if (startln)
            Insstart.col = 0;
     }
-    Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
+    Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline());
     Insstart_blank_vcol = MAXCOL;
     if (!did_ai)
        ai_col = 0;
@@ -2372,7 +2372,7 @@ stop_arrow(void)
            // 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());
+       Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline());
 
        if (u_save_cursor() == OK)
        {
index 3c13b8de293a9d5f6763806fa5c79bd342ed74a1..7f41c7915a425421351a7bf79e54c26192d0c453 100644 (file)
@@ -256,7 +256,7 @@ linelen(int *has_tab)
        ;
     save = *last;
     *last = NUL;
-    len = linetabsize(line);           // get line length
+    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;
index 5d36cc15297cfb7ea1faf3730982234611b883a8..84c5f431986f61237eea09e30896652735de4643 100644 (file)
@@ -150,7 +150,7 @@ coladvance2(
 
            if ((addspaces || finetune) && !VIsual_active)
            {
-               curwin->w_curswant = linetabsize(line) + one_more;
+               curwin->w_curswant = linetabsize_str(line) + one_more;
                if (curwin->w_curswant > 0)
                    --curwin->w_curswant;
            }
@@ -166,7 +166,7 @@ coladvance2(
                && wcol >= (colnr_T)width
                && width > 0)
        {
-           csize = linetabsize(line);
+           csize = linetabsize_str(line);
            if (csize > 0)
                csize--;
 
index 3a2eb5df89b43c7014a4d6198c2a65e145ff6157..c3f144ef3e696a4326e6de3c269ddaad73d33b33 100644 (file)
@@ -1633,7 +1633,7 @@ scrolldown(
 
     if (curwin->w_cursor.lnum == curwin->w_topline && do_sms)
     {
-       long    so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so;
+       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,8 +1684,7 @@ scrollup(
        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);
+           size = linetabsize(curwin, curwin->w_topline);
 
        // diff mode: first consume "topfill"
        // 'smoothscroll': increase "w_skipcol" until it goes over the end of
@@ -1740,8 +1739,7 @@ scrollup(
 # 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);
+                       size = linetabsize(curwin, curwin->w_topline);
                }
            }
        }
@@ -1784,11 +1782,15 @@ scrollup(
     {
        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;
+       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,11 +1825,22 @@ adjust_skipcol(void)
 
     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;
+    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,6 +2704,19 @@ cursor_correct(void)
            )
        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:
index a7c6d42aa9f0f782e98e66d2725a2bf58036f3d8..7b47f18a4c51f50c7b5ac0f3a4e19db6cf4fe447 100644 (file)
@@ -2266,7 +2266,7 @@ find_decl(
     static int
 nv_screengo(oparg_T *oap, int dir, long dist)
 {
-    int                linelen = linetabsize(ml_get_curline());
+    int                linelen = linetabsize_str(ml_get_curline());
     int                retval = OK;
     int                atend = FALSE;
     int                n;
@@ -2343,7 +2343,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
                }
                --curwin->w_cursor.lnum;
 
-               linelen = linetabsize(ml_get_curline());
+               linelen = linetabsize_str(ml_get_curline());
                if (linelen > width1)
                    curwin->w_curswant += (((linelen - width1 - 1) / width2)
                                                                + 1) * width2;
@@ -2383,7 +2383,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
                // clipped to column 0.
                if (curwin->w_curswant >= width1)
                    curwin->w_curswant -= width2;
-               linelen = linetabsize(ml_get_curline());
+               linelen = linetabsize_str(ml_get_curline());
            }
        }
       }
@@ -6005,7 +6005,7 @@ nv_g_cmd(cmdarg_T *cap)
        {
            oap->motion_type = MCHAR;
            oap->inclusive = FALSE;
-           i = linetabsize(ml_get_curline());
+           i = linetabsize_str(ml_get_curline());
            if (cap->count0 > 0 && cap->count0 <= 100)
                coladvance((colnr_T)(i * cap->count0 / 100));
            else
index 38827fffd03aa42ed38c703aa579d4a14e09adf0..a496c499d302959d99bd89ef0397c971527e1f54 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -3261,7 +3261,7 @@ cursor_pos_info(dict_T *dict)
                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));
+                                                          linetabsize_str(p));
 
                if (char_count_cursor == byte_count_cursor
                        && char_count == byte_count)
index f9cbcef48e9ee5a282c4f5c8aed0549ebef54fd7..9bc31746ec031ac99285f1d2064ed405bae67b06 100644 (file)
@@ -1403,8 +1403,7 @@ popup_adjust_position(win_T *wp)
        // "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);
+       len = linetabsize(wp, lnum);
        wp->w_width = w_width;
 
        if (wp->w_p_wrap)
index c7d5767954bab1ab93ad3ec8bc79085f25defe04..0277483370a13f127b5db095dc6c7a26398e8cd7 100644 (file)
@@ -15,9 +15,10 @@ int ptr2cells(char_u *p);
 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_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);
index bd9915a80fd3fec81aec482f82807c52819fdb49..34129a2453abb6da4a73b578b7de6475bfa1edda 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    751,
 /**/
     750,
 /**/