On Mi, 28 Mär 2018, Bram Moolenaar wrote:

> A test would be nice...

As mentioned before this simple patch is wrong. It turned out to be 
slightly more effort to make this work. And once this was changed a 
couple of other tests failed that would need to be adjusted or had to be 
accounted for in the source. So finally I think I have a patch that 
works correctly and is attached to this mail (only visible to the 
mailinglist, github won't receive it).

The reasoning for all the changes is in the commit message of the 
attached patch.

Best,
Christian
-- 
Dummheit ist ansteckend, Verstand wächst sich kaum zur Epidemie aus.
                -- Kazimierz Bartoszewicz

-- 
-- 
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 0e6c7278b6a820799f1bcd303b379a2b4ab9857e Mon Sep 17 00:00:00 2001
From: Christian Brabandt <[email protected]>
Date: Thu, 29 Mar 2018 11:02:07 +0200
Subject: [PATCH] Make :argedit reuse the current buffer if it is empty

When running `:argedit` Vim would create a new buffer even if the current
buffer was empty and unmodified, because in `alist_add_list()` only the flag
`BLN_LISTED` was given and not the flag `BLN_CURBUF`.

In order to make Vim reuse the current buffer, add the flag `BLN_CURBUF`
to the call and add a test to testdir/test_arglist.vim.

However, changing that broke ex_argedit further down, because
if the current buffer was unused and empty, `curbuf->b_ffname` would not
be NULL anymore so the call to `do_argfile()` would never happen.

So also call `do_argfile` if curbuf was empty before the `do_arglist`
call. To do so, the logic to determine whether the current buffer can be
reused was refactored into a new function `curbuf_empty()`.

After that, the `test_arglist` broke, because it was doing an implicit
`enew|:set modified|argedit` call and expected to receive an E37 error
message for trying to change a current modified buffer. Therefore add
a test for the current buffer being modified to the check in
`curbuf_empty()`

That fixed the failure in test_arglist, but now the test_command_count
broke. That was because it implicitly expected the first buffer to be
the empty buffer '[No Name]' and added a call to `:bnext` to account for
that. However that one is not needed anymore and would make the test
fail since the initial empty buffer was not used anymore. So adjust that
test as well and remove the now superflous :bnext call.
---
 src/buffer.c                       | 19 ++++++++++++++-----
 src/ex_cmds2.c                     |  9 +++++++--
 src/proto/buffer.pro               |  1 +
 src/testdir/test_arglist.vim       | 11 +++++++++++
 src/testdir/test_command_count.vim |  1 -
 5 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/buffer.c b/src/buffer.c
index 7bd3cdf01..aa7406635 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1842,6 +1842,19 @@ no_write_message_nobang(buf_T *buf UNUSED)
 
 static int  top_file_num = 1;		/* highest file number */
 
+/*
+ * return true, if the current buffer is empty and can be reused
+ */
+    int
+curbuf_empty(void)
+{
+    return (curbuf != NULL
+	&& curbuf->b_ffname == NULL
+	&& curbuf->b_nwindows <= 1
+	&& (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY())
+	&& !curbufIsChanged());
+}
+
 /*
  * Add a file name to the buffer list.  Return a pointer to the buffer.
  * If the same file name already exists return a pointer to that buffer.
@@ -1922,11 +1935,7 @@ buflist_new(
      * buffer.)
      */
     buf = NULL;
-    if ((flags & BLN_CURBUF)
-	    && curbuf != NULL
-	    && curbuf->b_ffname == NULL
-	    && curbuf->b_nwindows <= 1
-	    && (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY()))
+    if ((flags & BLN_CURBUF) && curbuf_empty())
     {
 	buf = curbuf;
 	/* It's like this buffer is deleted.  Watch out for autocommands that
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index ae4ce337d..313a06a0e 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -2958,8 +2958,13 @@ ex_next(exarg_T *eap)
     void
 ex_argedit(exarg_T *eap)
 {
+    /* if curbuf is unused, it will be reused,
+     * but then curbuf->b_ffname will be set */
+    int curbuf_is_empty;
     int i = eap->addr_count ? (int)eap->line2 : curwin->w_arg_idx + 1;
 
+    curbuf_is_empty = curbuf_empty();
+
     if (do_arglist(eap->arg, AL_ADD, i) == FAIL)
 	return;
 #ifdef FEAT_TITLE
@@ -2967,7 +2972,7 @@ ex_argedit(exarg_T *eap)
 #endif
 
     if (curwin->w_arg_idx == 0 && (curbuf->b_ml.ml_flags & ML_EMPTY)
-	    && curbuf->b_ffname == NULL)
+	    && (curbuf->b_ffname == NULL || curbuf_is_empty))
 	i = 0;
     /* Edit the argument. */
     if (i < ARGCOUNT)
@@ -3299,7 +3304,7 @@ alist_add_list(
 	for (i = 0; i < count; ++i)
 	{
 	    ARGLIST[after + i].ae_fname = files[i];
-	    ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
+	    ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED | BLN_CURBUF);
 	}
 	ALIST(curwin)->al_ga.ga_len += count;
 	if (old_argcount > 0 && curwin->w_arg_idx >= after)
diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro
index 8b9884354..e8f98aa47 100644
--- a/src/proto/buffer.pro
+++ b/src/proto/buffer.pro
@@ -15,6 +15,7 @@ void enter_buffer(buf_T *buf);
 void do_autochdir(void);
 void no_write_message(void);
 void no_write_message_nobang(buf_T *buf);
+int curbuf_empty(void);
 buf_T *buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags);
 void free_buf_options(buf_T *buf, int free_p_ff);
 int buflist_getfile(int n, linenr_T lnum, int options, int forceit);
diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim
index 19d0cee47..dc5eb7345 100644
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -280,6 +280,17 @@ func Test_argedit()
   %argd
   bwipe! C
   bwipe! D
+  " :argedit reuses the current buffer if it is empty
+  %argd
+  " make sure to use a new buffer number for x when it is loaded
+  bw! x
+  new
+  let a=bufnr('')
+  argedit x
+  call assert_equal(a, bufnr(''))
+  call assert_equal('x', bufname(''))
+  %argd
+  bw! x
 endfunc
 
 " Test for the :argdelete command
diff --git a/src/testdir/test_command_count.vim b/src/testdir/test_command_count.vim
index 2d793ed88..7262789ab 100644
--- a/src/testdir/test_command_count.vim
+++ b/src/testdir/test_command_count.vim
@@ -173,7 +173,6 @@ func Test_command_count_4()
   only!
 
   exe bufnr . 'buf'
-  bnext
   let bufnr = bufnr('%')
   let buffers = []
   .,$-bufdo call add(buffers, bufnr('%'))
-- 
2.16.1

Raspunde prin e-mail lui