Skip to content

Commit c9121f7

Browse files
committed
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.
1 parent 0abd6cf commit c9121f7

File tree

10 files changed

+62
-23
lines changed

10 files changed

+62
-23
lines changed

src/charset.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -743,13 +743,13 @@ win_chartabsize(win_T *wp, char_u *p, colnr_T col)
743743
* Does not handle text properties, since "s" is not a buffer line.
744744
*/
745745
int
746-
linetabsize(char_u *s)
746+
linetabsize_str(char_u *s)
747747
{
748748
return linetabsize_col(0, s);
749749
}
750750

751751
/*
752-
* Like linetabsize(), but "s" starts at column "startcol".
752+
* Like linetabsize_str(), but "s" starts at column "startcol".
753753
*/
754754
int
755755
linetabsize_col(int startcol, char_u *s)
@@ -772,7 +772,7 @@ linetabsize_col(int startcol, char_u *s)
772772
}
773773

774774
/*
775-
* Like linetabsize(), but for a given window instead of the current one.
775+
* Like linetabsize_str(), but for a given window instead of the current one.
776776
*/
777777
int
778778
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)
785785
return (int)cts.cts_vcol;
786786
}
787787

788+
/*
789+
* Return the number of cells line "lnum" of window "wp" will take on the
790+
* screen, taking into account the size of a tab and text properties.
791+
*/
792+
int
793+
linetabsize(win_T *wp, linenr_T lnum)
794+
{
795+
return win_linetabsize(wp, lnum,
796+
ml_get_buf(wp->w_buffer, lnum, FALSE), (colnr_T)MAXCOL);
797+
}
798+
788799
void
789800
win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
790801
{

src/edit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ edit(
237237
if (startln)
238238
Insstart.col = 0;
239239
}
240-
Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
240+
Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline());
241241
Insstart_blank_vcol = MAXCOL;
242242
if (!did_ai)
243243
ai_col = 0;
@@ -2372,7 +2372,7 @@ stop_arrow(void)
23722372
// Don't update the original insert position when moved to the
23732373
// right, except when nothing was inserted yet.
23742374
update_Insstart_orig = FALSE;
2375-
Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
2375+
Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline());
23762376

23772377
if (u_save_cursor() == OK)
23782378
{

src/ex_cmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ linelen(int *has_tab)
256256
;
257257
save = *last;
258258
*last = NUL;
259-
len = linetabsize(line); // get line length
259+
len = linetabsize_str(line); // get line length on screen
260260
if (has_tab != NULL) // check for embedded TAB
261261
*has_tab = (vim_strchr(first, TAB) != NULL);
262262
*last = save;

src/misc2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ coladvance2(
150150

151151
if ((addspaces || finetune) && !VIsual_active)
152152
{
153-
curwin->w_curswant = linetabsize(line) + one_more;
153+
curwin->w_curswant = linetabsize_str(line) + one_more;
154154
if (curwin->w_curswant > 0)
155155
--curwin->w_curswant;
156156
}
@@ -166,7 +166,7 @@ coladvance2(
166166
&& wcol >= (colnr_T)width
167167
&& width > 0)
168168
{
169-
csize = linetabsize(line);
169+
csize = linetabsize_str(line);
170170
if (csize > 0)
171171
csize--;
172172

src/move.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,7 +1633,7 @@ scrolldown(
16331633

16341634
if (curwin->w_cursor.lnum == curwin->w_topline && do_sms)
16351635
{
1636-
long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so;
1636+
long so = get_scrolloff_value();
16371637
int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
16381638

16391639
// make sure the cursor is in the visible text
@@ -1684,8 +1684,7 @@ scrollup(
16841684
linenr_T prev_topline = curwin->w_topline;
16851685

16861686
if (do_sms)
1687-
size = win_linetabsize(curwin, curwin->w_topline,
1688-
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
1687+
size = linetabsize(curwin, curwin->w_topline);
16891688

16901689
// diff mode: first consume "topfill"
16911690
// 'smoothscroll': increase "w_skipcol" until it goes over the end of
@@ -1740,8 +1739,7 @@ scrollup(
17401739
# endif
17411740
curwin->w_skipcol = 0;
17421741
if (todo > 1 && do_sms)
1743-
size = win_linetabsize(curwin, curwin->w_topline,
1744-
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
1742+
size = linetabsize(curwin, curwin->w_topline);
17451743
}
17461744
}
17471745
}
@@ -1784,11 +1782,15 @@ scrollup(
17841782
{
17851783
int width1 = curwin->w_width - curwin_col_off();
17861784
int width2 = width1 + curwin_col_off2();
1787-
long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so;
1785+
long so = get_scrolloff_value();
17881786
int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
1787+
int space_cols = (curwin->w_height - 1) * width2;
17891788

17901789
// Make sure the cursor is in a visible part of the line, taking
17911790
// 'scrolloff' into account, but using screen lines.
1791+
// If there are not enough screen lines put the cursor in the middle.
1792+
if (scrolloff_cols > space_cols / 2)
1793+
scrolloff_cols = space_cols / 2;
17921794
validate_virtcol();
17931795
if (curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols)
17941796
{
@@ -1823,11 +1825,22 @@ adjust_skipcol(void)
18231825

18241826
int width1 = curwin->w_width - curwin_col_off();
18251827
int width2 = width1 + curwin_col_off2();
1826-
long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so;
1828+
long so = get_scrolloff_value();
18271829
int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
18281830
int scrolled = FALSE;
18291831

18301832
validate_virtcol();
1833+
if (curwin->w_cline_height == curwin->w_height)
1834+
{
1835+
// the line just fits in the window, don't scroll
1836+
if (curwin->w_skipcol != 0)
1837+
{
1838+
curwin->w_skipcol = 0;
1839+
redraw_later(UPD_NOT_VALID);
1840+
}
1841+
return;
1842+
}
1843+
18311844
while (curwin->w_skipcol > 0
18321845
&& curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols)
18331846
{
@@ -2691,6 +2704,19 @@ cursor_correct(void)
26912704
)
26922705
return;
26932706

2707+
if (curwin->w_p_sms && !curwin->w_p_wrap)
2708+
{
2709+
// 'smoothscroll is active
2710+
if (curwin->w_cline_height == curwin->w_height)
2711+
{
2712+
// The cursor line just fits in the window, don't scroll.
2713+
curwin->w_skipcol = 0;
2714+
return;
2715+
}
2716+
// TODO: If the cursor line doesn't fit in the window then only adjust
2717+
// w_skipcol.
2718+
}
2719+
26942720
/*
26952721
* Narrow down the area where the cursor can be put by taking lines from
26962722
* the top and the bottom until:

src/normal.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,7 +2266,7 @@ find_decl(
22662266
static int
22672267
nv_screengo(oparg_T *oap, int dir, long dist)
22682268
{
2269-
int linelen = linetabsize(ml_get_curline());
2269+
int linelen = linetabsize_str(ml_get_curline());
22702270
int retval = OK;
22712271
int atend = FALSE;
22722272
int n;
@@ -2343,7 +2343,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
23432343
}
23442344
--curwin->w_cursor.lnum;
23452345

2346-
linelen = linetabsize(ml_get_curline());
2346+
linelen = linetabsize_str(ml_get_curline());
23472347
if (linelen > width1)
23482348
curwin->w_curswant += (((linelen - width1 - 1) / width2)
23492349
+ 1) * width2;
@@ -2383,7 +2383,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
23832383
// clipped to column 0.
23842384
if (curwin->w_curswant >= width1)
23852385
curwin->w_curswant -= width2;
2386-
linelen = linetabsize(ml_get_curline());
2386+
linelen = linetabsize_str(ml_get_curline());
23872387
}
23882388
}
23892389
}
@@ -6005,7 +6005,7 @@ nv_g_cmd(cmdarg_T *cap)
60056005
{
60066006
oap->motion_type = MCHAR;
60076007
oap->inclusive = FALSE;
6008-
i = linetabsize(ml_get_curline());
6008+
i = linetabsize_str(ml_get_curline());
60096009
if (cap->count0 > 0 && cap->count0 <= 100)
60106010
coladvance((colnr_T)(i * cap->count0 / 100));
60116011
else

src/ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3261,7 +3261,7 @@ cursor_pos_info(dict_T *dict)
32613261
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
32623262
(int)curwin->w_virtcol + 1);
32633263
col_print(buf2, sizeof(buf2), (int)STRLEN(p),
3264-
linetabsize(p));
3264+
linetabsize_str(p));
32653265

32663266
if (char_count_cursor == byte_count_cursor
32673267
&& char_count == byte_count)

src/popupwin.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,8 +1403,7 @@ popup_adjust_position(win_T *wp)
14031403
// "margin_width" is added to "len" where it matters.
14041404
if (wp->w_width < maxwidth)
14051405
wp->w_width = maxwidth;
1406-
len = win_linetabsize(wp, lnum, ml_get_buf(wp->w_buffer, lnum, FALSE),
1407-
(colnr_T)MAXCOL);
1406+
len = linetabsize(wp, lnum);
14081407
wp->w_width = w_width;
14091408

14101409
if (wp->w_p_wrap)

src/proto/charset.pro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ int ptr2cells(char_u *p);
1515
int vim_strsize(char_u *s);
1616
int vim_strnsize(char_u *s, int len);
1717
int chartabsize(char_u *p, colnr_T col);
18-
int linetabsize(char_u *s);
18+
int linetabsize_str(char_u *s);
1919
int linetabsize_col(int startcol, char_u *s);
2020
int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len);
21+
int linetabsize(win_T *wp, linenr_T lnum);
2122
void win_linetabsize_cts(chartabsize_T *cts, colnr_T len);
2223
int vim_isIDc(int c);
2324
int vim_isNormalIDc(int c);

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
751,
698700
/**/
699701
750,
700702
/**/

0 commit comments

Comments
 (0)