0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

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)
This commit is contained in:
Luuk van Baal
2022-09-27 12:31:15 +01:00
committed by Bram Moolenaar
parent 7fc6c0e4da
commit 7c1cbb6cd4
8 changed files with 205 additions and 110 deletions

View File

@@ -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);
@@ -2805,6 +2815,55 @@ cursor_up(
return OK;
}
/*
* 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.
*/
@@ -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);