Mercurial > vim
diff src/edit.c @ 30535:04df44c52d65 v9.0.0603
patch 9.0.0603: with 'nosplitscroll' folds are not handled correctly
Commit: https://github.com/vim/vim/commit/7c1cbb6cd437c6e0c3ccc05840cc931108b4a60a
Author: Luuk van Baal <luukvbaal@gmail.com>
Date: Tue Sep 27 12:31:15 2022 +0100
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 27 Sep 2022 13:45:04 +0200 |
parents | 087c42245022 |
children | 9a6f7e750697 |
line wrap: on
line diff
--- a/src/edit.c +++ b/src/edit.c @@ -2749,52 +2749,62 @@ oneleft(void) return OK; } +/* + * 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 = wp->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 0; + if (n >= lnum) + lnum = 1; + else +#ifdef FEAT_FOLDING + 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)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL); + } + 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 { - linenr_T 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 -#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); - - 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; - } - else -#endif - lnum -= n; - curwin->w_cursor.lnum = lnum; - } + 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,6 +2816,55 @@ cursor_up( } /* + * Move the cursor down "n" lines in window "wp". + * Takes care of closed folds. + * Returns the new cursor line or zero for failure. + */ + linenr_T +cursor_down_inner(win_T *wp, long n) +{ + linenr_T lnum = wp->w_cursor.lnum; + linenr_T line_count = wp->w_buffer->b_ml.ml_line_count; + +#ifdef FEAT_FOLDING + // 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(wp)) + { + linenr_T last; + + // 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; + } + 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 @@ -2813,47 +2872,8 @@ cursor_down( long n, int upd_topline) // When TRUE: update topline { - linenr_T lnum; - - 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 -#ifdef FEAT_FOLDING - if (hasAnyFolding(curwin)) - { - 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; - } - else -#endif - lnum += n; - curwin->w_cursor.lnum = lnum; - } + 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);