diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-03-09 23:12:33 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-09 23:12:33 +0100 |
commit | 3cb89cafe3e99fc64f6fd6fff47831d1a9331b4e (patch) | |
tree | d1425262042fabbf9c3c575270cc7ab5f73ebd2e /src | |
parent | 6eca56c6c5a994be77ad6fd28a3639d963cb7ffc (diff) | |
download | rneovim-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.c | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_window_cmd.vim | 128 | ||||
-rw-r--r-- | src/nvim/window.c | 17 |
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) { |