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 | |
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
-rw-r--r-- | runtime/doc/eval.txt | 2 | ||||
-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 | ||||
-rw-r--r-- | test/functional/terminal/window_split_tab_spec.lua | 9 | ||||
-rw-r--r-- | test/functional/ui/highlight_spec.lua | 9 | ||||
-rw-r--r-- | test/functional/ui/inccommand_spec.lua | 18 | ||||
-rw-r--r-- | test/functional/ui/mouse_spec.lua | 17 | ||||
-rw-r--r-- | test/functional/ui/popupmenu_spec.lua | 6 | ||||
-rw-r--r-- | test/functional/ui/syntax_conceal_spec.lua | 7 |
10 files changed, 177 insertions, 38 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 3efe651dfe..da17faaaf6 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -4504,11 +4504,13 @@ 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 quickfix 1 if quickfix or location list window tabnr tab page number + topline first displayed buffer line variables a reference to the dictionary with window-local variables width window width 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) { diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua index f3d0b45d09..c0ce656bb1 100644 --- a/test/functional/terminal/window_split_tab_spec.lua +++ b/test/functional/terminal/window_split_tab_spec.lua @@ -39,10 +39,11 @@ describe(':terminal', function() it('does not change size on WinEnter', function() if helpers.pending_win32(pending) then return end feed('<c-\\><c-n>') + feed('k') feed_command('2split') screen:expect([[ - tty ready | - ^rows: 5, cols: 50 | + ^tty ready | + rows: 5, cols: 50 | ========== | tty ready | rows: 5, cols: 50 | @@ -57,8 +58,8 @@ describe(':terminal', function() tty ready | rows: 5, cols: 50 | ========== | - tty ready | - ^rows: 5, cols: 50 | + ^tty ready | + rows: 5, cols: 50 | {2: } | | | diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index 39170337d7..3ee3f173d6 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -1274,17 +1274,18 @@ describe("'winhighlight' highlight", function() command('set number') command('set colorcolumn=2') command('set cursorcolumn') + feed('k') command('split') command('set winhl=LineNr:Background1,CursorColumn:Background2,' ..'ColorColumn:ErrorMsg') screen:expect([[ - {1: 1 }v{15:e}ry tex{5:t} | - {1: 2 }m{15:o}re tex^t | + {1: 1 }v{15:e}ry tex^t | + {1: 2 }m{15:o}re tex{5:t} | {0:~ }| {3:[No Name] [+] }| - {9: 1 }v{17:e}ry tex{18:t} | - {9: 2 }m{17:o}re text | + {9: 1 }v{17:e}ry text | + {9: 2 }m{17:o}re tex{18:t} | {4:[No Name] [+] }| | ]]) diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 536264019c..c215ece2f2 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -938,11 +938,11 @@ describe(":substitute, inccommand=split", function() feed(":%s/tw") -- 'cursorline' is NOT active during preview. screen:expect([[ - Inc substitution on | {12:tw}o lines | Inc substitution on | {12:tw}o lines | | + {15:~ }| {11:[No Name] [+] }| |2| {12:tw}o lines | |4| {12:tw}o lines | @@ -1185,6 +1185,7 @@ describe(":substitute, inccommand=split", function() end) it("clears preview if non-previewable command is edited #5585", function() + feed('gg') -- Put a non-previewable command in history. feed_command("echo 'foo'") -- Start an incomplete :substitute command. @@ -2084,11 +2085,11 @@ describe(":substitute", function() feed(":%s/[0-9]\\n\\zs[A-Z]/OKO") screen:expect([[ - 1 2 3 | {12:OKO} B C | 4 5 6 | {12:OKO} Y Z | 7 8 9 | + | {11:[No Name] [+] }| |1| 1 2 3 | |2| {12:OKO} B C | @@ -2204,11 +2205,11 @@ describe(":substitute", function() feed("/KKK") screen:expect([[ - x | afa {12:KKK}adf la;lkd {12:KKK}alx | | {15:~ }| {15:~ }| + {15:~ }| {11:[No Name] [+] }| |3| afa {12:KKK}adf la;lkd {12:KKK}alx | {15:~ }| @@ -2256,11 +2257,11 @@ describe(":substitute", function() common_setup(screen, "split", multibyte_text) feed(":%s/£.*ѫ/X¥¥") screen:expect([[ - {12:X¥¥} | a{12:X¥¥}¥KOL | £ ¥ libm | £ ¥ | | + {15:~ }| {11:[No Name] [+] }| |1| {12:X¥¥} PEPPERS | |2| {12:X¥¥} | @@ -2275,11 +2276,11 @@ describe(":substitute", function() feed("\\ra££ ¥") screen:expect([[ - {12:a££ ¥} | a{12:X¥¥} | {12:a££ ¥}¥KOL | £ ¥ libm | £ ¥ | + | {11:[No Name] [+] }| |1| {12:X¥¥} | |2|{12: a££ ¥} PEPPERS | @@ -2378,7 +2379,6 @@ describe(":substitute", function() feed("\\rѫ ab \\rXXXX") screen:expect([[ - 7 8 9 | K L M | {12:JLKR £} | {12:ѫ ab } | @@ -2387,6 +2387,7 @@ describe(":substitute", function() {12:ѫ ab } | {12:XXXX} e f | {12:JLKR £} | + {12:ѫ ab } | {11:[No Name] [+] }| | 7| {12:JLKR £} | | 8|{12: ѫ ab } | @@ -2480,14 +2481,15 @@ describe(":substitute", function() ]]) feed("<C-c>") + feed('gg') wait() feed([[:%s/\(some\)\@<lt>!thing/one/]]) screen:expect([[ - something | every{12:one} | someone | {15:~ }| {15:~ }| + {15:~ }| {11:[No Name] [+] }| |2| every{12:one} | {15:~ }| @@ -2525,11 +2527,11 @@ describe(":substitute", function() wait() feed([[:%s/some\(thing\)\@!/every/]]) screen:expect([[ - everything | {12:every}one | {15:~ }| {15:~ }| {15:~ }| + {15:~ }| {11:[No Name] [+] }| |3| {12:every}one | {15:~ }| diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index 7805ed3cb9..c1a350dc34 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -649,13 +649,14 @@ describe('ui/mouse/input', function() mouse scrolling ]]) screen:try_resize(53, 14) + feed('k') feed_command('sp', 'vsp') screen:expect([[ lines {4:│}lines | to {4:│}to | test {4:│}test | - mouse scrolling {4:│}mouse scrolling | - ^ {4:│} | + ^mouse scrolling {4:│}mouse scrolling | + {4:│} | {0:~ }{4:│}{0:~ }| {5:[No Name] [+] }{4:[No Name] [+] }| to | @@ -672,8 +673,8 @@ describe('ui/mouse/input', function() feed('<ScrollWheelDown><0,0>') end screen:expect([[ - mouse scrolling {4:│}lines | - ^ {4:│}to | + ^mouse scrolling {4:│}lines | + {4:│}to | {0:~ }{4:│}test | {0:~ }{4:│}mouse scrolling | {0:~ }{4:│} | @@ -693,8 +694,8 @@ describe('ui/mouse/input', function() feed('<ScrollWheelUp><27,0>') end screen:expect([[ - mouse scrolling {4:│}text | - ^ {4:│}with | + ^mouse scrolling {4:│}text | + {4:│}with | {0:~ }{4:│}many | {0:~ }{4:│}lines | {0:~ }{4:│}to | @@ -715,8 +716,8 @@ describe('ui/mouse/input', function() feed('<ScrollWheelUp><27,7><ScrollWheelUp>') end screen:expect([[ - mouse scrolling {4:│}text | - ^ {4:│}with | + ^mouse scrolling {4:│}text | + {4:│}with | {0:~ }{4:│}many | {0:~ }{4:│}lines | {0:~ }{4:│}to | diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 9a8c5a5789..1e6ebb87f5 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1198,20 +1198,20 @@ describe('builtin popupmenu', function() command("split") screen:expect([[ - xx | choice^ | + {1:~ }| {n:word }{1: }| {s:choice }{4: }| {n:text } | - {n:thing } | + {n:thing }{1: }| {3:[No Name] [+] }| {2:-- INSERT --} | ]]) meths.input_mouse('wheel', 'down', '', 0, 6, 15) screen:expect([[ - xx | choice^ | + {1:~ }| {n:word }{1: }| {s:choice }{4: }| {n:text } | diff --git a/test/functional/ui/syntax_conceal_spec.lua b/test/functional/ui/syntax_conceal_spec.lua index d678784dc9..00e94ef94b 100644 --- a/test/functional/ui/syntax_conceal_spec.lua +++ b/test/functional/ui/syntax_conceal_spec.lua @@ -356,16 +356,17 @@ describe('Screen', function() end) it('between windows', function() + feed('k') command("split") screen:expect([[ foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | foo barf bar barf egg^s | + foo {1:b} bar {1:b} eggs | | {2:[No Name] [+] }| foo {1:b} bar {1:b} eggs | foo {1:b} bar {1:b} eggs | - | + foo {1:b} bar {1:b} eggs | {3:[No Name] [+] }| | ]]) @@ -379,7 +380,7 @@ describe('Screen', function() {3:[No Name] [+] }| foo {1:b} bar {1:b} eggs | foo barf bar barf egg^s | - | + foo {1:b} bar {1:b} eggs | {2:[No Name] [+] }| | ]]) |