@@ -1621,7 +1621,7 @@ f_virtcol2col(typval_T *argvars UNUSED, typval_T *rettv)
16211621 */
16221622static void cursor_correct_sms (void )
16231623{
1624- if (!curwin -> w_p_sms || !curwin -> w_p_wrap
1624+ if (!curwin -> w_p_sms || !curwin -> w_p_wrap
16251625 || curwin -> w_cursor .lnum != curwin -> w_topline )
16261626 return ;
16271627
@@ -1631,8 +1631,7 @@ static void cursor_correct_sms(void)
16311631 int so_cols = so == 0 ? 0 : width1 + (so - 1 ) * width2 ;
16321632 int space_cols = (curwin -> w_height - 1 ) * width2 ;
16331633 int overlap , top , bot ;
1634- int size = so == 0 ? 0 : win_linetabsize (curwin , curwin -> w_topline ,
1635- ml_get (curwin -> w_topline ), (colnr_T )MAXCOL );
1634+ int size = so == 0 ? 0 : linetabsize_eol (curwin , curwin -> w_topline );
16361635
16371636 if (curwin -> w_topline == 1 && curwin -> w_skipcol == 0 )
16381637 so_cols = 0 ; // Ignore 'scrolloff' at top of buffer.
@@ -1645,10 +1644,10 @@ static void cursor_correct_sms(void)
16451644 if (so_cols >= width1 && so_cols > size )
16461645 so_cols -= width1 ;
16471646
1648- // If there is no marker or we have non-zero scrolloff, just ignore it.
1649- overlap = (curwin -> w_skipcol == 0 || so_cols != 0 ) ? 0
1650- : sms_marker_overlap ( curwin , -1 );
1651- top = curwin -> w_skipcol + overlap + so_cols ;
1647+ overlap = curwin -> w_skipcol == 0 ? 0
1648+ : sms_marker_overlap (curwin , curwin -> w_width - width2 );
1649+ // If we have non-zero scrolloff, ignore marker overlap.
1650+ top = curwin -> w_skipcol + ( so_cols != 0 ? so_cols : overlap ) ;
16521651 bot = curwin -> w_skipcol + width1 + (curwin -> w_height - 1 ) * width2
16531652 - so_cols ;
16541653 validate_virtcol ();
@@ -1667,12 +1666,28 @@ static void cursor_correct_sms(void)
16671666
16681667 if (col != curwin -> w_virtcol )
16691668 {
1669+ int rc ;
1670+
16701671 curwin -> w_curswant = col ;
1671- coladvance (curwin -> w_curswant );
1672+ rc = coladvance (curwin -> w_curswant );
16721673 // validate_virtcol() marked various things as valid, but after
16731674 // moving the cursor they need to be recomputed
16741675 curwin -> w_valid &=
16751676 ~(VALID_WROW |VALID_WCOL |VALID_CHEIGHT |VALID_CROW |VALID_VIRTCOL );
1677+ if (rc == FAIL && curwin -> w_skipcol > 0
1678+ && curwin -> w_cursor .lnum < curbuf -> b_ml .ml_line_count )
1679+ {
1680+ validate_virtcol ();
1681+ if (curwin -> w_virtcol < curwin -> w_skipcol + overlap )
1682+ {
1683+ // Cursor still not visible: move it to the next line instead.
1684+ curwin -> w_cursor .lnum ++ ;
1685+ curwin -> w_cursor .col = 0 ;
1686+ curwin -> w_cursor .coladd = 0 ;
1687+ curwin -> w_curswant = 0 ;
1688+ curwin -> w_valid &= ~VALID_VIRTCOL ;
1689+ }
1690+ }
16761691 }
16771692}
16781693
@@ -1813,8 +1828,7 @@ scrolldown(
18131828#endif
18141829 if (do_sms )
18151830 {
1816- int size = win_linetabsize (curwin , curwin -> w_topline ,
1817- ml_get (curwin -> w_topline ), (colnr_T )MAXCOL );
1831+ int size = linetabsize_eol (curwin , curwin -> w_topline );
18181832 if (size > width1 )
18191833 {
18201834 curwin -> w_skipcol = width1 ;
@@ -1911,7 +1925,7 @@ scrollup(
19111925 colnr_T prev_skipcol = curwin -> w_skipcol ;
19121926
19131927 if (do_sms )
1914- size = linetabsize (curwin , curwin -> w_topline );
1928+ size = linetabsize_eol (curwin , curwin -> w_topline );
19151929
19161930 // diff mode: first consume "topfill"
19171931 // 'smoothscroll': increase "w_skipcol" until it goes over the end of
@@ -1966,7 +1980,7 @@ scrollup(
19661980# endif
19671981 curwin -> w_skipcol = 0 ;
19681982 if (todo > 1 && do_sms )
1969- size = linetabsize (curwin , curwin -> w_topline );
1983+ size = linetabsize_eol (curwin , curwin -> w_topline );
19701984 }
19711985 }
19721986 }
@@ -2043,7 +2057,7 @@ adjust_skipcol(void)
20432057 }
20442058
20452059 validate_virtcol ();
2046- overlap = sms_marker_overlap (curwin , -1 );
2060+ overlap = sms_marker_overlap (curwin , curwin -> w_width - width2 );
20472061 while (curwin -> w_skipcol > 0
20482062 && curwin -> w_virtcol < curwin -> w_skipcol + overlap + scrolloff_cols )
20492063 {
@@ -2066,8 +2080,7 @@ adjust_skipcol(void)
20662080 // Avoid adjusting for 'scrolloff' beyond the text line height.
20672081 if (scrolloff_cols > 0 )
20682082 {
2069- int size = win_linetabsize (curwin , curwin -> w_topline ,
2070- ml_get (curwin -> w_topline ), (colnr_T )MAXCOL );
2083+ int size = linetabsize_eol (curwin , curwin -> w_topline );
20712084 size = width1 + width2 * ((size - width1 + width2 - 1 ) / width2 );
20722085 while (col > size )
20732086 col -= width2 ;
0 commit comments