]> granicus.if.org Git - vim/commitdiff
patch 8.2.4389: screenpos() does not handle a position in a closed fold v8.2.4389
authorBram Moolenaar <Bram@vim.org>
Tue, 15 Feb 2022 13:40:17 +0000 (13:40 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 15 Feb 2022 13:40:17 +0000 (13:40 +0000)
Problem:    screenpos() does not handle a position in a closed fold.
Solution:   Check if the position is inside a closed fold. (closes #9778)

src/move.c
src/testdir/test_cursor_func.vim
src/version.c

index f52e4c071e48549fc3592aa5ed416c4b28d9de45..1c88e6ebcc5959a55707b44ad27fd34e147b1758 100644 (file)
@@ -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;
index bc12511aff33f01cf60214fda9872f4eb3bf9dae..7d21d847294773b253ae52be50f80c943468a8ca 100644 (file)
@@ -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
index 559b6022d8dbc7492547a7d19c12d2e35a7ff637..7bf2ddb9ac5c7a017f099795bd6a9be2cdaf3412 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4389,
 /**/
     4388,
 /**/