mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 9.0.0640: cannot scroll by screen line if a line wraps
Problem: Cannot scroll by screen line if a line wraps. Solution: Add the 'smoothscroll' option. Only works for CTRL-E and CTRL-Y so far.
This commit is contained in:
144
src/move.c
144
src/move.c
@@ -35,6 +35,32 @@ typedef struct
|
||||
static void topline_back(lineoff_T *lp);
|
||||
static void botline_forw(lineoff_T *lp);
|
||||
|
||||
/*
|
||||
* Reduce "n" for the screen lines skipped with "wp->w_skipcol".
|
||||
*/
|
||||
static int
|
||||
adjust_plines_for_skipcol(win_T *wp, int n)
|
||||
{
|
||||
if (wp->w_skipcol == 0)
|
||||
return n;
|
||||
|
||||
int off = 0;
|
||||
int width = wp->w_width - win_col_off(wp);
|
||||
if (wp->w_skipcol >= width)
|
||||
{
|
||||
++off;
|
||||
int skip = wp->w_skipcol - width;
|
||||
width -= win_col_off2(wp);
|
||||
while (skip >= width)
|
||||
{
|
||||
++off;
|
||||
skip -= width;
|
||||
}
|
||||
}
|
||||
wp->w_valid &= ~VALID_WROW;
|
||||
return n - off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute wp->w_botline for the current wp->w_topline. Can be called after
|
||||
* wp->w_topline changed.
|
||||
@@ -78,12 +104,16 @@ comp_botline(win_T *wp)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef FEAT_DIFF
|
||||
if (lnum == wp->w_topline)
|
||||
n = plines_win_nofill(wp, lnum, TRUE) + wp->w_topfill;
|
||||
else
|
||||
#endif
|
||||
n = plines_win(wp, lnum, TRUE);
|
||||
if (lnum == wp->w_topline)
|
||||
n = adjust_plines_for_skipcol(wp, n);
|
||||
}
|
||||
if (
|
||||
#ifdef FEAT_FOLDING
|
||||
lnum <= wp->w_cursor.lnum && last >= wp->w_cursor.lnum
|
||||
@@ -778,13 +808,18 @@ curs_rows(win_T *wp)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int n;
|
||||
#ifdef FEAT_DIFF
|
||||
if (lnum == wp->w_topline)
|
||||
wp->w_cline_row += plines_win_nofill(wp, lnum++, TRUE)
|
||||
+ wp->w_topfill;
|
||||
n = plines_win_nofill(wp, lnum, TRUE) + wp->w_topfill;
|
||||
else
|
||||
#endif
|
||||
wp->w_cline_row += plines_win(wp, lnum++, TRUE);
|
||||
n = plines_win(wp, lnum, TRUE);
|
||||
if (lnum++ == wp->w_topline)
|
||||
n = adjust_plines_for_skipcol(wp, n);
|
||||
wp->w_cline_row += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1237,7 +1272,7 @@ curs_columns(
|
||||
else if (extra < 0)
|
||||
win_del_lines(curwin, 0, -extra, FALSE, FALSE, 0);
|
||||
}
|
||||
else
|
||||
else if (!curwin->w_p_sms)
|
||||
curwin->w_skipcol = 0;
|
||||
if (prev_skipcol != curwin->w_skipcol)
|
||||
redraw_later(UPD_NOT_VALID);
|
||||
@@ -1422,6 +1457,14 @@ scrolldown(
|
||||
long done = 0; // total # of physical lines done
|
||||
int wrow;
|
||||
int moved = FALSE;
|
||||
int width1 = 0;
|
||||
int width2 = 0;
|
||||
|
||||
if (curwin->w_p_wrap && curwin->w_p_sms)
|
||||
{
|
||||
width1 = curwin->w_width - curwin_col_off();
|
||||
width2 = width1 - curwin_col_off2();
|
||||
}
|
||||
|
||||
#ifdef FEAT_FOLDING
|
||||
linenr_T first;
|
||||
@@ -1442,25 +1485,57 @@ scrolldown(
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (curwin->w_topline == 1)
|
||||
if (curwin->w_topline == 1 && curwin->w_skipcol < width1)
|
||||
break;
|
||||
--curwin->w_topline;
|
||||
#ifdef FEAT_DIFF
|
||||
curwin->w_topfill = 0;
|
||||
#endif
|
||||
#ifdef FEAT_FOLDING
|
||||
// A sequence of folded lines only counts for one logical line
|
||||
if (hasFolding(curwin->w_topline, &first, NULL))
|
||||
if (curwin->w_p_wrap && curwin->w_p_sms
|
||||
&& curwin->w_skipcol >= width1)
|
||||
{
|
||||
if (curwin->w_skipcol >= width1 + width2)
|
||||
curwin->w_skipcol -= width2;
|
||||
else
|
||||
curwin->w_skipcol -= width1;
|
||||
redraw_later(UPD_NOT_VALID);
|
||||
++done;
|
||||
if (!byfold)
|
||||
line_count -= curwin->w_topline - first - 1;
|
||||
curwin->w_botline -= curwin->w_topline - first;
|
||||
curwin->w_topline = first;
|
||||
}
|
||||
else
|
||||
{
|
||||
--curwin->w_topline;
|
||||
curwin->w_skipcol = 0;
|
||||
#ifdef FEAT_DIFF
|
||||
curwin->w_topfill = 0;
|
||||
#endif
|
||||
done += PLINES_NOFILL(curwin->w_topline);
|
||||
#ifdef FEAT_FOLDING
|
||||
// A sequence of folded lines only counts for one logical line
|
||||
if (hasFolding(curwin->w_topline, &first, NULL))
|
||||
{
|
||||
++done;
|
||||
if (!byfold)
|
||||
line_count -= curwin->w_topline - first - 1;
|
||||
curwin->w_botline -= curwin->w_topline - first;
|
||||
curwin->w_topline = first;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (curwin->w_p_wrap && curwin->w_p_sms)
|
||||
{
|
||||
int size = win_linetabsize(curwin, curwin->w_topline,
|
||||
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
|
||||
if (size > width1)
|
||||
{
|
||||
curwin->w_skipcol = width1;
|
||||
size -= width1;
|
||||
redraw_later(UPD_NOT_VALID);
|
||||
}
|
||||
while (size > width2)
|
||||
{
|
||||
curwin->w_skipcol += width2;
|
||||
size -= width2;
|
||||
}
|
||||
++done;
|
||||
}
|
||||
else
|
||||
done += PLINES_NOFILL(curwin->w_topline);
|
||||
}
|
||||
}
|
||||
--curwin->w_botline; // approximate w_botline
|
||||
invalidate_botline();
|
||||
@@ -1565,6 +1640,41 @@ scrollup(
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (curwin->w_p_wrap && curwin->w_p_sms)
|
||||
{
|
||||
int off1 = curwin_col_off();
|
||||
int off2 = off1 + curwin_col_off2();
|
||||
int add;
|
||||
int size = win_linetabsize(curwin, curwin->w_topline,
|
||||
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
|
||||
linenr_T prev_topline = curwin->w_topline;
|
||||
|
||||
// 'smoothscroll': increase "w_skipcol" until it goes over the end of
|
||||
// the line, then advance to the next line.
|
||||
for (int todo = line_count; todo > 0; --todo)
|
||||
{
|
||||
add = curwin->w_width - (curwin->w_skipcol > 0 ? off2 : off1);
|
||||
curwin->w_skipcol += add;
|
||||
if (curwin->w_skipcol >= size)
|
||||
{
|
||||
if (curwin->w_topline == curbuf->b_ml.ml_line_count)
|
||||
{
|
||||
curwin->w_skipcol -= add;
|
||||
break;
|
||||
}
|
||||
++curwin->w_topline;
|
||||
++curwin->w_botline; // approximate w_botline
|
||||
curwin->w_skipcol = 0;
|
||||
if (todo > 1)
|
||||
size = win_linetabsize(curwin, curwin->w_topline,
|
||||
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
|
||||
}
|
||||
}
|
||||
if (curwin->w_topline == prev_topline)
|
||||
// need to redraw even though w_topline didn't change
|
||||
redraw_later(UPD_NOT_VALID);
|
||||
}
|
||||
else
|
||||
{
|
||||
curwin->w_topline += line_count;
|
||||
curwin->w_botline += line_count; // approximate w_botline
|
||||
|
Reference in New Issue
Block a user