aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-03-09 23:12:33 +0100
committerGitHub <noreply@github.com>2019-03-09 23:12:33 +0100
commit3cb89cafe3e99fc64f6fd6fff47831d1a9331b4e (patch)
treed1425262042fabbf9c3c575270cc7ab5f73ebd2e /src
parent6eca56c6c5a994be77ad6fd28a3639d963cb7ffc (diff)
downloadrneovim-3cb89cafe3e99fc64f6fd6fff47831d1a9331b4e.tar.gz
rneovim-3cb89cafe3e99fc64f6fd6fff47831d1a9331b4e.tar.bz2
rneovim-3cb89cafe3e99fc64f6fd6fff47831d1a9331b4e.zip
vim-patch:8.1.0994: fix relative cursor position #9676
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. https://github.com/vim/vim/commit/8fcb60f961bdd134599fb016c6537fd496e800f5
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/testdir/test_window_cmd.vim128
-rw-r--r--src/nvim/window.c17
3 files changed, 139 insertions, 8 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 57777f049a..c23177f23a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -10316,6 +10316,8 @@ static dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr)
tv_dict_add_nr(dict, S_LEN("winid"), wp->handle);
tv_dict_add_nr(dict, S_LEN("height"), wp->w_height);
tv_dict_add_nr(dict, S_LEN("winrow"), wp->w_winrow);
+ tv_dict_add_nr(dict, S_LEN("topline"), wp->w_topline);
+ tv_dict_add_nr(dict, S_LEN("botline"), wp->w_botline - 1);
tv_dict_add_nr(dict, S_LEN("width"), wp->w_width);
tv_dict_add_nr(dict, S_LEN("bufnr"), wp->w_buffer->b_fnum);
tv_dict_add_nr(dict, S_LEN("wincol"), wp->w_wincol);
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
index b3ab6957dc..57fb36abb8 100644
--- a/src/nvim/testdir/test_window_cmd.vim
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -518,4 +518,132 @@ func Test_winrestcmd()
only
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
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 2d71c19230..efdee34c10 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -5332,7 +5332,10 @@ void win_drag_vsep_line(win_T *dragwin, int offset)
void set_fraction(win_T *wp)
{
if (wp->w_height_inner > 1) {
- wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height_inner / 2)
+ // 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_inner;
}
}
@@ -5364,8 +5367,8 @@ void scroll_to_fraction(win_T *wp, int prev_height)
int sline, line_size;
int height = wp->w_height_inner;
- /* 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)
) {
@@ -5376,8 +5379,7 @@ void 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;
@@ -5408,7 +5410,6 @@ void scroll_to_fraction(win_T *wp, int prev_height)
wp->w_wrow--;
}
}
- set_topline(wp, lnum);
} else if (sline > 0) {
while (sline > 0 && lnum > 1) {
(void)hasFoldingWin(wp, lnum, &lnum, NULL, true, NULL);
@@ -5437,12 +5438,12 @@ void scroll_to_fraction(win_T *wp, int prev_height)
lnum++;
wp->w_wrow -= line_size + sline;
} 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) {