1
0
forked from aniani/vim

patch 9.0.0751: 'scrolloff' does not work well with 'smoothscroll'

Problem:    'scrolloff' does not work well with 'smoothscroll'.
Solution:   Make positioning the cursor a bit better.  Rename functions.
This commit is contained in:
Bram Moolenaar 2022-10-14 20:09:04 +01:00
parent 0abd6cf62d
commit c9121f798f
10 changed files with 62 additions and 23 deletions

View 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. * Does not handle text properties, since "s" is not a buffer line.
*/ */
int int
linetabsize(char_u *s) linetabsize_str(char_u *s)
{ {
return linetabsize_col(0, s); return linetabsize_col(0, s);
} }
/* /*
* Like linetabsize(), but "s" starts at column "startcol". * Like linetabsize_str(), but "s" starts at column "startcol".
*/ */
int int
linetabsize_col(int startcol, char_u *s) 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 int
win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len) 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 (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 void
win_linetabsize_cts(chartabsize_T *cts, colnr_T len) win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
{ {

View File

@ -237,7 +237,7 @@ edit(
if (startln) if (startln)
Insstart.col = 0; Insstart.col = 0;
} }
Insstart_textlen = (colnr_T)linetabsize(ml_get_curline()); Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline());
Insstart_blank_vcol = MAXCOL; Insstart_blank_vcol = MAXCOL;
if (!did_ai) if (!did_ai)
ai_col = 0; ai_col = 0;
@ -2372,7 +2372,7 @@ stop_arrow(void)
// Don't update the original insert position when moved to the // Don't update the original insert position when moved to the
// right, except when nothing was inserted yet. // right, except when nothing was inserted yet.
update_Insstart_orig = FALSE; 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) if (u_save_cursor() == OK)
{ {

View File

@ -256,7 +256,7 @@ linelen(int *has_tab)
; ;
save = *last; save = *last;
*last = NUL; *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 if (has_tab != NULL) // check for embedded TAB
*has_tab = (vim_strchr(first, TAB) != NULL); *has_tab = (vim_strchr(first, TAB) != NULL);
*last = save; *last = save;

View File

@ -150,7 +150,7 @@ coladvance2(
if ((addspaces || finetune) && !VIsual_active) 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) if (curwin->w_curswant > 0)
--curwin->w_curswant; --curwin->w_curswant;
} }
@ -166,7 +166,7 @@ coladvance2(
&& wcol >= (colnr_T)width && wcol >= (colnr_T)width
&& width > 0) && width > 0)
{ {
csize = linetabsize(line); csize = linetabsize_str(line);
if (csize > 0) if (csize > 0)
csize--; csize--;

View File

@ -1633,7 +1633,7 @@ scrolldown(
if (curwin->w_cursor.lnum == curwin->w_topline && do_sms) 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; int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
// make sure the cursor is in the visible text // make sure the cursor is in the visible text
@ -1684,8 +1684,7 @@ scrollup(
linenr_T prev_topline = curwin->w_topline; linenr_T prev_topline = curwin->w_topline;
if (do_sms) if (do_sms)
size = win_linetabsize(curwin, curwin->w_topline, size = linetabsize(curwin, curwin->w_topline);
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
// diff mode: first consume "topfill" // diff mode: first consume "topfill"
// 'smoothscroll': increase "w_skipcol" until it goes over the end of // 'smoothscroll': increase "w_skipcol" until it goes over the end of
@ -1740,8 +1739,7 @@ scrollup(
# endif # endif
curwin->w_skipcol = 0; curwin->w_skipcol = 0;
if (todo > 1 && do_sms) if (todo > 1 && do_sms)
size = win_linetabsize(curwin, curwin->w_topline, size = linetabsize(curwin, curwin->w_topline);
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
} }
} }
} }
@ -1784,11 +1782,15 @@ scrollup(
{ {
int width1 = curwin->w_width - curwin_col_off(); int width1 = curwin->w_width - curwin_col_off();
int width2 = width1 + curwin_col_off2(); 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 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 // Make sure the cursor is in a visible part of the line, taking
// 'scrolloff' into account, but using screen lines. // '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(); validate_virtcol();
if (curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) 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 width1 = curwin->w_width - curwin_col_off();
int width2 = width1 + curwin_col_off2(); 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 scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
int scrolled = FALSE; int scrolled = FALSE;
validate_virtcol(); 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 while (curwin->w_skipcol > 0
&& curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols)
{ {
@ -2691,6 +2704,19 @@ cursor_correct(void)
) )
return; 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 * Narrow down the area where the cursor can be put by taking lines from
* the top and the bottom until: * the top and the bottom until:

View File

@ -2266,7 +2266,7 @@ find_decl(
static int static int
nv_screengo(oparg_T *oap, int dir, long dist) 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 retval = OK;
int atend = FALSE; int atend = FALSE;
int n; int n;
@ -2343,7 +2343,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
} }
--curwin->w_cursor.lnum; --curwin->w_cursor.lnum;
linelen = linetabsize(ml_get_curline()); linelen = linetabsize_str(ml_get_curline());
if (linelen > width1) if (linelen > width1)
curwin->w_curswant += (((linelen - width1 - 1) / width2) curwin->w_curswant += (((linelen - width1 - 1) / width2)
+ 1) * width2; + 1) * width2;
@ -2383,7 +2383,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
// clipped to column 0. // clipped to column 0.
if (curwin->w_curswant >= width1) if (curwin->w_curswant >= width1)
curwin->w_curswant -= width2; 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->motion_type = MCHAR;
oap->inclusive = FALSE; oap->inclusive = FALSE;
i = linetabsize(ml_get_curline()); i = linetabsize_str(ml_get_curline());
if (cap->count0 > 0 && cap->count0 <= 100) if (cap->count0 > 0 && cap->count0 <= 100)
coladvance((colnr_T)(i * cap->count0 / 100)); coladvance((colnr_T)(i * cap->count0 / 100));
else else

View File

@ -3261,7 +3261,7 @@ cursor_pos_info(dict_T *dict)
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1, col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
(int)curwin->w_virtcol + 1); (int)curwin->w_virtcol + 1);
col_print(buf2, sizeof(buf2), (int)STRLEN(p), col_print(buf2, sizeof(buf2), (int)STRLEN(p),
linetabsize(p)); linetabsize_str(p));
if (char_count_cursor == byte_count_cursor if (char_count_cursor == byte_count_cursor
&& char_count == byte_count) && char_count == byte_count)

View File

@ -1403,8 +1403,7 @@ popup_adjust_position(win_T *wp)
// "margin_width" is added to "len" where it matters. // "margin_width" is added to "len" where it matters.
if (wp->w_width < maxwidth) if (wp->w_width < maxwidth)
wp->w_width = maxwidth; wp->w_width = maxwidth;
len = win_linetabsize(wp, lnum, ml_get_buf(wp->w_buffer, lnum, FALSE), len = linetabsize(wp, lnum);
(colnr_T)MAXCOL);
wp->w_width = w_width; wp->w_width = w_width;
if (wp->w_p_wrap) if (wp->w_p_wrap)

View File

@ -15,9 +15,10 @@ int ptr2cells(char_u *p);
int vim_strsize(char_u *s); int vim_strsize(char_u *s);
int vim_strnsize(char_u *s, int len); int vim_strnsize(char_u *s, int len);
int chartabsize(char_u *p, colnr_T col); 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 linetabsize_col(int startcol, char_u *s);
int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len); 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); void win_linetabsize_cts(chartabsize_T *cts, colnr_T len);
int vim_isIDc(int c); int vim_isIDc(int c);
int vim_isNormalIDc(int c); int vim_isNormalIDc(int c);

View File

@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
751,
/**/ /**/
750, 750,
/**/ /**/