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.