diff options
Diffstat (limited to 'src/move.c')
-rw-r--r-- | src/move.c | 144 |
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 |