summaryrefslogtreecommitdiff
path: root/src/edit.c
diff options
context:
space:
mode:
authorLuuk van Baal <luukvbaal@gmail.com>2022-09-27 12:31:15 +0100
committerBram Moolenaar <Bram@vim.org>2022-09-27 12:31:15 +0100
commit7c1cbb6cd437c6e0c3ccc05840cc931108b4a60a (patch)
tree6beeee2a32dd5f38a4aa2429c2573ad3a96658dc /src/edit.c
parent7fc6c0e4dab4e80b9806a973936af54276468513 (diff)
downloadvim-git-7c1cbb6cd437c6e0c3ccc05840cc931108b4a60a.tar.gz
patch 9.0.0603: with 'nosplitscroll' folds are not handled correctlyv9.0.0603
Problem: With 'nosplitscroll' folds are not handled correctly. Solution: Take care of closed folds when moving the cursor. (Luuk van Baal, closes #11234)
Diffstat (limited to 'src/edit.c')
-rw-r--r--src/edit.c180
1 files changed, 100 insertions, 80 deletions
diff --git a/src/edit.c b/src/edit.c
index ec3e8ff6c..2ac544a6b 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);