From 7c1cbb6cd437c6e0c3ccc05840cc931108b4a60a Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Tue, 27 Sep 2022 12:31:15 +0100 Subject: patch 9.0.0603: with 'nosplitscroll' folds are not handled correctly Problem: With 'nosplitscroll' folds are not handled correctly. Solution: Take care of closed folds when moving the cursor. (Luuk van Baal, closes #11234) --- src/edit.c | 180 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 100 insertions(+), 80 deletions(-) (limited to 'src/edit.c') diff --git a/src/edit.c b/src/edit.c index ec3e8ff6c4..2ac544a6be 100644 --- a/src/edit.c +++ b/src/edit.c @@ -2749,52 +2749,62 @@ oneleft(void) return OK; } - int -cursor_up( - long n, - int upd_topline) // When TRUE: update topline +/* + * Move the cursor up "n" lines in window "wp". + * Takes care of closed folds. + * Returns the new cursor line or zero for failure. + */ + linenr_T +cursor_up_inner(win_T *wp, long n) { - linenr_T lnum; + linenr_T lnum = wp->w_cursor.lnum; - if (n > 0) - { - lnum = curwin->w_cursor.lnum; - // This fails if the cursor is already in the first line or the count - // is larger than the line number and '-' is in 'cpoptions' - if (lnum <= 1 || (n >= lnum && vim_strchr(p_cpo, CPO_MINUS) != NULL)) - return FAIL; - if (n >= lnum) - lnum = 1; - else + // This fails if the cursor is already in the first line or the count is + // larger than the line number and '-' is in 'cpoptions' + if (lnum <= 1 || (n >= lnum && vim_strchr(p_cpo, CPO_MINUS) != NULL)) + return 0; + if (n >= lnum) + lnum = 1; + else #ifdef FEAT_FOLDING - if (hasAnyFolding(curwin)) - { - /* - * Count each sequence of folded lines as one logical line. - */ - // go to the start of the current fold - (void)hasFolding(lnum, &lnum, NULL); + if (hasAnyFolding(wp)) + { + /* + * Count each sequence of folded lines as one logical line. + */ + // go to the start of the current fold + (void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL); - while (n--) - { - // move up one line - --lnum; - if (lnum <= 1) - break; - // If we entered a fold, move to the beginning, unless in - // Insert mode or when 'foldopen' contains "all": it will open - // in a moment. - if (n > 0 || !((State & MODE_INSERT) || (fdo_flags & FDO_ALL))) - (void)hasFolding(lnum, &lnum, NULL); - } - if (lnum < 1) - lnum = 1; + while (n--) + { + // move up one line + --lnum; + if (lnum <= 1) + break; + // If we entered a fold, move to the beginning, unless in + // Insert mode or when 'foldopen' contains "all": it will open + // in a moment. + if (n > 0 || !((State & MODE_INSERT) || (fdo_flags & FDO_ALL))) + (void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL); } - else -#endif - lnum -= n; - curwin->w_cursor.lnum = lnum; + if (lnum < 1) + lnum = 1; } + else +#endif + lnum -= n; + + wp->w_cursor.lnum = lnum; + return lnum; +} + + int +cursor_up( + long n, + int upd_topline) // When TRUE: update topline +{ + if (n > 0 && cursor_up_inner(curwin, n) == 0) + return FAIL; // try to advance to the column we want to be at coladvance(curwin->w_curswant); @@ -2806,54 +2816,64 @@ cursor_up( } /* - * Cursor down a number of logical lines. + * Move the cursor down "n" lines in window "wp". + * Takes care of closed folds. + * Returns the new cursor line or zero for failure. */ - int -cursor_down( - long n, - int upd_topline) // When TRUE: update topline + linenr_T +cursor_down_inner(win_T *wp, long n) { - linenr_T lnum; + linenr_T lnum = wp->w_cursor.lnum; + linenr_T line_count = wp->w_buffer->b_ml.ml_line_count; - if (n > 0) - { - lnum = curwin->w_cursor.lnum; #ifdef FEAT_FOLDING - // Move to last line of fold, will fail if it's the end-of-file. - (void)hasFolding(lnum, NULL, &lnum); -#endif - // This fails if the cursor is already in the last line or would move - // beyond the last line and '-' is in 'cpoptions' - if (lnum >= curbuf->b_ml.ml_line_count - || (lnum + n > curbuf->b_ml.ml_line_count - && vim_strchr(p_cpo, CPO_MINUS) != NULL)) - return FAIL; - if (lnum + n >= curbuf->b_ml.ml_line_count) - lnum = curbuf->b_ml.ml_line_count; - else + // Move to last line of fold, will fail if it's the end-of-file. + (void)hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL); +#endif + // This fails if the cursor is already in the last line or would move + // beyond the last line and '-' is in 'cpoptions' + if (lnum >= line_count + || (lnum + n > line_count && vim_strchr(p_cpo, CPO_MINUS) != NULL)) + return FAIL; + if (lnum + n >= line_count) + lnum = line_count; + else #ifdef FEAT_FOLDING - if (hasAnyFolding(curwin)) - { - linenr_T last; + if (hasAnyFolding(wp)) + { + linenr_T last; - // count each sequence of folded lines as one logical line - while (n--) - { - if (hasFolding(lnum, NULL, &last)) - lnum = last + 1; - else - ++lnum; - if (lnum >= curbuf->b_ml.ml_line_count) - break; - } - if (lnum > curbuf->b_ml.ml_line_count) - lnum = curbuf->b_ml.ml_line_count; + // count each sequence of folded lines as one logical line + while (n--) + { + if (hasFoldingWin(wp, lnum, NULL, &last, TRUE, NULL)) + lnum = last + 1; + else + ++lnum; + if (lnum >= line_count) + break; } - else -#endif - lnum += n; - curwin->w_cursor.lnum = lnum; + if (lnum > line_count) + lnum = line_count; } + else +#endif + lnum += n; + + wp->w_cursor.lnum = lnum; + return lnum; +} + +/* + * Cursor down a number of logical lines. + */ + int +cursor_down( + long n, + int upd_topline) // When TRUE: update topline +{ + if (n > 0 && cursor_down_inner(curwin, n) == 0) + return FAIL; // try to advance to the column we want to be at coladvance(curwin->w_curswant); -- cgit v1.2.3