Bram et al.,

I noticed this week that Ctrl-^ and Ctrl-W-Ctrl-^ are not consistent in their
behavior when the alternate file is not named.  The former works as expected,
and the latter fails.  This was a tad annoying.

Example:
vim --clean
:e Xfoo
:enew
<C-^><C-^><C-^> " works fine
<C-W><C-^> " fails to split window on other buffer

With this patch, <C-W><C-^> will work just like <C-^> but it will split
a window first (with some sanity/error checking before it does so).

I also included MANY test cases.  Before these patches, these commands weren't
tested very well at all.

Best,
Jason Franklin

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
>From 999a274db45d754979ed0fdaf3a747beafdcbf6f Mon Sep 17 00:00:00 2001
From: Jason Franklin <[email protected]>
Date: Fri, 9 Nov 2018 13:56:07 -0500
Subject: [PATCH 1/7] Improve the test for the "<C-^>" command

The test that was in use did not use 'tx' in the "feedkeys()"
function calls.  This meant that the functionality of interest
wasn't being tested.

I also added a couple of cases that weren't examined previously.
---
 src/testdir/test_normal.vim | 42 ++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index a06426e8e..de6c25808 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -1260,20 +1260,34 @@ func! Test_normal20_exmode()
 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!
+
+  " 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()
-- 
2.17.1


>From 1f40cc9f17226b7dfec7d9512235f306f60fc178 Mon Sep 17 00:00:00 2001
From: Jason Franklin <[email protected]>
Date: Fri, 9 Nov 2018 14:48:54 -0500
Subject: [PATCH 2/7] Add a failing test for ":wincmd ^"

The test for ":wincmd ^" now fails for the case where the alternate
buffer is not named.  This is the case that will be addressed in the
next commit.
---
 src/testdir/test_window_cmd.vim | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim
index 423d6f8d2..c1e3d0a1b 100644
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -104,14 +104,26 @@ func Test_window_vertical_split()
 endfunc
 
 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))
+
+  %bw!
 endfunc
 
 func Test_window_preview()
@@ -322,7 +334,7 @@ func Test_equalalways_on_close()
   set equalalways
   vsplit
   windo split
-  split 
+  split
   wincmd J
   " now we have a frame top-left with two windows, a frame top-right with two
   " windows and a frame at the bottom, full-width.
-- 
2.17.1


>From 874815d2de6445700130ae7dd58944122b64810d Mon Sep 17 00:00:00 2001
From: Jason Franklin <[email protected]>
Date: Fri, 9 Nov 2018 15:04:07 -0500
Subject: [PATCH 3/7] Allow ":wincmd ^" to work with a [No Name] buffer

---
 src/normal.c |  3 ++-
 src/window.c | 12 ++++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/normal.c b/src/normal.c
index 4c157004a..a0683b207 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -5496,7 +5496,8 @@ 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)
diff --git a/src/window.c b/src/window.c
index e16570f4e..be942884d 100644
--- a/src/window.c
+++ b/src/window.c
@@ -151,8 +151,16 @@ do_window(
     case '^':
 		CHECK_CMDWIN;
 		reset_VIsual_and_resel();	/* stop Visual mode */
-		cmd_with_count("split #", cbuf, sizeof(cbuf), Prenum);
-		do_cmdline_cmd(cbuf);
+
+		if (buflist_findnr(curwin->w_alt_fnum) == NULL)
+		{
+		    EMSG(_(e_noalt));
+		    break;
+		}
+
+		if (!curbuf_locked() && win_split(0, 0) == OK)
+		    (void) buflist_getfile(curwin->w_alt_fnum, (linenr_T) 0, GETF_ALT, FALSE);
+
 		break;
 
 /* open new window */
-- 
2.17.1


>From 2fb244b47d2ffef3647512bc80ad97e5703a90e4 Mon Sep 17 00:00:00 2001
From: Jason Franklin <[email protected]>
Date: Sat, 10 Nov 2018 06:55:24 -0500
Subject: [PATCH 4/7] Add a test for the [count]<C-^> command

---
 src/testdir/test_normal.vim | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index de6c25808..e5b06a94c 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -2461,7 +2461,7 @@ func! Test_normal53_digraph()
   bw!
 endfunc
 
-func Test_normal54_Ctrl_bsl()
+func! Test_normal54_Ctrl_bsl()
   new
   call setline(1, 'abcdefghijklmn')
   exe "norm! df\<c-\>\<c-n>"
@@ -2485,7 +2485,7 @@ func Test_normal54_Ctrl_bsl()
   bw!
 endfunc
 
-func Test_normal_large_count()
+func! Test_normal_large_count()
   " This may fail with 32bit long, how do we detect that?
   new
   normal o
@@ -2493,7 +2493,7 @@ func Test_normal_large_count()
   bwipe!
 endfunc
 
-func Test_delete_until_paragraph()
+func! Test_delete_until_paragraph()
   if !has('multi_byte')
     return
   endif
@@ -2507,7 +2507,7 @@ endfunc
 
 " Test for the gr (virtual replace) command
 " Test for the bug fixed by 7.4.387
-func Test_gr_command()
+func! Test_gr_command()
   enew!
   let save_cpo = &cpo
   call append(0, ['First line', 'Second line', 'Third line'])
@@ -2527,7 +2527,7 @@ endfunc
 " When splitting a window the changelist position is wrong.
 " Test the changelist position after splitting a window.
 " Test for the bug fixed by 7.4.386
-func Test_changelist()
+func! Test_changelist()
   let save_ul = &ul
   enew!
   call append('$', ['1', '2'])
@@ -2546,3 +2546,27 @@ func Test_changelist()
   %bwipe!
   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
-- 
2.17.1


>From 39e24747628bcd33be4b676839323dfd14ee2d2e Mon Sep 17 00:00:00 2001
From: Jason Franklin <[email protected]>
Date: Sat, 10 Nov 2018 07:37:06 -0500
Subject: [PATCH 5/7] Add tests for :[count]wincmd ^ and [count]<C-W>^

---
 src/testdir/test_window_cmd.vim | 38 +++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim
index c1e3d0a1b..a60986810 100644
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -103,6 +103,7 @@ func Test_window_vertical_split()
   bw
 endfunc
 
+" Test the ":wincmd ^" and "<C-W>^" commands.
 func Test_window_split_edit_alternate()
 
   " Test for failure when the alternate buffer/file no longer exists.
@@ -122,6 +123,43 @@ func Test_window_split_edit_alternate()
   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
-- 
2.17.1


>From d6103602a13561264cdfa679e0a29cd4212e908a Mon Sep 17 00:00:00 2001
From: Jason Franklin <[email protected]>
Date: Sat, 10 Nov 2018 07:42:30 -0500
Subject: [PATCH 6/7] Restore the functionality of [count]<C-W>^

---
 src/window.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/window.c b/src/window.c
index be942884d..3f854dff4 100644
--- a/src/window.c
+++ b/src/window.c
@@ -152,14 +152,18 @@ do_window(
 		CHECK_CMDWIN;
 		reset_VIsual_and_resel();	/* stop Visual mode */
 
-		if (buflist_findnr(curwin->w_alt_fnum) == NULL)
+		if (buflist_findnr(Prenum == 0 ? curwin->w_alt_fnum : Prenum) == NULL)
 		{
-		    EMSG(_(e_noalt));
+		    if (Prenum == 0)
+			EMSG(_(e_noalt));
+		    if (Prenum != 0)
+			EMSGN(_("E92: Buffer %ld not found"), Prenum);
 		    break;
 		}
 
 		if (!curbuf_locked() && win_split(0, 0) == OK)
-		    (void) buflist_getfile(curwin->w_alt_fnum, (linenr_T) 0, GETF_ALT, FALSE);
+		    (void) buflist_getfile(Prenum == 0 ? curwin->w_alt_fnum : Prenum,
+			    (linenr_T) 0, GETF_ALT, FALSE);
 
 		break;
 
-- 
2.17.1


>From a876b24407500a93c4751fff0c15a6b852e974e9 Mon Sep 17 00:00:00 2001
From: Jason Franklin <[email protected]>
Date: Sat, 10 Nov 2018 07:53:23 -0500
Subject: [PATCH 7/7] Update the documentation

---
 runtime/doc/windows.txt | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index 824efe709..90a178900 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -222,9 +222,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_:*
 CTRL-W :	Does the same as typing |:| - enter a command line.  Useful in a
-- 
2.17.1

Raspunde prin e-mail lui