summaryrefslogtreecommitdiffstats
path: root/src/move.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/move.c')
-rw-r--r--src/move.c144
1 files changed, 127 insertions, 17 deletions
diff --git a/src/move.c b/src/move.c
index 8a8af9a4e9..dca77f787c 100644
--- a/src/move.c
+++ b/src/move.c
@@ -36,6 +36,32 @@ 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
+#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
- done += PLINES_NOFILL(curwin->w_topline);
+ 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