mirror of
https://github.com/vim/vim.git
synced 2025-09-29 04:34:16 -04:00
patch 8.1.0994: relative cursor position is not calculated correctly
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.
This commit is contained in:
@@ -5228,6 +5228,7 @@ getwininfo([{winid}]) *getwininfo()*
|
||||
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
|
||||
@@ -5237,6 +5238,7 @@ getwininfo([{winid}]) *getwininfo()*
|
||||
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
|
||||
|
@@ -5762,6 +5762,8 @@ get_win_info(win_T *wp, short tpnr, short winnr)
|
||||
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
|
||||
|
@@ -615,4 +615,132 @@ func Test_window_prevwin()
|
||||
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
|
||||
|
@@ -779,6 +779,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
994,
|
||||
/**/
|
||||
993,
|
||||
/**/
|
||||
|
19
src/window.c
19
src/window.c
@@ -5719,8 +5719,11 @@ win_drag_vsep_line(win_T *dragwin, int offset)
|
||||
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
|
||||
+ wp->w_height / 2) / (long)wp->w_height;
|
||||
+ FRACTION_MULT / 2) / (long)wp->w_height;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5770,8 +5773,8 @@ scroll_to_fraction(win_T *wp, int prev_height)
|
||||
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. */
|
||||
// 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,8 +5784,8 @@ scroll_to_fraction(win_T *wp, int prev_height)
|
||||
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;
|
||||
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,7 +5821,6 @@ scroll_to_fraction(win_T *wp, int prev_height)
|
||||
--wp->w_wrow;
|
||||
}
|
||||
}
|
||||
set_topline(wp, lnum);
|
||||
}
|
||||
else if (sline > 0)
|
||||
{
|
||||
@@ -5859,13 +5861,12 @@ scroll_to_fraction(win_T *wp, int prev_height)
|
||||
}
|
||||
else if (sline > 0)
|
||||
{
|
||||
/* First line of file reached, use that as topline. */
|
||||
// First line of file reached, use that as topline.
|
||||
lnum = 1;
|
||||
wp->w_wrow -= sline;
|
||||
}
|
||||
|
||||
set_topline(wp, lnum);
|
||||
}
|
||||
set_topline(wp, lnum);
|
||||
}
|
||||
|
||||
if (wp == curwin)
|
||||
|
Reference in New Issue
Block a user