diff options
| author | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-05-12 02:25:17 +0200 |
|---|---|---|
| committer | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-05-15 20:46:01 +0200 |
| commit | da51dc9cf202772f60bd2da975dbef257bd9237c (patch) | |
| tree | 5c16b93238a153f55634e9323077f30c8133970c /src/move.c | |
| parent | ffe61e5ba1721340ca51d56bae3ddaca415fb5bc (diff) | |
| download | rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.gz rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.bz2 rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.zip | |
Introduce nvim namespace: Move files.
Move files from src/ to src/nvim/.
- src/nvim/ becomes the new root dir for nvim executable sources.
- src/libnvim/ is planned to become root dir of the neovim library.
Diffstat (limited to 'src/move.c')
| -rw-r--r-- | src/move.c | 2242 |
1 files changed, 0 insertions, 2242 deletions
diff --git a/src/move.c b/src/move.c deleted file mode 100644 index f234d968a6..0000000000 --- a/src/move.c +++ /dev/null @@ -1,2242 +0,0 @@ -/* - * VIM - Vi IMproved by Bram Moolenaar - * - * Do ":help uganda" in Vim to read copying and usage conditions. - * Do ":help credits" in Vim to see a list of people who contributed. - * See README.txt for an overview of the Vim source code. - */ -/* - * move.c: Functions for moving the cursor and scrolling text. - * - * There are two ways to move the cursor: - * 1. Move the cursor directly, the text is scrolled to keep the cursor in the - * window. - * 2. Scroll the text, the cursor is moved into the text visible in the - * window. - * The 'scrolloff' option makes this a bit complicated. - */ - -#include "vim.h" -#include "move.h" -#include "charset.h" -#include "diff.h" -#include "edit.h" -#include "fold.h" -#include "mbyte.h" -#include "memline.h" -#include "misc1.h" -#include "misc2.h" -#include "popupmnu.h" -#include "screen.h" - -static void comp_botline(win_T *wp); -static void redraw_for_cursorline(win_T *wp); -static int scrolljump_value(void); -static int check_top_offset(void); -static void curs_rows(win_T *wp, int do_botline); -static void validate_botline_win(win_T *wp); -static void validate_cheight(void); - -typedef struct { - linenr_T lnum; /* line number */ - int fill; /* filler lines */ - int height; /* height of added line */ -} lineoff_T; - -static void topline_back(lineoff_T *lp); -static void botline_forw(lineoff_T *lp); -static void botline_topline(lineoff_T *lp); -static void topline_botline(lineoff_T *lp); -static void max_topfill(void); - -/* - * Compute wp->w_botline for the current wp->w_topline. Can be called after - * wp->w_topline changed. - */ -static void comp_botline(win_T *wp) -{ - int n; - linenr_T lnum; - int done; - linenr_T last; - int folded; - - /* - * If w_cline_row is valid, start there. - * Otherwise have to start at w_topline. - */ - check_cursor_moved(wp); - if (wp->w_valid & VALID_CROW) { - lnum = wp->w_cursor.lnum; - done = wp->w_cline_row; - } else { - lnum = wp->w_topline; - done = 0; - } - - for (; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum) { - last = lnum; - folded = FALSE; - if (hasFoldingWin(wp, lnum, NULL, &last, TRUE, NULL)) { - n = 1; - folded = TRUE; - } else if (lnum == wp->w_topline) - n = plines_win_nofill(wp, lnum, TRUE) + wp->w_topfill; - else - n = plines_win(wp, lnum, TRUE); - if ( - lnum <= wp->w_cursor.lnum && last >= wp->w_cursor.lnum - ) { - wp->w_cline_row = done; - wp->w_cline_height = n; - wp->w_cline_folded = folded; - redraw_for_cursorline(wp); - wp->w_valid |= (VALID_CROW|VALID_CHEIGHT); - } - if (done + n > wp->w_height) - break; - done += n; - lnum = last; - } - - /* wp->w_botline is the line that is just below the window */ - wp->w_botline = lnum; - wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; - - set_empty_rows(wp, done); -} - -/* -* Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is -* set. -*/ -static void redraw_for_cursorline(win_T *wp) -{ - if ((wp->w_p_rnu || wp->w_p_cul) - && (wp->w_valid & VALID_CROW) == 0 - && !pum_visible()) { - redraw_win_later(wp, SOME_VALID); - } -} - -/* - * Update curwin->w_topline and redraw if necessary. - * Used to update the screen before printing a message. - */ -void update_topline_redraw(void) -{ - update_topline(); - if (must_redraw) - update_screen(0); -} - -/* - * Update curwin->w_topline to move the cursor onto the screen. - */ -void update_topline(void) -{ - long line_count; - int halfheight; - int n; - linenr_T old_topline; - int old_topfill; - linenr_T lnum; - int check_topline = FALSE; - int check_botline = FALSE; - int save_so = p_so; - - if (!screen_valid(TRUE)) - return; - - check_cursor_moved(curwin); - if (curwin->w_valid & VALID_TOPLINE) - return; - - /* When dragging with the mouse, don't scroll that quickly */ - if (mouse_dragging > 0) - p_so = mouse_dragging - 1; - - old_topline = curwin->w_topline; - old_topfill = curwin->w_topfill; - - /* - * If the buffer is empty, always set topline to 1. - */ - if (bufempty()) { /* special case - file is empty */ - if (curwin->w_topline != 1) - redraw_later(NOT_VALID); - curwin->w_topline = 1; - curwin->w_botline = 2; - curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; - curwin->w_scbind_pos = 1; - } - /* - * If the cursor is above or near the top of the window, scroll the window - * to show the line the cursor is in, with 'scrolloff' context. - */ - else { - if (curwin->w_topline > 1) { - /* If the cursor is above topline, scrolling is always needed. - * If the cursor is far below topline and there is no folding, - * scrolling down is never needed. */ - if (curwin->w_cursor.lnum < curwin->w_topline) - check_topline = TRUE; - else if (check_top_offset()) - check_topline = TRUE; - } - /* Check if there are more filler lines than allowed. */ - if (!check_topline && curwin->w_topfill > diff_check_fill(curwin, - curwin->w_topline)) - check_topline = TRUE; - - if (check_topline) { - halfheight = curwin->w_height / 2 - 1; - if (halfheight < 2) - halfheight = 2; - - if (hasAnyFolding(curwin)) { - /* Count the number of logical lines between the cursor and - * topline + p_so (approximation of how much will be - * scrolled). */ - n = 0; - for (lnum = curwin->w_cursor.lnum; - lnum < curwin->w_topline + p_so; ++lnum) { - ++n; - /* stop at end of file or when we know we are far off */ - if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight) - break; - (void)hasFolding(lnum, NULL, &lnum); - } - } else - n = curwin->w_topline + p_so - curwin->w_cursor.lnum; - - /* If we weren't very close to begin with, we scroll to put the - * cursor in the middle of the window. Otherwise put the cursor - * near the top of the window. */ - if (n >= halfheight) - scroll_cursor_halfway(FALSE); - else { - scroll_cursor_top(scrolljump_value(), FALSE); - check_botline = TRUE; - } - } else { - /* Make sure topline is the first line of a fold. */ - (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); - check_botline = TRUE; - } - } - - /* - * If the cursor is below the bottom of the window, scroll the window - * to put the cursor on the window. - * When w_botline is invalid, recompute it first, to avoid a redraw later. - * If w_botline was approximated, we might need a redraw later in a few - * cases, but we don't want to spend (a lot of) time recomputing w_botline - * for every small change. - */ - if (check_botline) { - if (!(curwin->w_valid & VALID_BOTLINE_AP)) - validate_botline(); - - if (curwin->w_botline <= curbuf->b_ml.ml_line_count) { - if (curwin->w_cursor.lnum < curwin->w_botline) { - if (((long)curwin->w_cursor.lnum - >= (long)curwin->w_botline - p_so - || hasAnyFolding(curwin) - )) { - lineoff_T loff; - - /* Cursor is (a few lines) above botline, check if there are - * 'scrolloff' window lines below the cursor. If not, need to - * scroll. */ - n = curwin->w_empty_rows; - loff.lnum = curwin->w_cursor.lnum; - /* In a fold go to its last line. */ - (void)hasFolding(loff.lnum, NULL, &loff.lnum); - loff.fill = 0; - n += curwin->w_filler_rows; - loff.height = 0; - while (loff.lnum < curwin->w_botline - && (loff.lnum + 1 < curwin->w_botline || loff.fill == 0) - ) { - n += loff.height; - if (n >= p_so) - break; - botline_forw(&loff); - } - if (n >= p_so) - /* sufficient context, no need to scroll */ - check_botline = FALSE; - } else - /* sufficient context, no need to scroll */ - check_botline = FALSE; - } - if (check_botline) { - if (hasAnyFolding(curwin)) { - /* Count the number of logical lines between the cursor and - * botline - p_so (approximation of how much will be - * scrolled). */ - line_count = 0; - for (lnum = curwin->w_cursor.lnum; - lnum >= curwin->w_botline - p_so; --lnum) { - ++line_count; - /* stop at end of file or when we know we are far off */ - if (lnum <= 0 || line_count > curwin->w_height + 1) - break; - (void)hasFolding(lnum, &lnum, NULL); - } - } else - line_count = curwin->w_cursor.lnum - curwin->w_botline - + 1 + p_so; - if (line_count <= curwin->w_height + 1) - scroll_cursor_bot(scrolljump_value(), FALSE); - else - scroll_cursor_halfway(FALSE); - } - } - } - curwin->w_valid |= VALID_TOPLINE; - - /* - * Need to redraw when topline changed. - */ - if (curwin->w_topline != old_topline - || curwin->w_topfill != old_topfill - ) { - dollar_vcol = -1; - if (curwin->w_skipcol != 0) { - curwin->w_skipcol = 0; - redraw_later(NOT_VALID); - } else - redraw_later(VALID); - /* May need to set w_skipcol when cursor in w_topline. */ - if (curwin->w_cursor.lnum == curwin->w_topline) - validate_cursor(); - } - - p_so = save_so; -} - -/* - * Return the scrolljump value to use for the current window. - * When 'scrolljump' is positive use it as-is. - * When 'scrolljump' is negative use it as a percentage of the window height. - */ -static int scrolljump_value(void) -{ - if (p_sj >= 0) - return (int)p_sj; - return (curwin->w_height * -p_sj) / 100; -} - -/* - * Return TRUE when there are not 'scrolloff' lines above the cursor for the - * current window. - */ -static int check_top_offset(void) -{ - lineoff_T loff; - int n; - - if (curwin->w_cursor.lnum < curwin->w_topline + p_so - || hasAnyFolding(curwin) - ) { - loff.lnum = curwin->w_cursor.lnum; - loff.fill = 0; - n = curwin->w_topfill; /* always have this context */ - /* Count the visible screen lines above the cursor line. */ - while (n < p_so) { - topline_back(&loff); - /* Stop when included a line above the window. */ - if (loff.lnum < curwin->w_topline - || (loff.lnum == curwin->w_topline && loff.fill > 0) - ) - break; - n += loff.height; - } - if (n < p_so) - return TRUE; - } - return FALSE; -} - -void update_curswant(void) -{ - if (curwin->w_set_curswant) { - validate_virtcol(); - curwin->w_curswant = curwin->w_virtcol; - curwin->w_set_curswant = FALSE; - } -} - -/* - * Check if the cursor has moved. Set the w_valid flag accordingly. - */ -void check_cursor_moved(win_T *wp) -{ - if (wp->w_cursor.lnum != wp->w_valid_cursor.lnum) { - wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL - |VALID_CHEIGHT|VALID_CROW|VALID_TOPLINE); - wp->w_valid_cursor = wp->w_cursor; - wp->w_valid_leftcol = wp->w_leftcol; - } else if (wp->w_cursor.col != wp->w_valid_cursor.col - || wp->w_leftcol != wp->w_valid_leftcol - || wp->w_cursor.coladd != wp->w_valid_cursor.coladd - ) { - wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL); - wp->w_valid_cursor.col = wp->w_cursor.col; - wp->w_valid_leftcol = wp->w_leftcol; - wp->w_valid_cursor.coladd = wp->w_cursor.coladd; - } -} - -/* - * Call this function when some window settings have changed, which require - * the cursor position, botline and topline to be recomputed and the window to - * be redrawn. E.g, when changing the 'wrap' option or folding. - */ -void changed_window_setting(void) -{ - changed_window_setting_win(curwin); -} - -void changed_window_setting_win(win_T *wp) -{ - wp->w_lines_valid = 0; - changed_line_abv_curs_win(wp); - wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP|VALID_TOPLINE); - redraw_win_later(wp, NOT_VALID); -} - -/* - * Set wp->w_topline to a certain number. - */ -void set_topline(win_T *wp, linenr_T lnum) -{ - /* go to first of folded lines */ - (void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL); - /* Approximate the value of w_botline */ - wp->w_botline += lnum - wp->w_topline; - wp->w_topline = lnum; - wp->w_topline_was_set = TRUE; - wp->w_topfill = 0; - wp->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_TOPLINE); - /* Don't set VALID_TOPLINE here, 'scrolloff' needs to be checked. */ - redraw_later(VALID); -} - -/* - * Call this function when the length of the cursor line (in screen - * characters) has changed, and the change is before the cursor. - * Need to take care of w_botline separately! - */ -void changed_cline_bef_curs(void) -{ - curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL - |VALID_CHEIGHT|VALID_TOPLINE); -} - -void changed_cline_bef_curs_win(win_T *wp) -{ - wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL - |VALID_CHEIGHT|VALID_TOPLINE); -} - -/* - * Call this function when the length of a line (in screen characters) above - * the cursor have changed. - * Need to take care of w_botline separately! - */ -void changed_line_abv_curs(void) -{ - curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW - |VALID_CHEIGHT|VALID_TOPLINE); -} - -void changed_line_abv_curs_win(win_T *wp) -{ - wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW - |VALID_CHEIGHT|VALID_TOPLINE); -} - -/* - * Make sure the value of curwin->w_botline is valid. - */ -void validate_botline(void) -{ - if (!(curwin->w_valid & VALID_BOTLINE)) - comp_botline(curwin); -} - -/* - * Make sure the value of wp->w_botline is valid. - */ -static void validate_botline_win(win_T *wp) -{ - if (!(wp->w_valid & VALID_BOTLINE)) - comp_botline(wp); -} - -/* - * Mark curwin->w_botline as invalid (because of some change in the buffer). - */ -void invalidate_botline(void) -{ - curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP); -} - -void invalidate_botline_win(win_T *wp) -{ - wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP); -} - -void approximate_botline_win(win_T *wp) -{ - wp->w_valid &= ~VALID_BOTLINE; -} - -/* - * Return TRUE if curwin->w_wrow and curwin->w_wcol are valid. - */ -int cursor_valid(void) -{ - check_cursor_moved(curwin); - return (curwin->w_valid & (VALID_WROW|VALID_WCOL)) == - (VALID_WROW|VALID_WCOL); -} - -/* - * Validate cursor position. Makes sure w_wrow and w_wcol are valid. - * w_topline must be valid, you may need to call update_topline() first! - */ -void validate_cursor(void) -{ - check_cursor_moved(curwin); - if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW)) - curs_columns(TRUE); -} - -/* - * Compute wp->w_cline_row and wp->w_cline_height, based on the current value - * of wp->w_topline. - * - * Returns OK when cursor is in the window, FAIL when it isn't. - */ -static void -curs_rows ( - win_T *wp, - int do_botline /* also compute w_botline */ -) -{ - linenr_T lnum; - int i; - int all_invalid; - int valid; - long fold_count; - - /* Check if wp->w_lines[].wl_size is invalid */ - all_invalid = (!redrawing() - || wp->w_lines_valid == 0 - || wp->w_lines[0].wl_lnum > wp->w_topline); - i = 0; - wp->w_cline_row = 0; - for (lnum = wp->w_topline; lnum < wp->w_cursor.lnum; ++i) { - valid = FALSE; - if (!all_invalid && i < wp->w_lines_valid) { - if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid) - continue; /* skip changed or deleted lines */ - if (wp->w_lines[i].wl_lnum == lnum) { - /* Check for newly inserted lines below this row, in which - * case we need to check for folded lines. */ - if (!wp->w_buffer->b_mod_set - || wp->w_lines[i].wl_lastlnum < wp->w_cursor.lnum - || wp->w_buffer->b_mod_top - > wp->w_lines[i].wl_lastlnum + 1) - valid = TRUE; - } else if (wp->w_lines[i].wl_lnum > lnum) - --i; /* hold at inserted lines */ - } - if (valid - && (lnum != wp->w_topline || !wp->w_p_diff) - ) { - lnum = wp->w_lines[i].wl_lastlnum + 1; - /* Cursor inside folded lines, don't count this row */ - if (lnum > wp->w_cursor.lnum) - break; - wp->w_cline_row += wp->w_lines[i].wl_size; - } else { - fold_count = foldedCount(wp, lnum, NULL); - if (fold_count) { - lnum += fold_count; - if (lnum > wp->w_cursor.lnum) - break; - ++wp->w_cline_row; - } else if (lnum == wp->w_topline) - wp->w_cline_row += plines_win_nofill(wp, lnum++, TRUE) - + wp->w_topfill; - else - wp->w_cline_row += plines_win(wp, lnum++, TRUE); - } - } - - check_cursor_moved(wp); - if (!(wp->w_valid & VALID_CHEIGHT)) { - if (all_invalid - || i == wp->w_lines_valid - || (i < wp->w_lines_valid - && (!wp->w_lines[i].wl_valid - || wp->w_lines[i].wl_lnum != wp->w_cursor.lnum))) { - if (wp->w_cursor.lnum == wp->w_topline) - wp->w_cline_height = plines_win_nofill(wp, wp->w_cursor.lnum, - TRUE) + wp->w_topfill; - else - wp->w_cline_height = plines_win(wp, wp->w_cursor.lnum, TRUE); - wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum, - NULL, NULL, TRUE, NULL); - } else if (i > wp->w_lines_valid) { - /* a line that is too long to fit on the last screen line */ - wp->w_cline_height = 0; - wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum, - NULL, NULL, TRUE, NULL); - } else { - wp->w_cline_height = wp->w_lines[i].wl_size; - wp->w_cline_folded = wp->w_lines[i].wl_folded; - } - } - - redraw_for_cursorline(curwin); - wp->w_valid |= VALID_CROW|VALID_CHEIGHT; - - /* validate botline too, if update_screen doesn't do it */ - if (do_botline && all_invalid) - validate_botline_win(wp); -} - -/* - * Validate curwin->w_virtcol only. - */ -void validate_virtcol(void) -{ - validate_virtcol_win(curwin); -} - -/* - * Validate wp->w_virtcol only. - */ -void validate_virtcol_win(win_T *wp) -{ - check_cursor_moved(wp); - if (!(wp->w_valid & VALID_VIRTCOL)) { - getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL); - wp->w_valid |= VALID_VIRTCOL; - if (wp->w_p_cuc - && !pum_visible() - ) - redraw_win_later(wp, SOME_VALID); - } -} - -/* - * Validate curwin->w_cline_height only. - */ -static void validate_cheight(void) -{ - check_cursor_moved(curwin); - if (!(curwin->w_valid & VALID_CHEIGHT)) { - if (curwin->w_cursor.lnum == curwin->w_topline) - curwin->w_cline_height = plines_nofill(curwin->w_cursor.lnum) - + curwin->w_topfill; - else - curwin->w_cline_height = plines(curwin->w_cursor.lnum); - curwin->w_cline_folded = hasFolding(curwin->w_cursor.lnum, NULL, NULL); - curwin->w_valid |= VALID_CHEIGHT; - } -} - -/* - * Validate w_wcol and w_virtcol only. - */ -void validate_cursor_col(void) -{ - colnr_T off; - colnr_T col; - int width; - - validate_virtcol(); - if (!(curwin->w_valid & VALID_WCOL)) { - col = curwin->w_virtcol; - off = curwin_col_off(); - col += off; - width = W_WIDTH(curwin) - off + curwin_col_off2(); - - /* long line wrapping, adjust curwin->w_wrow */ - if (curwin->w_p_wrap - && col >= (colnr_T)W_WIDTH(curwin) - && width > 0) - /* use same formula as what is used in curs_columns() */ - col -= ((col - W_WIDTH(curwin)) / width + 1) * width; - if (col > (int)curwin->w_leftcol) - col -= curwin->w_leftcol; - else - col = 0; - curwin->w_wcol = col; - - curwin->w_valid |= VALID_WCOL; - } -} - -/* - * Compute offset of a window, occupied by absolute or relative line number, - * fold column and sign column (these don't move when scrolling horizontally). - */ -int win_col_off(win_T *wp) -{ - return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0) - + (cmdwin_type == 0 || wp != curwin ? 0 : 1) - + wp->w_p_fdc - + (wp->w_buffer->b_signlist != NULL ? 2 : 0) - ; -} - -int curwin_col_off(void) -{ - return win_col_off(curwin); -} - -/* - * Return the difference in column offset for the second screen line of a - * wrapped line. It's 8 if 'number' or 'relativenumber' is on and 'n' is in - * 'cpoptions'. - */ -int win_col_off2(win_T *wp) -{ - if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL) - return number_width(wp) + 1; - return 0; -} - -int curwin_col_off2(void) -{ - return win_col_off2(curwin); -} - -/* - * compute curwin->w_wcol and curwin->w_virtcol. - * Also updates curwin->w_wrow and curwin->w_cline_row. - * Also updates curwin->w_leftcol. - */ -void -curs_columns ( - int may_scroll /* when TRUE, may scroll horizontally */ -) -{ - int diff; - int extra; /* offset for first screen line */ - int off_left, off_right; - int n; - int p_lines; - int width = 0; - int textwidth; - int new_leftcol; - colnr_T startcol; - colnr_T endcol; - colnr_T prev_skipcol; - - /* - * First make sure that w_topline is valid (after moving the cursor). - */ - update_topline(); - - /* - * Next make sure that w_cline_row is valid. - */ - if (!(curwin->w_valid & VALID_CROW)) - curs_rows(curwin, FALSE); - - /* - * Compute the number of virtual columns. - */ - if (curwin->w_cline_folded) - /* In a folded line the cursor is always in the first column */ - startcol = curwin->w_virtcol = endcol = curwin->w_leftcol; - else - getvvcol(curwin, &curwin->w_cursor, - &startcol, &(curwin->w_virtcol), &endcol); - - /* remove '$' from change command when cursor moves onto it */ - if (startcol > dollar_vcol) - dollar_vcol = -1; - - extra = curwin_col_off(); - curwin->w_wcol = curwin->w_virtcol + extra; - endcol += extra; - - /* - * Now compute w_wrow, counting screen lines from w_cline_row. - */ - curwin->w_wrow = curwin->w_cline_row; - - textwidth = W_WIDTH(curwin) - extra; - if (textwidth <= 0) { - /* No room for text, put cursor in last char of window. */ - curwin->w_wcol = W_WIDTH(curwin) - 1; - curwin->w_wrow = curwin->w_height - 1; - } else if (curwin->w_p_wrap - && curwin->w_width != 0 - ) { - width = textwidth + curwin_col_off2(); - - /* long line wrapping, adjust curwin->w_wrow */ - if (curwin->w_wcol >= W_WIDTH(curwin)) { - /* this same formula is used in validate_cursor_col() */ - n = (curwin->w_wcol - W_WIDTH(curwin)) / width + 1; - curwin->w_wcol -= n * width; - curwin->w_wrow += n; - - /* When cursor wraps to first char of next line in Insert - * mode, the 'showbreak' string isn't shown, backup to first - * column */ - if (*p_sbr && *ml_get_cursor() == NUL - && curwin->w_wcol == (int)vim_strsize(p_sbr)) - curwin->w_wcol = 0; - } - } - /* No line wrapping: compute curwin->w_leftcol if scrolling is on and line - * is not folded. - * If scrolling is off, curwin->w_leftcol is assumed to be 0 */ - else if (may_scroll - && !curwin->w_cline_folded - ) { - /* - * If Cursor is left of the screen, scroll rightwards. - * If Cursor is right of the screen, scroll leftwards - * If we get closer to the edge than 'sidescrolloff', scroll a little - * extra - */ - off_left = (int)startcol - (int)curwin->w_leftcol - p_siso; - off_right = (int)endcol - (int)(curwin->w_leftcol + W_WIDTH(curwin) - - p_siso) + 1; - if (off_left < 0 || off_right > 0) { - if (off_left < 0) - diff = -off_left; - else - diff = off_right; - - /* When far off or not enough room on either side, put cursor in - * middle of window. */ - if (p_ss == 0 || diff >= textwidth / 2 || off_right >= off_left) - new_leftcol = curwin->w_wcol - extra - textwidth / 2; - else { - if (diff < p_ss) - diff = p_ss; - if (off_left < 0) - new_leftcol = curwin->w_leftcol - diff; - else - new_leftcol = curwin->w_leftcol + diff; - } - if (new_leftcol < 0) - new_leftcol = 0; - if (new_leftcol != (int)curwin->w_leftcol) { - curwin->w_leftcol = new_leftcol; - /* screen has to be redrawn with new curwin->w_leftcol */ - redraw_later(NOT_VALID); - } - } - curwin->w_wcol -= curwin->w_leftcol; - } else if (curwin->w_wcol > (int)curwin->w_leftcol) - curwin->w_wcol -= curwin->w_leftcol; - else - curwin->w_wcol = 0; - - /* Skip over filler lines. At the top use w_topfill, there - * may be some filler lines above the window. */ - if (curwin->w_cursor.lnum == curwin->w_topline) - curwin->w_wrow += curwin->w_topfill; - else - curwin->w_wrow += diff_check_fill(curwin, curwin->w_cursor.lnum); - - prev_skipcol = curwin->w_skipcol; - - p_lines = 0; - if ((curwin->w_wrow >= curwin->w_height - || ((prev_skipcol > 0 - || curwin->w_wrow + p_so >= curwin->w_height) - && (p_lines = - plines_win_nofill - (curwin, curwin->w_cursor.lnum, FALSE)) - - 1 >= curwin->w_height)) - && curwin->w_height != 0 - && curwin->w_cursor.lnum == curwin->w_topline - && width > 0 - && curwin->w_width != 0 - ) { - /* Cursor past end of screen. Happens with a single line that does - * not fit on screen. Find a skipcol to show the text around the - * cursor. Avoid scrolling all the time. compute value of "extra": - * 1: Less than "p_so" lines above - * 2: Less than "p_so" lines below - * 3: both of them */ - extra = 0; - if (curwin->w_skipcol + p_so * width > curwin->w_virtcol) - extra = 1; - /* Compute last display line of the buffer line that we want at the - * bottom of the window. */ - if (p_lines == 0) - p_lines = plines_win(curwin, curwin->w_cursor.lnum, FALSE); - --p_lines; - if (p_lines > curwin->w_wrow + p_so) - n = curwin->w_wrow + p_so; - else - n = p_lines; - if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width) - extra += 2; - - if (extra == 3 || p_lines < p_so * 2) { - /* not enough room for 'scrolloff', put cursor in the middle */ - n = curwin->w_virtcol / width; - if (n > curwin->w_height / 2) - n -= curwin->w_height / 2; - else - n = 0; - /* don't skip more than necessary */ - if (n > p_lines - curwin->w_height + 1) - n = p_lines - curwin->w_height + 1; - curwin->w_skipcol = n * width; - } else if (extra == 1) { - /* less then 'scrolloff' lines above, decrease skipcol */ - extra = (curwin->w_skipcol + p_so * width - curwin->w_virtcol - + width - 1) / width; - if (extra > 0) { - if ((colnr_T)(extra * width) > curwin->w_skipcol) - extra = curwin->w_skipcol / width; - curwin->w_skipcol -= extra * width; - } - } else if (extra == 2) { - /* less then 'scrolloff' lines below, increase skipcol */ - endcol = (n - curwin->w_height + 1) * width; - while (endcol > curwin->w_virtcol) - endcol -= width; - if (endcol > curwin->w_skipcol) - curwin->w_skipcol = endcol; - } - - curwin->w_wrow -= curwin->w_skipcol / width; - if (curwin->w_wrow >= curwin->w_height) { - /* small window, make sure cursor is in it */ - extra = curwin->w_wrow - curwin->w_height + 1; - curwin->w_skipcol += extra * width; - curwin->w_wrow -= extra; - } - - extra = ((int)prev_skipcol - (int)curwin->w_skipcol) / width; - if (extra > 0) - win_ins_lines(curwin, 0, extra, FALSE, FALSE); - else if (extra < 0) - win_del_lines(curwin, 0, -extra, FALSE, FALSE); - } else - curwin->w_skipcol = 0; - if (prev_skipcol != curwin->w_skipcol) - redraw_later(NOT_VALID); - - /* Redraw when w_virtcol changes and 'cursorcolumn' is set */ - if (curwin->w_p_cuc && (curwin->w_valid & VALID_VIRTCOL) == 0 - && !pum_visible()) { - redraw_later(SOME_VALID); - } - - curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL; -} - -/* - * Scroll the current window down by "line_count" logical lines. "CTRL-Y" - */ -void -scrolldown ( - long line_count, - int byfold /* TRUE: count a closed fold as one line */ -) -{ - long done = 0; /* total # of physical lines done */ - int wrow; - int moved = FALSE; - - linenr_T first; - - /* Make sure w_topline is at the first of a sequence of folded lines. */ - (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); - validate_cursor(); /* w_wrow needs to be valid */ - while (line_count-- > 0) { - if (curwin->w_topfill < diff_check(curwin, curwin->w_topline) - && curwin->w_topfill < curwin->w_height - 1) { - ++curwin->w_topfill; - ++done; - } else { - if (curwin->w_topline == 1) - break; - --curwin->w_topline; - curwin->w_topfill = 0; - /* 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 - done += plines_nofill(curwin->w_topline); - } - --curwin->w_botline; /* approximate w_botline */ - invalidate_botline(); - } - curwin->w_wrow += done; /* keep w_wrow updated */ - curwin->w_cline_row += done; /* keep w_cline_row updated */ - - if (curwin->w_cursor.lnum == curwin->w_topline) - curwin->w_cline_row = 0; - check_topfill(curwin, TRUE); - - /* - * Compute the row number of the last row of the cursor line - * and move the cursor onto the displayed part of the window. - */ - wrow = curwin->w_wrow; - if (curwin->w_p_wrap - && curwin->w_width != 0 - ) { - validate_virtcol(); - validate_cheight(); - wrow += curwin->w_cline_height - 1 - - curwin->w_virtcol / W_WIDTH(curwin); - } - while (wrow >= curwin->w_height && curwin->w_cursor.lnum > 1) { - if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) { - --wrow; - if (first == 1) - curwin->w_cursor.lnum = 1; - else - curwin->w_cursor.lnum = first - 1; - } else - wrow -= plines(curwin->w_cursor.lnum--); - curwin->w_valid &= - ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL); - moved = TRUE; - } - if (moved) { - /* Move cursor to first line of closed fold. */ - foldAdjustCursor(); - coladvance(curwin->w_curswant); - } -} - -/* - * Scroll the current window up by "line_count" logical lines. "CTRL-E" - */ -void -scrollup ( - long line_count, - int byfold /* TRUE: count a closed fold as one line */ -) -{ - linenr_T lnum; - - if ( - (byfold && hasAnyFolding(curwin)) - || - curwin->w_p_diff - ) { - /* count each sequence of folded lines as one logical line */ - lnum = curwin->w_topline; - while (line_count--) { - if (curwin->w_topfill > 0) - --curwin->w_topfill; - else { - if (byfold) - (void)hasFolding(lnum, NULL, &lnum); - if (lnum >= curbuf->b_ml.ml_line_count) - break; - ++lnum; - curwin->w_topfill = diff_check_fill(curwin, lnum); - } - } - /* approximate w_botline */ - curwin->w_botline += lnum - curwin->w_topline; - curwin->w_topline = lnum; - } else { - curwin->w_topline += |