mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 9.1.0208: winfixbuf does not allow to re-edit current buffer
Problem: winfixbuf does not allow to re-edit current buffer (Tim Pope, after v9.1.0147) Solution: Explicitly allow :e even when 'winfixbuf' is set, since it just re-loads the current buffer (Colin Kennedy) fixes: #14237 closes: #14286 Signed-off-by: Colin Kennedy <colinvfx@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
e5f2280381
commit
65e580bd56
@@ -460,6 +460,40 @@ restore_dbg_stuff(struct dbg_stuff *dsp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if ffname differs from fnum.
|
||||||
|
* fnum is a buffer number. 0 == current buffer, 1-or-more must be a valid buffer ID.
|
||||||
|
* ffname is a full path to where a buffer lives on-disk or would live on-disk.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
is_other_file(int fnum, char_u *ffname)
|
||||||
|
{
|
||||||
|
if (fnum != 0)
|
||||||
|
{
|
||||||
|
if (fnum == curbuf->b_fnum)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ffname == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (*ffname == NUL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// TODO: Need a reliable way to know whether a buffer is meant to live on-disk
|
||||||
|
// !curbuf->b_dev_valid is not always available (example: missing on Windows)
|
||||||
|
if (curbuf->b_sfname != NULL
|
||||||
|
&& *curbuf->b_sfname != NUL)
|
||||||
|
// This occurs with unsaved buffers. In which case `ffname`
|
||||||
|
// actually corresponds to curbuf->b_sfname
|
||||||
|
return fnamecmp(ffname, curbuf->b_sfname) != 0;
|
||||||
|
|
||||||
|
return otherfile(ffname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
|
* do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
|
||||||
* command is given.
|
* command is given.
|
||||||
@@ -7256,12 +7290,15 @@ ex_open(exarg_T *eap)
|
|||||||
static void
|
static void
|
||||||
ex_edit(exarg_T *eap)
|
ex_edit(exarg_T *eap)
|
||||||
{
|
{
|
||||||
|
char_u *ffname = eap->cmdidx == CMD_enew ? NULL : eap->arg;
|
||||||
|
|
||||||
// Exclude commands which keep the window's current buffer
|
// Exclude commands which keep the window's current buffer
|
||||||
if (
|
if (
|
||||||
eap->cmdidx != CMD_badd
|
eap->cmdidx != CMD_badd
|
||||||
&& eap->cmdidx != CMD_balt
|
&& eap->cmdidx != CMD_balt
|
||||||
// All other commands must obey 'winfixbuf' / ! rules
|
// All other commands must obey 'winfixbuf' / ! rules
|
||||||
&& !check_can_set_curbuf_forceit(eap->forceit))
|
&& (is_other_file(0, ffname) && !check_can_set_curbuf_forceit(eap->forceit))
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
do_exedit(eap, NULL);
|
do_exedit(eap, NULL);
|
||||||
|
@@ -1125,6 +1125,146 @@ func Test_edit()
|
|||||||
call assert_equal(l:other, bufnr())
|
call assert_equal(l:other, bufnr())
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Fail :e when selecting a buffer from a relative path if in a different folder
|
||||||
|
"
|
||||||
|
" In this tests there's 2 buffers
|
||||||
|
"
|
||||||
|
" foo - lives on disk, in some folder. e.g. /tmp/foo
|
||||||
|
" foo - an in-memory buffer that has not been saved to disk. If saved, it
|
||||||
|
" would live in a different folder, /other/foo.
|
||||||
|
"
|
||||||
|
" The 'winfixbuf' is looking at the in-memory buffer and trying to switch to
|
||||||
|
" the buffer on-disk (and fails, because it's a different buffer)
|
||||||
|
func Test_edit_different_buffer_on_disk_and_relative_path_to_disk()
|
||||||
|
call s:reset_all_buffers()
|
||||||
|
|
||||||
|
let l:file_on_disk = tempname()
|
||||||
|
let l:directory_on_disk1 = fnamemodify(l:file_on_disk, ":p:h")
|
||||||
|
let l:name = fnamemodify(l:file_on_disk, ":t")
|
||||||
|
execute "edit " . l:file_on_disk
|
||||||
|
write!
|
||||||
|
|
||||||
|
let l:directory_on_disk2 = l:directory_on_disk1 . "_something_else"
|
||||||
|
|
||||||
|
if !isdirectory(l:directory_on_disk2)
|
||||||
|
call mkdir(l:directory_on_disk2)
|
||||||
|
endif
|
||||||
|
|
||||||
|
execute "cd " . l:directory_on_disk2
|
||||||
|
execute "edit " l:name
|
||||||
|
|
||||||
|
let l:current = bufnr()
|
||||||
|
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
set winfixbuf
|
||||||
|
call assert_fails("edit " . l:file_on_disk, "E1513:")
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
|
||||||
|
call delete(l:directory_on_disk1)
|
||||||
|
call delete(l:directory_on_disk2)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Fail :e when selecting a buffer from a relative path if in a different folder
|
||||||
|
"
|
||||||
|
" In this tests there's 2 buffers
|
||||||
|
"
|
||||||
|
" foo - lives on disk, in some folder. e.g. /tmp/foo
|
||||||
|
" foo - an in-memory buffer that has not been saved to disk. If saved, it
|
||||||
|
" would live in a different folder, /other/foo.
|
||||||
|
"
|
||||||
|
" The 'winfixbuf' is looking at the on-disk buffer and trying to switch to
|
||||||
|
" the in-memory buffer (and fails, because it's a different buffer)
|
||||||
|
func Test_edit_different_buffer_on_disk_and_relative_path_to_memory()
|
||||||
|
call s:reset_all_buffers()
|
||||||
|
|
||||||
|
let l:file_on_disk = tempname()
|
||||||
|
let l:directory_on_disk1 = fnamemodify(l:file_on_disk, ":p:h")
|
||||||
|
let l:name = fnamemodify(l:file_on_disk, ":t")
|
||||||
|
execute "edit " . l:file_on_disk
|
||||||
|
write!
|
||||||
|
|
||||||
|
let l:directory_on_disk2 = l:directory_on_disk1 . "_something_else"
|
||||||
|
|
||||||
|
if !isdirectory(l:directory_on_disk2)
|
||||||
|
call mkdir(l:directory_on_disk2)
|
||||||
|
endif
|
||||||
|
|
||||||
|
execute "cd " . l:directory_on_disk2
|
||||||
|
execute "edit " l:name
|
||||||
|
execute "cd " . l:directory_on_disk1
|
||||||
|
execute "edit " l:file_on_disk
|
||||||
|
execute "cd " . l:directory_on_disk2
|
||||||
|
|
||||||
|
let l:current = bufnr()
|
||||||
|
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
set winfixbuf
|
||||||
|
call assert_fails("edit " . l:name, "E1513:")
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
|
||||||
|
call delete(l:directory_on_disk1)
|
||||||
|
call delete(l:directory_on_disk2)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Fail to call `:e first` if called from a starting, in-memory buffer
|
||||||
|
func Test_edit_first_buffer()
|
||||||
|
call s:reset_all_buffers()
|
||||||
|
|
||||||
|
set winfixbuf
|
||||||
|
let l:current = bufnr()
|
||||||
|
|
||||||
|
call assert_fails("edit first", "E1513:")
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
|
||||||
|
edit! first
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
edit! somewhere_else
|
||||||
|
call assert_notequal(l:current, bufnr())
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Allow reloading a buffer using :e
|
||||||
|
func Test_edit_no_arguments()
|
||||||
|
call s:reset_all_buffers()
|
||||||
|
|
||||||
|
let l:current = bufnr()
|
||||||
|
file some_buffer
|
||||||
|
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
set winfixbuf
|
||||||
|
edit
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Allow :e selecting the current buffer
|
||||||
|
func Test_edit_same_buffer_in_memory()
|
||||||
|
call s:reset_all_buffers()
|
||||||
|
|
||||||
|
let l:current = bufnr()
|
||||||
|
file same_buffer
|
||||||
|
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
set winfixbuf
|
||||||
|
edit same_buffer
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Allow :e selecting the current buffer as a full path
|
||||||
|
func Test_edit_same_buffer_on_disk_absolute_path()
|
||||||
|
call s:reset_all_buffers()
|
||||||
|
|
||||||
|
let l:file = tempname()
|
||||||
|
let l:current = bufnr()
|
||||||
|
execute "edit " . l:file
|
||||||
|
write!
|
||||||
|
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
set winfixbuf
|
||||||
|
execute "edit " l:file
|
||||||
|
call assert_equal(l:current, bufnr())
|
||||||
|
|
||||||
|
call delete(l:file)
|
||||||
|
endfunc
|
||||||
|
|
||||||
" Fail :enew but :enew! is allowed
|
" Fail :enew but :enew! is allowed
|
||||||
func Test_enew()
|
func Test_enew()
|
||||||
call s:reset_all_buffers()
|
call s:reset_all_buffers()
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
208,
|
||||||
/**/
|
/**/
|
||||||
207,
|
207,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user