vim-patch:8.0.1763: :argedit does not reuse an empty unnamed buffer

Problem:    :argedit does not reuse an empty unnamed buffer.
Solution:   Add the BLN_CURBUF flag and fix all the side effects. (Christian Brabandt)

46a53dfc29
This commit is contained in:
Marco Hinz 2019-04-08 19:50:36 +02:00
parent 5a81561e7a
commit a8d0062c67
No known key found for this signature in database
GPG Key ID: 1C980A1B657B4A4F
4 changed files with 31 additions and 9 deletions

View File

@ -1717,11 +1717,7 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
* buffer.) * buffer.)
*/ */
buf = NULL; buf = NULL;
if ((flags & BLN_CURBUF) if ((flags & BLN_CURBUF) && curbuf_reusable()) {
&& curbuf != NULL
&& curbuf->b_ffname == NULL
&& curbuf->b_nwindows <= 1
&& (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY())) {
buf = curbuf; buf = curbuf;
/* It's like this buffer is deleted. Watch out for autocommands that /* It's like this buffer is deleted. Watch out for autocommands that
* change curbuf! If that happens, allocate a new buffer anyway. */ * change curbuf! If that happens, allocate a new buffer anyway. */
@ -1864,6 +1860,17 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
return buf; return buf;
} }
/// Return true if the current buffer is empty, unnamed, unmodified and used in
/// only one window. That means it can be reused.
bool curbuf_reusable(void)
{
return (curbuf != NULL
&& curbuf->b_ffname == NULL
&& curbuf->b_nwindows <= 1
&& (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY())
&& !curbufIsChanged());
}
/* /*
* Free the memory for the options of a buffer. * Free the memory for the options of a buffer.
* If "free_p_ff" is true also free 'fileformat', 'buftype' and * If "free_p_ff" is true also free 'fileformat', 'buftype' and

View File

@ -1952,14 +1952,17 @@ void ex_next(exarg_T *eap)
void ex_argedit(exarg_T *eap) void ex_argedit(exarg_T *eap)
{ {
int i = eap->addr_count ? (int)eap->line2 : curwin->w_arg_idx + 1; int i = eap->addr_count ? (int)eap->line2 : curwin->w_arg_idx + 1;
// Whether curbuf will be reused, curbuf->b_ffname will be set.
bool curbuf_is_reusable = curbuf_reusable();
if (do_arglist(eap->arg, AL_ADD, i) == FAIL) { if (do_arglist(eap->arg, AL_ADD, i) == FAIL) {
return; return;
} }
maketitle(); maketitle();
if (curwin->w_arg_idx == 0 && (curbuf->b_ml.ml_flags & ML_EMPTY) if (curwin->w_arg_idx == 0
&& curbuf->b_ffname == NULL) { && (curbuf->b_ml.ml_flags & ML_EMPTY)
&& (curbuf->b_ffname == NULL || curbuf_is_reusable)) {
i = 0; i = 0;
} }
// Edit the argument. // Edit the argument.
@ -2257,7 +2260,8 @@ static int alist_add_list(int count, char_u **files, int after)
} }
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
ARGLIST[after + i].ae_fname = files[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; ALIST(curwin)->al_ga.ga_len += count;
if (old_argcount > 0 && curwin->w_arg_idx >= after) { if (old_argcount > 0 && curwin->w_arg_idx >= after) {

View File

@ -329,6 +329,18 @@ func Test_argedit()
%argd %argd
bwipe! C bwipe! C
bwipe! D 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 endfunc
" Test for the :argdelete command " Test for the :argdelete command

View File

@ -173,7 +173,6 @@ func Test_command_count_4()
only! only!
exe bufnr . 'buf' exe bufnr . 'buf'
bnext
let bufnr = bufnr('%') let bufnr = bufnr('%')
let buffers = [] let buffers = []
.,$-bufdo call add(buffers, bufnr('%')) .,$-bufdo call add(buffers, bufnr('%'))