aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2019-09-24 22:53:20 -0400
committerJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2019-10-01 22:27:43 -0400
commit17e96d96bac4ea9074a337b263fe85d4755106b6 (patch)
treeaa24ce3db7cfc79e7af4e80c68bed44a0fd491bf
parent8d0bc3c18964db51fec4b204a122e946393f2d6d (diff)
downloadrneovim-17e96d96bac4ea9074a337b263fe85d4755106b6.tar.gz
rneovim-17e96d96bac4ea9074a337b263fe85d4755106b6.tar.bz2
rneovim-17e96d96bac4ea9074a337b263fe85d4755106b6.zip
vim-patch:8.1.0514: CTRL-W ^ does not work when alternate buffer has no name
Problem: CTRL-W ^ does not work when alternate buffer has no name. Solution: Use another method to split and edit the alternate buffer. (Jason Franklin) https://github.com/vim/vim/commit/1bbb61948342b5cf6e363629f145c65eb455c388
-rw-r--r--runtime/doc/windows.txt8
-rw-r--r--src/nvim/normal.c5
-rw-r--r--src/nvim/testdir/test_normal.vim163
-rw-r--r--src/nvim/testdir/test_window_cmd.vim60
-rw-r--r--src/nvim/window.c16
5 files changed, 176 insertions, 76 deletions
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index 76bb096ee3..977e0daef7 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -201,9 +201,11 @@ CTRL-W CTRL_N *CTRL-W_CTRL-N*
|:find|. Doesn't split if {file} is not found.
CTRL-W CTRL-^ *CTRL-W_CTRL-^* *CTRL-W_^*
-CTRL-W ^ Does ":split #", split window in two and edit alternate file.
- When a count is given, it becomes ":split #N", split window
- and edit buffer N.
+CTRL-W ^ Split the current window in two and edit the alternate file.
+ When a count N is given, split the current window and edit
+ buffer N. Similar to ":sp #" and ":sp #N", but it allows the
+ other buffer to be unnamed. This command matches the behavior
+ of |CTRL-^|, except that it splits a window first.
CTRL-W ge *CTRL-W_ge*
Detach the current window as an external window.
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 6b76082772..e32b738c7e 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -4680,9 +4680,8 @@ static void nv_ctrlo(cmdarg_T *cap)
}
}
-/*
- * CTRL-^ command, short for ":e #"
- */
+// CTRL-^ command, short for ":e #". Works even when the alternate buffer is
+// not named.
static void nv_hat(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap))
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
index 0c71e2af4c..b3e43640bb 100644
--- a/src/nvim/testdir/test_normal.vim
+++ b/src/nvim/testdir/test_normal.vim
@@ -2,12 +2,12 @@
source shared.vim
-func! Setup_NewWindow()
+func Setup_NewWindow()
10new
call setline(1, range(1,100))
endfunc
-func! MyFormatExpr()
+func MyFormatExpr()
" Adds '->$' at lines having numbers followed by trailing whitespace
for ln in range(v:lnum, v:lnum+v:count-1)
let line = getline(ln)
@@ -17,7 +17,7 @@ func! MyFormatExpr()
endfor
endfunc
-func! CountSpaces(type, ...)
+func CountSpaces(type, ...)
" for testing operatorfunc
" will count the number of spaces
" and return the result in g:a
@@ -37,7 +37,7 @@ func! CountSpaces(type, ...)
let @@ = reg_save
endfunc
-func! OpfuncDummy(type, ...)
+func OpfuncDummy(type, ...)
" for testing operatorfunc
let g:opt=&linebreak
@@ -81,7 +81,7 @@ fun! Test_normal00_optrans()
bw!
endfunc
-func! Test_normal01_keymodel()
+func Test_normal01_keymodel()
call Setup_NewWindow()
" Test 1: depending on 'keymodel' <s-down> does something different
50
@@ -115,7 +115,7 @@ func! Test_normal01_keymodel()
bw!
endfunc
-func! Test_normal02_selectmode()
+func Test_normal02_selectmode()
" some basic select mode tests
call Setup_NewWindow()
50
@@ -129,7 +129,7 @@ func! Test_normal02_selectmode()
bw!
endfunc
-func! Test_normal02_selectmode2()
+func Test_normal02_selectmode2()
" some basic select mode tests
call Setup_NewWindow()
50
@@ -139,7 +139,7 @@ func! Test_normal02_selectmode2()
bw!
endfunc
-func! Test_normal03_join()
+func Test_normal03_join()
" basic join test
call Setup_NewWindow()
50
@@ -159,7 +159,7 @@ func! Test_normal03_join()
bw!
endfunc
-func! Test_normal04_filter()
+func Test_normal04_filter()
" basic filter test
" only test on non windows platform
if has('win32')
@@ -185,7 +185,7 @@ func! Test_normal04_filter()
bw!
endfunc
-func! Test_normal05_formatexpr()
+func Test_normal05_formatexpr()
" basic formatexpr test
call Setup_NewWindow()
%d_
@@ -222,7 +222,7 @@ func Test_normal05_formatexpr_setopt()
set formatexpr=
endfunc
-func! Test_normal06_formatprg()
+func Test_normal06_formatprg()
" basic test for formatprg
" only test on non windows platform
if has('win32')
@@ -256,7 +256,7 @@ func! Test_normal06_formatprg()
call delete('Xsed_format.sh')
endfunc
-func! Test_normal07_internalfmt()
+func Test_normal07_internalfmt()
" basic test for internal formmatter to textwidth of 12
let list=range(1,11)
call map(list, 'v:val." "')
@@ -270,7 +270,7 @@ func! Test_normal07_internalfmt()
bw!
endfunc
-func! Test_normal08_fold()
+func Test_normal08_fold()
" basic tests for foldopen/folddelete
if !has("folding")
return
@@ -329,7 +329,7 @@ func! Test_normal08_fold()
bw!
endfunc
-func! Test_normal09_operatorfunc()
+func Test_normal09_operatorfunc()
" Test operatorfunc
call Setup_NewWindow()
" Add some spaces for counting
@@ -359,7 +359,7 @@ func! Test_normal09_operatorfunc()
bw!
endfunc
-func! Test_normal09a_operatorfunc()
+func Test_normal09a_operatorfunc()
" Test operatorfunc
call Setup_NewWindow()
" Add some spaces for counting
@@ -385,7 +385,7 @@ func! Test_normal09a_operatorfunc()
unlet! g:opt
endfunc
-func! Test_normal10_expand()
+func Test_normal10_expand()
" Test for expand()
10new
call setline(1, ['1', 'ifooar,,cbar'])
@@ -420,7 +420,7 @@ func! Test_normal10_expand()
bw!
endfunc
-func! Test_normal11_showcmd()
+func Test_normal11_showcmd()
" test for 'showcmd'
10new
exe "norm! ofoobar\<esc>"
@@ -435,7 +435,7 @@ func! Test_normal11_showcmd()
bw!
endfunc
-func! Test_normal12_nv_error()
+func Test_normal12_nv_error()
" Test for nv_error
10new
call setline(1, range(1,5))
@@ -445,7 +445,7 @@ func! Test_normal12_nv_error()
bw!
endfunc
-func! Test_normal13_help()
+func Test_normal13_help()
" Test for F1
call assert_equal(1, winnr())
call feedkeys("\<f1>", 'txi')
@@ -454,7 +454,7 @@ func! Test_normal13_help()
bw!
endfunc
-func! Test_normal14_page()
+func Test_normal14_page()
" basic test for Ctrl-F and Ctrl-B
call Setup_NewWindow()
exe "norm! \<c-f>"
@@ -488,7 +488,7 @@ func! Test_normal14_page()
bw!
endfunc
-func! Test_normal14_page_eol()
+func Test_normal14_page_eol()
10new
norm oxxxxxxx
exe "norm 2\<c-f>"
@@ -497,7 +497,7 @@ func! Test_normal14_page_eol()
bw!
endfunc
-func! Test_normal15_z_scroll_vert()
+func Test_normal15_z_scroll_vert()
" basic test for z commands that scroll the window
call Setup_NewWindow()
100
@@ -586,7 +586,7 @@ func! Test_normal15_z_scroll_vert()
bw!
endfunc
-func! Test_normal16_z_scroll_hor()
+func Test_normal16_z_scroll_hor()
" basic test for z commands that scroll the window
10new
15vsp
@@ -652,7 +652,7 @@ func! Test_normal16_z_scroll_hor()
bw!
endfunc
-func! Test_normal17_z_scroll_hor2()
+func Test_normal17_z_scroll_hor2()
" basic test for z commands that scroll the window
" using 'sidescrolloff' setting
10new
@@ -719,7 +719,7 @@ func! Test_normal17_z_scroll_hor2()
bw!
endfunc
-func! Test_normal18_z_fold()
+func Test_normal18_z_fold()
" basic tests for foldopen/folddelete
if !has("folding")
return
@@ -1090,7 +1090,7 @@ func! Test_normal18_z_fold()
bw!
endfunc
-func! Test_normal19_z_spell()
+func Test_normal19_z_spell()
if !has("spell") || !has('syntax')
return
endif
@@ -1245,7 +1245,7 @@ func! Test_normal19_z_spell()
bw!
endfunc
-func! Test_normal20_exmode()
+func Test_normal20_exmode()
if !has("unix")
" Reading from redirected file doesn't work on MS-Windows
return
@@ -1263,24 +1263,38 @@ func! Test_normal20_exmode()
bw!
endfunc
-func! Test_normal21_nv_hat()
- set hidden
- new
- " to many buffers opened already, will not work
- "call assert_fails(":b#", 'E23')
- "call assert_equal('', @#)
- e Xfoobar
- e Xfile2
- call feedkeys("\<c-^>", 't')
- call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t'))
- call feedkeys("f\<c-^>", 't')
- call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t'))
- " clean up
- set nohidden
- bw!
+func Test_normal21_nv_hat()
+
+ " Edit a fresh file and wipe the buffer list so that there is no alternate
+ " file present. Next, check for the expected command failures.
+ edit Xfoo | %bw
+ call assert_fails(':buffer #', 'E86')
+ call assert_fails(':execute "normal! \<C-^>"', 'E23')
+
+ " Test for the expected behavior when switching between two named buffers.
+ edit Xfoo | edit Xbar
+ call feedkeys("\<C-^>", 'tx')
+ call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
+ call feedkeys("\<C-^>", 'tx')
+ call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
+
+ " Test for the expected behavior when only one buffer is named.
+ enew | let l:nr = bufnr('%')
+ call feedkeys("\<C-^>", 'tx')
+ call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
+ call feedkeys("\<C-^>", 'tx')
+ call assert_equal('', bufname('%'))
+ call assert_equal(l:nr, bufnr('%'))
+
+ " Test that no action is taken by "<C-^>" when an operator is pending.
+ edit Xfoo
+ call feedkeys("ci\<C-^>", 'tx')
+ call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
+
+ %bw!
endfunc
-func! Test_normal22_zet()
+func Test_normal22_zet()
" Test for ZZ
" let shell = &shell
" let &shell = 'sh'
@@ -1308,7 +1322,7 @@ func! Test_normal22_zet()
" let &shell = shell
endfunc
-func! Test_normal23_K()
+func Test_normal23_K()
" Test for K command
new
call append(0, ['helphelp.txt', 'man', 'aa%bb', 'cc|dd'])
@@ -1373,7 +1387,7 @@ func! Test_normal23_K()
bw!
endfunc
-func! Test_normal24_rot13()
+func Test_normal24_rot13()
" Testing for g?? g?g?
new
call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
@@ -1387,7 +1401,7 @@ func! Test_normal24_rot13()
bw!
endfunc
-func! Test_normal25_tag()
+func Test_normal25_tag()
" Testing for CTRL-] g CTRL-] g]
" CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
h
@@ -1454,7 +1468,7 @@ func! Test_normal25_tag()
helpclose
endfunc
-func! Test_normal26_put()
+func Test_normal26_put()
" Test for ]p ]P [p and [P
new
call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
@@ -1473,7 +1487,7 @@ func! Test_normal26_put()
bw!
endfunc
-func! Test_normal27_bracket()
+func Test_normal27_bracket()
" Test for [' [` ]' ]`
call Setup_NewWindow()
1,21s/.\+/ & b/
@@ -1524,7 +1538,7 @@ func! Test_normal27_bracket()
bw!
endfunc
-func! Test_normal28_parenthesis()
+func Test_normal28_parenthesis()
" basic testing for ( and )
new
call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
@@ -1718,7 +1732,7 @@ fun! Test_normal31_r_cmd()
bw!
endfunc
-func! Test_normal32_g_cmd1()
+func Test_normal32_g_cmd1()
" Test for g*, g#
new
call append(0, ['abc.x_foo', 'x_foobar.abc'])
@@ -1849,7 +1863,7 @@ fun! Test_normal33_g_cmd2()
bw!
endfunc
-func! Test_g_ctrl_g()
+func Test_g_ctrl_g()
new
let a = execute(":norm! g\<c-g>")
@@ -2139,7 +2153,7 @@ fun! Test_normal41_insert_reg()
bw!
endfunc
-func! Test_normal42_halfpage()
+func Test_normal42_halfpage()
" basic test for Ctrl-D and Ctrl-U
call Setup_NewWindow()
call assert_equal(5, &scroll)
@@ -2207,7 +2221,7 @@ fun! Test_normal43_textobject1()
bw!
endfunc
-func! Test_normal44_textobjects2()
+func Test_normal44_textobjects2()
" basic testing for is and as text objects
new
call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
@@ -2262,7 +2276,7 @@ func! Test_normal44_textobjects2()
bw!
endfunc
-func! Test_normal45_drop()
+func Test_normal45_drop()
if !has('dnd')
" The ~ register does not exist
call assert_beeps('norm! "~')
@@ -2280,7 +2294,7 @@ func! Test_normal45_drop()
bw!
endfunc
-func! Test_normal46_ignore()
+func Test_normal46_ignore()
new
" How to test this?
" let's just for now test, that the buffer
@@ -2299,7 +2313,7 @@ func! Test_normal46_ignore()
bw!
endfunc
-func! Test_normal47_visual_buf_wipe()
+func Test_normal47_visual_buf_wipe()
" This was causing a crash or ml_get error.
enew!
call setline(1,'xxx')
@@ -2313,7 +2327,7 @@ func! Test_normal47_visual_buf_wipe()
set nomodified
endfunc
-func! Test_normal47_autocmd()
+func Test_normal47_autocmd()
" disabled, does not seem to be possible currently
throw "Skipped: not possible to test cursorhold autocmd while waiting for input in normal_cmd"
new
@@ -2331,14 +2345,14 @@ func! Test_normal47_autocmd()
bw!
endfunc
-func! Test_normal48_wincmd()
+func Test_normal48_wincmd()
new
exe "norm! \<c-w>c"
call assert_equal(1, winnr('$'))
call assert_fails(":norm! \<c-w>c", "E444")
endfunc
-func! Test_normal49_counts()
+func Test_normal49_counts()
new
call setline(1, 'one two three four five six seven eight nine ten')
1
@@ -2347,7 +2361,7 @@ func! Test_normal49_counts()
bw!
endfunc
-func! Test_normal50_commandline()
+func Test_normal50_commandline()
if !has("timers") || !has("cmdline_hist") || !has("vertsplit")
return
endif
@@ -2378,7 +2392,7 @@ func! Test_normal50_commandline()
bw!
endfunc
-func! Test_normal51_FileChangedRO()
+func Test_normal51_FileChangedRO()
if !has("autocmd")
return
endif
@@ -2395,7 +2409,7 @@ func! Test_normal51_FileChangedRO()
call delete("Xreadonly.log")
endfunc
-func! Test_normal52_rl()
+func Test_normal52_rl()
if !has("rightleft")
return
endif
@@ -2428,7 +2442,7 @@ func! Test_normal52_rl()
bw!
endfunc
-func! Test_normal53_digraph()
+func Test_normal53_digraph()
if !has('digraphs')
return
endif
@@ -2516,6 +2530,29 @@ func Test_changelist()
let &ul = save_ul
endfunc
+func Test_nv_hat_count()
+ %bwipeout!
+ let l:nr = bufnr('%') + 1
+ call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92')
+
+ edit Xfoo
+ let l:foo_nr = bufnr('Xfoo')
+
+ edit Xbar
+ let l:bar_nr = bufnr('Xbar')
+
+ " Make sure we are not just using the alternate file.
+ edit Xbaz
+
+ call feedkeys(l:foo_nr . "\<C-^>", 'tx')
+ call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
+
+ call feedkeys(l:bar_nr . "\<C-^>", 'tx')
+ call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
+
+ %bwipeout!
+endfunc
+
func Test_delete_until_paragraph()
new
normal grádv}
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
index c87c0a0af4..9f899fba04 100644
--- a/src/nvim/testdir/test_window_cmd.vim
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -117,15 +117,65 @@ func Test_window_vertical_split()
bw
endfunc
+" Test the ":wincmd ^" and "<C-W>^" commands.
func Test_window_split_edit_alternate()
- e Xa
- e Xb
+ " Test for failure when the alternate buffer/file no longer exists.
+ edit Xfoo | %bw
+ call assert_fails(':wincmd ^', 'E23')
+
+ " Test for the expected behavior when we have two named buffers.
+ edit Xfoo | edit Xbar
wincmd ^
- call assert_equal('Xa', bufname(winbufnr(1)))
- call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xfoo', bufname(winbufnr(1)))
+ call assert_equal('Xbar', bufname(winbufnr(2)))
+ only
- bw Xa Xb
+ " Test for the expected behavior when the alternate buffer is not named.
+ enew | let l:nr1 = bufnr('%')
+ edit Xfoo | let l:nr2 = bufnr('%')
+ wincmd ^
+ call assert_equal(l:nr1, winbufnr(1))
+ call assert_equal(l:nr2, winbufnr(2))
+ only
+
+ " Test the Normal mode command.
+ call feedkeys("\<C-W>\<C-^>", 'tx')
+ call assert_equal(l:nr2, winbufnr(1))
+ call assert_equal(l:nr1, winbufnr(2))
+
+ %bw!
+endfunc
+
+" Test the ":[count]wincmd ^" and "[count]<C-W>^" commands.
+func Test_window_split_edit_bufnr()
+
+ %bwipeout
+ let l:nr = bufnr('%') + 1
+ call assert_fails(':execute "normal! ' . l:nr . '\<C-W>\<C-^>"', 'E92')
+ call assert_fails(':' . l:nr . 'wincmd ^', 'E16')
+ call assert_fails(':0wincmd ^', 'E16')
+
+ edit Xfoo | edit Xbar | edit Xbaz
+ let l:foo_nr = bufnr('Xfoo')
+ let l:bar_nr = bufnr('Xbar')
+ let l:baz_nr = bufnr('Xbaz')
+
+ call feedkeys(l:foo_nr . "\<C-W>\<C-^>", 'tx')
+ call assert_equal('Xfoo', bufname(winbufnr(1)))
+ call assert_equal('Xbaz', bufname(winbufnr(2)))
+ only
+
+ call feedkeys(l:bar_nr . "\<C-W>\<C-^>", 'tx')
+ call assert_equal('Xbar', bufname(winbufnr(1)))
+ call assert_equal('Xfoo', bufname(winbufnr(2)))
+ only
+
+ execute l:baz_nr . 'wincmd ^'
+ call assert_equal('Xbaz', bufname(winbufnr(1)))
+ call assert_equal('Xbar', bufname(winbufnr(2)))
+
+ %bw!
endfunc
func Test_window_preview()
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 1e6de73549..d7df048588 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -131,8 +131,20 @@ do_window (
case '^':
CHECK_CMDWIN;
reset_VIsual_and_resel(); // stop Visual mode
- cmd_with_count("split #", (char_u *)cbuf, sizeof(cbuf), Prenum);
- do_cmdline_cmd(cbuf);
+
+ if (buflist_findnr(Prenum == 0 ? curwin->w_alt_fnum : Prenum) == NULL) {
+ if (Prenum == 0) {
+ EMSG(_(e_noalt));
+ } else {
+ EMSGN(_("E92: Buffer %" PRId64 " not found"), Prenum);
+ }
+ break;
+ }
+
+ if (!curbuf_locked() && win_split(0, 0) == OK) {
+ (void)buflist_getfile(Prenum == 0 ? curwin->w_alt_fnum : Prenum,
+ (linenr_T)0, GETF_ALT, false);
+ }
break;
/* open new window */