Patch 8.1.0994
Problem:    Relative cursor position is not calculated correctly.
Solution:   Always set topline, also when window is one line only.
            (Robert Webb) Add more info to getwininfo() for testing.
Files:      src/window.c, src/evalfunc.c, runtime/doc/eval.txt,
            src/testdir/test_window_cmd.vim


*** ../vim-8.1.0993/src/window.c        2019-02-22 17:56:02.787842436 +0100
--- src/window.c        2019-03-04 13:13:19.387148607 +0100
***************
*** 5719,5726 ****
  set_fraction(win_T *wp)
  {
      if (wp->w_height > 1)
        wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT
!                                   + wp->w_height / 2) / (long)wp->w_height;
  }
  
  /*
--- 5719,5729 ----
  set_fraction(win_T *wp)
  {
      if (wp->w_height > 1)
+       // When cursor is in the first line the percentage is computed as if
+       // it's halfway that line.  Thus with two lines it is 25%, with three
+       // lines 17%, etc.  Similarly for the last line: 75%, 83%, etc.
        wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT
!                                    + FRACTION_MULT / 2) / (long)wp->w_height;
  }
  
  /*
***************
*** 5770,5777 ****
      int               sline, line_size;
      int               height = wp->w_height;
  
!     /* Don't change w_topline when height is zero.  Don't set w_topline when
!      * 'scrollbind' is set and this isn't the current window. */
      if (height > 0 && (!wp->w_p_scb || wp == curwin))
      {
        /*
--- 5773,5780 ----
      int               sline, line_size;
      int               height = wp->w_height;
  
!     // Don't change w_topline when height is zero.  Don't set w_topline when
!     // 'scrollbind' is set and this isn't the current window.
      if (height > 0 && (!wp->w_p_scb || wp == curwin))
      {
        /*
***************
*** 5781,5788 ****
        lnum = wp->w_cursor.lnum;
        if (lnum < 1)           /* can happen when starting up */
            lnum = 1;
!       wp->w_wrow = ((long)wp->w_fraction * (long)height - 1L
!                                        + FRACTION_MULT / 2) / FRACTION_MULT;
        line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1;
        sline = wp->w_wrow - line_size;
  
--- 5784,5791 ----
        lnum = wp->w_cursor.lnum;
        if (lnum < 1)           /* can happen when starting up */
            lnum = 1;
!       wp->w_wrow = ((long)wp->w_fraction * (long)height - 1L)
!                                                              / FRACTION_MULT;
        line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1;
        sline = wp->w_wrow - line_size;
  
***************
*** 5818,5824 ****
                    --wp->w_wrow;
                }
            }
-           set_topline(wp, lnum);
        }
        else if (sline > 0)
        {
--- 5821,5826 ----
***************
*** 5859,5871 ****
            }
            else if (sline > 0)
            {
!               /* First line of file reached, use that as topline. */
                lnum = 1;
                wp->w_wrow -= sline;
            }
- 
-           set_topline(wp, lnum);
        }
      }
  
      if (wp == curwin)
--- 5861,5872 ----
            }
            else if (sline > 0)
            {
!               // First line of file reached, use that as topline.
                lnum = 1;
                wp->w_wrow -= sline;
            }
        }
+       set_topline(wp, lnum);
      }
  
      if (wp == curwin)
*** ../vim-8.1.0993/src/evalfunc.c      2019-03-02 10:13:36.792974862 +0100
--- src/evalfunc.c      2019-03-02 14:10:35.133529737 +0100
***************
*** 5762,5767 ****
--- 5762,5769 ----
      dict_add_number(dict, "winid", wp->w_id);
      dict_add_number(dict, "height", wp->w_height);
      dict_add_number(dict, "winrow", wp->w_winrow + 1);
+     dict_add_number(dict, "topline", wp->w_topline);
+     dict_add_number(dict, "botline", wp->w_botline - 1);
  #ifdef FEAT_MENU
      dict_add_number(dict, "winbar", wp->w_winbar_height);
  #endif
*** ../vim-8.1.0993/runtime/doc/eval.txt        2019-02-12 22:28:27.841232690 
+0100
--- runtime/doc/eval.txt        2019-03-02 14:09:27.798085747 +0100
***************
*** 5195,5200 ****
--- 5228,5234 ----
                tab pages is returned.
  
                Each List item is a Dictionary with the following entries:
+                       botline         last displayed buffer line
                        bufnr           number of buffer in the window
                        height          window height (excluding winbar)
                        loclist         1 if showing a location list
***************
*** 5204,5209 ****
--- 5238,5244 ----
                        terminal        1 if a terminal window
                                        {only with the +terminal feature}
                        tabnr           tab page number
+                       topline         first displayed buffer line 
                        variables       a reference to the dictionary with
                                        window-local variables
                        width           window width
*** ../vim-8.1.0993/src/testdir/test_window_cmd.vim     2019-01-09 
23:00:58.001176090 +0100
--- src/testdir/test_window_cmd.vim     2019-03-04 13:09:05.308910495 +0100
***************
*** 615,618 ****
--- 615,746 ----
    delfunc Fun_RenewFile
  endfunc
  
+ func Test_relative_cursor_position_in_one_line_window()
+   new
+   only
+   call setline(1, range(1, 10000))
+   normal 50%
+   let lnum = getcurpos()[1]
+   split
+   split
+   " make third window take as many lines as possible, other windows will
+   " become one line
+   3wincmd w
+   for i in range(1, &lines - 6)
+     wincmd +
+     redraw!
+   endfor
+ 
+   " first and second window should show cursor line
+   let wininfo = getwininfo()
+   call assert_equal(lnum, wininfo[0].topline)
+   call assert_equal(lnum, wininfo[1].topline)
+ 
+   only!
+   bwipe!
+ endfunc
+ 
+ func Test_relative_cursor_position_after_move_and_resize()
+   let so_save = &so
+   set so=0
+   enew
+   call setline(1, range(1, 10000))
+   normal 50%
+   split
+   1wincmd w
+   " Move cursor to first line in window
+   normal H
+   redraw!
+   " Reduce window height to two lines
+   let height = winheight(0)
+   while winheight(0) > 2
+     wincmd -
+     redraw!
+   endwhile
+   " move cursor to second/last line in window
+   normal j
+   " restore previous height
+   while winheight(0) < height
+     wincmd +
+     redraw!
+   endwhile
+   " make window two lines again
+   while winheight(0) > 2
+     wincmd -
+     redraw!
+   endwhile
+ 
+   " cursor should be at bottom line
+   let info = getwininfo(win_getid())[0]
+   call assert_equal(info.topline + 1, getcurpos()[1])
+ 
+   only!
+   bwipe!
+   let &so = so_save
+ endfunc
+ 
+ func Test_relative_cursor_position_after_resize()
+   let so_save = &so
+   set so=0
+   enew
+   call setline(1, range(1, 10000))
+   normal 50%
+   split
+   1wincmd w
+   let winid1 = win_getid()
+   let info = getwininfo(winid1)[0]
+   " Move cursor to second line in window
+   exe "normal " . (info.topline + 1) . "G"
+   redraw!
+   let lnum = getcurpos()[1]
+ 
+   " Make the window only two lines high, cursor should end up in top line
+   2wincmd w
+   exe (info.height - 2) . "wincmd +"
+   redraw!
+   let info = getwininfo(winid1)[0]
+   call assert_equal(lnum, info.topline)
+ 
+   only!
+   bwipe!
+   let &so = so_save
+ endfunc
+ 
+ func Test_relative_cursor_second_line_after_resize()
+   let so_save = &so
+   set so=0
+   enew
+   call setline(1, range(1, 10000))
+   normal 50%
+   split
+   1wincmd w
+   let winid1 = win_getid()
+   let info = getwininfo(winid1)[0]
+ 
+   " Make the window only two lines high
+   2wincmd _
+ 
+   " Move cursor to second line in window
+   normal H
+   normal j
+ 
+   " Make window size bigger, then back to 2 lines
+   for i in range(1, 10)
+     wincmd +
+     redraw!
+   endfor
+   for i in range(1, 10)
+     wincmd -
+     redraw!
+   endfor
+ 
+   " cursor should end up in bottom line
+   let info = getwininfo(winid1)[0]
+   call assert_equal(info.topline + 1, getcurpos()[1])
+ 
+   only!
+   bwipe!
+   let &so = so_save
+ endfunc
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.1.0993/src/version.c       2019-03-04 12:09:43.905395998 +0100
--- src/version.c       2019-03-04 13:16:17.053913047 +0100
***************
*** 781,782 ****
--- 781,784 ----
  {   /* Add new patch number below this line */
+ /**/
+     994,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
36. You miss more than five meals a week downloading the latest games from
    Apogee.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui