summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-02-15 13:40:17 +0000
committerBram Moolenaar <Bram@vim.org>2022-02-15 13:40:17 +0000
commit4556a2e8681c5c98fb4c7ca0a016924a69b4452a (patch)
tree7f5cb71bb3b4713c2fc9a10465cf320834c063c9
parent7745f14ef324a7134b2f26a47451cf5032f44b89 (diff)
patch 8.2.4389: screenpos() does not handle a position in a closed foldv8.2.4389
Problem: screenpos() does not handle a position in a closed fold. Solution: Check if the position is inside a closed fold. (closes #9778)
-rw-r--r--src/move.c71
-rw-r--r--src/testdir/test_cursor_func.vim21
-rw-r--r--src/version.c2
3 files changed, 64 insertions, 30 deletions
diff --git a/src/move.c b/src/move.c
index f52e4c071e..1c88e6ebcc 100644
--- a/src/move.c
+++ b/src/move.c
@@ -1236,39 +1236,54 @@ textpos2screenpos(
if (pos->lnum >= wp->w_topline && pos->lnum <= wp->w_botline)
{
- colnr_T off;
- colnr_T col;
- int width;
-
- row = plines_m_win(wp, wp->w_topline, pos->lnum - 1) + 1;
- getvcol(wp, pos, &scol, &ccol, &ecol);
-
- // similar to what is done in validate_cursor_col()
- col = scol;
- off = win_col_off(wp);
- col += off;
- width = wp->w_width - off + win_col_off2(wp);
+ colnr_T off;
+ colnr_T col;
+ int width;
+ linenr_T lnum = pos->lnum;
+#ifdef FEAT_FOLDING
+ int is_folded;
- // long line wrapping, adjust row
- if (wp->w_p_wrap
- && col >= (colnr_T)wp->w_width
- && width > 0)
- {
- // use same formula as what is used in curs_columns()
- rowoff = ((col - wp->w_width) / width + 1);
- col -= rowoff * width;
- }
- col -= wp->w_leftcol;
- if (col >= wp->w_width)
- col = -1;
- if (col >= 0 && row + rowoff <= wp->w_height)
+ is_folded = hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
+#endif
+ row = plines_m_win(wp, wp->w_topline, lnum - 1) + 1;
+#ifdef FEAT_FOLDING
+ if (is_folded)
{
- coloff = col - scol + wp->w_wincol + 1;
row += W_WINROW(wp);
+ coloff = wp->w_wincol + 1;
}
else
- // character is left, right or below of the window
- row = rowoff = scol = ccol = ecol = 0;
+#endif
+ {
+ getvcol(wp, pos, &scol, &ccol, &ecol);
+
+ // similar to what is done in validate_cursor_col()
+ col = scol;
+ off = win_col_off(wp);
+ col += off;
+ width = wp->w_width - off + win_col_off2(wp);
+
+ // long line wrapping, adjust row
+ if (wp->w_p_wrap
+ && col >= (colnr_T)wp->w_width
+ && width > 0)
+ {
+ // use same formula as what is used in curs_columns()
+ rowoff = ((col - wp->w_width) / width + 1);
+ col -= rowoff * width;
+ }
+ col -= wp->w_leftcol;
+ if (col >= wp->w_width)
+ col = -1;
+ if (col >= 0 && row + rowoff <= wp->w_height)
+ {
+ coloff = col - scol + wp->w_wincol + 1;
+ row += W_WINROW(wp);
+ }
+ else
+ // character is left, right or below of the window
+ row = rowoff = scol = ccol = ecol = 0;
+ }
}
*rowp = row + rowoff;
*scolp = scol + coloff;
diff --git a/src/testdir/test_cursor_func.vim b/src/testdir/test_cursor_func.vim
index bc12511aff..7d21d84729 100644
--- a/src/testdir/test_cursor_func.vim
+++ b/src/testdir/test_cursor_func.vim
@@ -1,5 +1,7 @@
" Tests for cursor() and other functions that get/set the cursor position
+source check.vim
+
func Test_wrong_arguments()
call assert_fails('call cursor(1. 3)', 'E474:')
call assert_fails('call cursor(test_null_list())', 'E474:')
@@ -133,12 +135,27 @@ func Test_screenpos()
bwipe!
set display&
- call assert_equal({'col': 1, 'row': 1, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1))
+ call assert_equal(#{col: 1, row: 1, endcol: 1, curscol: 1}, screenpos(win_getid(), 1, 1))
nmenu WinBar.TEST :
- call assert_equal({'col': 1, 'row': 2, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1))
+ call assert_equal(#{col: 1, row: 2, endcol: 1, curscol: 1}, screenpos(win_getid(), 1, 1))
nunmenu WinBar.TEST
endfunc
+func Test_screenpos_fold()
+ CheckFeature folding
+
+ enew!
+ call setline(1, range(10))
+ 3,5fold
+ redraw
+ call assert_equal(2, screenpos(1, 2, 1).row)
+ call assert_equal(#{col: 1, row: 3, endcol: 1, curscol: 1}, screenpos(1, 3, 1))
+ call assert_equal(3, screenpos(1, 4, 1).row)
+ call assert_equal(3, screenpos(1, 5, 1).row)
+ call assert_equal(4, screenpos(1, 6, 1).row)
+ bwipe!
+endfunc
+
func Test_screenpos_number()
rightbelow new
rightbelow 73vsplit
diff --git a/src/version.c b/src/version.c
index 559b6022d8..7bf2ddb9ac 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4389,
+/**/
4388,
/**/
4387,