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);