From 387c3be82a34f698d483347cbad4a7cfd39153b8 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 21 Aug 2018 11:25:27 -0400 Subject: [PATCH 1/4] vim-patch:8.0.1331: possible crash when window can be zero lines high Problem: Possible crash when window can be zero lines high. (Joseph Dornisch) Solution: Only set w_fraction if the window is at least two lines high. https://github.com/vim/vim/commit/3679c17917d7ff22e836982c81e5816bd07451dd --- src/nvim/window.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/nvim/window.c b/src/nvim/window.c index 8239061a0c..751d70a14a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -843,8 +843,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) /* Set w_fraction now so that the cursor keeps the same relative * vertical position. */ - if (oldwin->w_height > 0) - set_fraction(oldwin); + set_fraction(oldwin); wp->w_fraction = oldwin->w_fraction; if (flags & WSP_VERT) { @@ -4791,10 +4790,13 @@ void win_drag_vsep_line(win_T *dragwin, int offset) #define FRACTION_MULT 16384L // Set wp->w_fraction for the current w_wrow and w_height. +// Has no effect when the window is less than two lines. void set_fraction(win_T *wp) { - wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height / 2) + if (wp->w_height > 1) { + wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height / 2) / (long)wp->w_height; + } } /* From 39777ad4b8fdd4e09df85025667845b43e1f2d72 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 21 Aug 2018 12:04:44 -0400 Subject: [PATCH 2/4] vim-patch:8.0.1426: "gf" and don't accept ? and & in URL Problem: "gf" and don't accept ? and & in URL. (Dmitrii Tcyganok) Solution: Check for a URL and allow for extra characters. (closes vim/vim#2493) https://github.com/vim/vim/commit/9e3dfc650190e96739abc004eb9948afa68136b4 --- src/nvim/testdir/test_gf.vim | 7 ++++++- src/nvim/window.c | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim index ef1bf1075b..c352379697 100644 --- a/src/nvim/testdir/test_gf.vim +++ b/src/nvim/testdir/test_gf.vim @@ -7,7 +7,8 @@ func Test_gf_url() \ "first test for URL://machine.name/tmp/vimtest2a and other text", \ "second test for URL://machine.name/tmp/vimtest2b. And other text", \ "third test for URL:\\\\machine.name\\vimtest2c and other text", - \ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text" + \ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text", + \ "fifth test for URL://machine.name/tmp?q=vim&opt=yes and other text", \ ]) call cursor(1,1) call search("^first") @@ -28,6 +29,10 @@ func Test_gf_url() call search("URL") call assert_equal("URL:\\\\machine.name\\tmp\\vimtest2d", expand("")) + call search("^fifth") + call search("URL") + call assert_equal("URL://machine.name/tmp?q=vim&opt=yes", expand("")) + set isf&vim enew! endfunc diff --git a/src/nvim/window.c b/src/nvim/window.c index 751d70a14a..d9903338e8 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5112,6 +5112,8 @@ file_name_in_line ( { char_u *ptr; size_t len; + bool in_type = true; + bool is_url = false; /* * search forward for what could be the start of a file name @@ -5147,7 +5149,19 @@ file_name_in_line ( */ len = 0; while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ') - || ((options & FNAME_HYP) && path_is_url((char *)ptr + len))) { + || ((options & FNAME_HYP) && path_is_url((char *)ptr + len)) + || (is_url && vim_strchr((char_u *)"?&=", ptr[len]) != NULL)) { + // After type:// we also include ?, & and = as valid characters, so that + // http://google.com?q=this&that=ok works. + if ((ptr[len] >= 'A' && ptr[len] <= 'Z') + || (ptr[len] >= 'a' && ptr[len] <= 'z')) { + if (in_type && path_is_url((char *)ptr + len + 1)) { + is_url = true; + } + } else { + in_type = false; + } + if (ptr[len] == '\\' && ptr[len + 1] == ' ') { // Skip over the "\" in "\ ". ++len; From b5fc21dbf05874ef7901a5e66f39612c46a698e3 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 21 Aug 2018 12:33:00 -0400 Subject: [PATCH 3/4] vim-patch:8.0.1707: when 'wfh' is set ":bel 10new" scrolls window Problem: When 'wfh' is set ":bel 10new" scrolls window. (Andrew Pyatkov) Solution: Set the fraction before changing the window height. (closes vim/vim#2798) https://github.com/vim/vim/commit/98da6ecab905df48a67da36ce60233f45726c979 --- src/nvim/window.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/nvim/window.c b/src/nvim/window.c index d9903338e8..89ab2c2b9c 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -565,6 +565,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) int before; int minheight; int wmh1; + bool did_set_fraction = false; if (flags & WSP_TOP) oldwin = firstwin; @@ -729,6 +730,11 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) * 'winfixheight' window. Take them from a window above or below * instead, if possible. */ if (oldwin->w_p_wfh) { + // Set w_fraction now so that the cursor keeps the same relative + // vertical position using the old height. + set_fraction(oldwin); + did_set_fraction = true; + win_setheight_win(oldwin->w_height + new_size + STATUS_HEIGHT, oldwin); oldwin_height = oldwin->w_height; @@ -843,7 +849,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) /* Set w_fraction now so that the cursor keeps the same relative * vertical position. */ - set_fraction(oldwin); + if (!did_set_fraction) { + set_fraction(oldwin); + } wp->w_fraction = oldwin->w_fraction; if (flags & WSP_VERT) { From 54e6ef73f058f3e3a340addd6354cf70e2fd11b7 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 21 Aug 2018 22:18:15 -0400 Subject: [PATCH 4/4] vim-patch:8.0.1790: 'winfixwidth' is not always respected by :close Problem: 'winfixwidth' is not always respected by :close. Solution: Prefer a frame without 'winfixwidth' or 'winfixheight'. (Jason Franklin) https://github.com/vim/vim/commit/c136af29c0b1939076fbae7d36afd90dce740315 --- src/nvim/testdir/test_winbuf_close.vim | 36 +++++++++++++++++ src/nvim/window.c | 54 ++++++++++++++++++-------- 2 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/nvim/testdir/test_winbuf_close.vim b/src/nvim/testdir/test_winbuf_close.vim index ed64dd79b7..e4618610cd 100644 --- a/src/nvim/testdir/test_winbuf_close.vim +++ b/src/nvim/testdir/test_winbuf_close.vim @@ -122,3 +122,39 @@ func Test_winbuf_close() call delete('Xtest2') call delete('Xtest3') endfunc + +" Test that ":close" will respect 'winfixheight' when possible. +func Test_winfixheight_on_close() + set nosplitbelow nosplitright + + split | split | vsplit + + $wincmd w + setlocal winfixheight + let l:height = winheight(0) + + 3close + + call assert_equal(l:height, winheight(0)) + + %bwipeout! + setlocal nowinfixheight splitbelow& splitright& +endfunc + +" Test that ":close" will respect 'winfixwidth' when possible. +func Test_winfixwidth_on_close() + set nosplitbelow nosplitright + + vsplit | vsplit | split + + $wincmd w + setlocal winfixwidth + let l:width = winwidth(0) + + 3close + + call assert_equal(l:width, winwidth(0)) + + %bwipeout! + setlocal nowinfixwidth splitbelow& splitright& +endfunction diff --git a/src/nvim/window.c b/src/nvim/window.c index 89ab2c2b9c..3f66568b58 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2337,14 +2337,14 @@ winframe_remove ( return wp; } -/* - * Find out which frame is going to get the freed up space when "win" is - * closed. - * if 'splitbelow'/'splitleft' the space goes to the window above/left. - * if 'nosplitbelow'/'nosplitleft' the space goes to the window below/right. - * This makes opening a window and closing it immediately keep the same window - * layout. - */ +// Return a pointer to the frame that will receive the empty screen space that +// is left over after "win" is closed. +// +// If 'splitbelow' or 'splitright' is set, the space goes above or to the left +// by default. Otherwise, the free space goes below or to the right. The +// result is that opening a window and then immediately closing it will +// preserve the initial window layout. The 'wfh' and 'wfw' settings are +// respected when possible. static frame_T * win_altframe ( win_T *win, @@ -2352,20 +2352,40 @@ win_altframe ( ) { frame_T *frp; - int b; - if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) - /* Last window in this tab page, will go to next tab page. */ + if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) { return alt_tabpage()->tp_curwin->w_frame; + } frp = win->w_frame; - if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW) - b = p_spr; - else - b = p_sb; - if ((!b && frp->fr_next != NULL) || frp->fr_prev == NULL) + + if (frp->fr_prev == NULL) { return frp->fr_next; - return frp->fr_prev; + } + if (frp->fr_next == NULL) { + return frp->fr_prev; + } + + frame_T *target_fr = frp->fr_next; + frame_T *other_fr = frp->fr_prev; + if (p_spr || p_sb) { + target_fr = frp->fr_prev; + other_fr = frp->fr_next; + } + + // If 'wfh' or 'wfw' is set for the target and not for the alternate + // window, reverse the selection. + if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW) { + if (frame_fixed_width(target_fr) && !frame_fixed_width(other_fr)) { + target_fr = other_fr; + } + } else { + if (frame_fixed_height(target_fr) && !frame_fixed_height(other_fr)) { + target_fr = other_fr; + } + } + + return target_fr; } /*