mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #19955 from zeertzjq/vim-9.0.0272
vim-patch:9.0.{0272,0274,0275,0276}: buffer loading fixes
This commit is contained in:
commit
d5e0883712
@ -165,11 +165,12 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags)
|
|||||||
///
|
///
|
||||||
/// @param read_stdin read file from stdin
|
/// @param read_stdin read file from stdin
|
||||||
/// @param eap for forced 'ff' and 'fenc' or NULL
|
/// @param eap for forced 'ff' and 'fenc' or NULL
|
||||||
/// @param flags extra flags for readfile()
|
/// @param flags_arg extra flags for readfile()
|
||||||
///
|
///
|
||||||
/// @return FAIL for failure, OK otherwise.
|
/// @return FAIL for failure, OK otherwise.
|
||||||
int open_buffer(int read_stdin, exarg_T *eap, int flags)
|
int open_buffer(int read_stdin, exarg_T *eap, int flags_arg)
|
||||||
{
|
{
|
||||||
|
int flags = flags_arg;
|
||||||
int retval = OK;
|
int retval = OK;
|
||||||
bufref_T old_curbuf;
|
bufref_T old_curbuf;
|
||||||
long old_tw = curbuf->b_p_tw;
|
long old_tw = curbuf->b_p_tw;
|
||||||
@ -224,8 +225,14 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags)
|
|||||||
// mark cursor position as being invalid
|
// mark cursor position as being invalid
|
||||||
curwin->w_valid = 0;
|
curwin->w_valid = 0;
|
||||||
|
|
||||||
|
// A buffer without an actual file should not use the buffer name to read a
|
||||||
|
// file.
|
||||||
|
if (bt_nofileread(curbuf)) {
|
||||||
|
flags |= READ_NOFILE;
|
||||||
|
}
|
||||||
|
|
||||||
// Read the file if there is one.
|
// Read the file if there is one.
|
||||||
if (curbuf->b_ffname != NULL && !bt_quickfix(curbuf) && !bt_nofilename(curbuf)) {
|
if (curbuf->b_ffname != NULL) {
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
int save_bin = curbuf->b_p_bin;
|
int save_bin = curbuf->b_p_bin;
|
||||||
int perm;
|
int perm;
|
||||||
@ -805,6 +812,18 @@ static void free_buffer(buf_T *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Free the b_wininfo list for buffer "buf".
|
||||||
|
static void clear_wininfo(buf_T *buf)
|
||||||
|
{
|
||||||
|
wininfo_T *wip;
|
||||||
|
|
||||||
|
while (buf->b_wininfo != NULL) {
|
||||||
|
wip = buf->b_wininfo;
|
||||||
|
buf->b_wininfo = wip->wi_next;
|
||||||
|
free_wininfo(wip, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Free stuff in the buffer for ":bdel" and when wiping out the buffer.
|
/// Free stuff in the buffer for ":bdel" and when wiping out the buffer.
|
||||||
///
|
///
|
||||||
/// @param buf Buffer pointer
|
/// @param buf Buffer pointer
|
||||||
@ -839,18 +858,6 @@ static void free_buffer_stuff(buf_T *buf, int free_flags)
|
|||||||
buf_updates_unload(buf, false);
|
buf_updates_unload(buf, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free the b_wininfo list for buffer "buf".
|
|
||||||
static void clear_wininfo(buf_T *buf)
|
|
||||||
{
|
|
||||||
wininfo_T *wip;
|
|
||||||
|
|
||||||
while (buf->b_wininfo != NULL) {
|
|
||||||
wip = buf->b_wininfo;
|
|
||||||
buf->b_wininfo = wip->wi_next;
|
|
||||||
free_wininfo(wip, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Go to another buffer. Handles the result of the ATTENTION dialog.
|
/// Go to another buffer. Handles the result of the ATTENTION dialog.
|
||||||
void goto_buffer(exarg_T *eap, int start, int dir, int count)
|
void goto_buffer(exarg_T *eap, int start, int dir, int count)
|
||||||
{
|
{
|
||||||
@ -3827,7 +3834,8 @@ bool bt_terminal(const buf_T *const buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @return true if "buf" is a "nofile", "acwrite", "terminal" or "prompt"
|
/// @return true if "buf" is a "nofile", "acwrite", "terminal" or "prompt"
|
||||||
/// buffer. This means the buffer name is not a file name.
|
/// buffer. This means the buffer name may not be a file name,
|
||||||
|
/// at least not for writing the buffer.
|
||||||
bool bt_nofilename(const buf_T *const buf)
|
bool bt_nofilename(const buf_T *const buf)
|
||||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
@ -3837,6 +3845,17 @@ bool bt_nofilename(const buf_T *const buf)
|
|||||||
|| buf->b_p_bt[0] == 'p');
|
|| buf->b_p_bt[0] == 'p');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @return true if "buf" is a "nofile", "quickfix", "terminal" or "prompt"
|
||||||
|
/// buffer. This means the buffer is not to be read from a file.
|
||||||
|
static bool bt_nofileread(const buf_T *const buf)
|
||||||
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
return buf != NULL && ((buf->b_p_bt[0] == 'n' && buf->b_p_bt[2] == 'f')
|
||||||
|
|| buf->b_p_bt[0] == 't'
|
||||||
|
|| buf->b_p_bt[0] == 'q'
|
||||||
|
|| buf->b_p_bt[0] == 'p');
|
||||||
|
}
|
||||||
|
|
||||||
/// @return true if "buf" has 'buftype' set to "nofile".
|
/// @return true if "buf" has 'buftype' set to "nofile".
|
||||||
bool bt_nofile(const buf_T *const buf)
|
bool bt_nofile(const buf_T *const buf)
|
||||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
@ -167,6 +167,7 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
|
|||||||
/// READ_STDIN read from stdin instead of a file
|
/// READ_STDIN read from stdin instead of a file
|
||||||
/// READ_BUFFER read from curbuf instead of a file (converting after reading
|
/// READ_BUFFER read from curbuf instead of a file (converting after reading
|
||||||
/// stdin)
|
/// stdin)
|
||||||
|
/// READ_NOFILE do not read a file, only trigger BufReadCmd
|
||||||
/// READ_DUMMY read into a dummy buffer (to check if file contents changed)
|
/// READ_DUMMY read into a dummy buffer (to check if file contents changed)
|
||||||
/// READ_KEEP_UNDO don't clear undo info or read it from a file
|
/// READ_KEEP_UNDO don't clear undo info or read it from a file
|
||||||
/// READ_FIFO read from fifo/socket instead of a file
|
/// READ_FIFO read from fifo/socket instead of a file
|
||||||
@ -334,6 +335,10 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
curbuf->b_op_start = orig_start;
|
curbuf->b_op_start = orig_start;
|
||||||
|
|
||||||
|
if (flags & READ_NOFILE) {
|
||||||
|
return NOTDONE; // so that BufEnter can be triggered
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0) {
|
if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0) {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define READ_KEEP_UNDO 0x20 // keep undo info
|
#define READ_KEEP_UNDO 0x20 // keep undo info
|
||||||
#define READ_FIFO 0x40 // read from fifo or socket
|
#define READ_FIFO 0x40 // read from fifo or socket
|
||||||
#define READ_NOWINENTER 0x80 // do not trigger BufWinEnter
|
#define READ_NOWINENTER 0x80 // do not trigger BufWinEnter
|
||||||
|
#define READ_NOFILE 0x100 // do not read a file, do trigger BufReadCmd
|
||||||
|
|
||||||
#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))
|
#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))
|
||||||
|
|
||||||
|
@ -493,6 +493,26 @@ func Test_BufReadCmdHelpJump()
|
|||||||
au! BufReadCmd
|
au! BufReadCmd
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" BufReadCmd is triggered for a "nofile" buffer. Check all values.
|
||||||
|
func Test_BufReadCmdNofile()
|
||||||
|
for val in ['nofile',
|
||||||
|
\ 'nowrite',
|
||||||
|
\ 'acwrite',
|
||||||
|
\ 'quickfix',
|
||||||
|
\ 'help',
|
||||||
|
\ 'prompt',
|
||||||
|
\ ]
|
||||||
|
new somefile
|
||||||
|
exe 'set buftype=' .. val
|
||||||
|
au BufReadCmd somefile call setline(1, 'triggered')
|
||||||
|
edit
|
||||||
|
call assert_equal('triggered', getline(1))
|
||||||
|
|
||||||
|
au! BufReadCmd
|
||||||
|
bwipe!
|
||||||
|
endfor
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_augroup_deleted()
|
func Test_augroup_deleted()
|
||||||
" This caused a crash before E936 was introduced
|
" This caused a crash before E936 was introduced
|
||||||
augroup x
|
augroup x
|
||||||
@ -587,9 +607,26 @@ func Test_BufEnter()
|
|||||||
" On MS-Windows we can't edit the directory, make sure we wipe the right
|
" On MS-Windows we can't edit the directory, make sure we wipe the right
|
||||||
" buffer.
|
" buffer.
|
||||||
bwipe! Xdir
|
bwipe! Xdir
|
||||||
|
|
||||||
call delete('Xdir', 'd')
|
call delete('Xdir', 'd')
|
||||||
au! BufEnter
|
au! BufEnter
|
||||||
|
|
||||||
|
" Editing a "nofile" buffer doesn't read the file but does trigger BufEnter
|
||||||
|
" for historic reasons. Also test other 'buftype' values.
|
||||||
|
for val in ['nofile',
|
||||||
|
\ 'nowrite',
|
||||||
|
\ 'acwrite',
|
||||||
|
\ 'quickfix',
|
||||||
|
\ 'help',
|
||||||
|
\ 'prompt',
|
||||||
|
\ ]
|
||||||
|
new somefile
|
||||||
|
exe 'set buftype=' .. val
|
||||||
|
au BufEnter somefile call setline(1, 'some text')
|
||||||
|
edit
|
||||||
|
call assert_equal('some text', getline(1))
|
||||||
|
bwipe!
|
||||||
|
au! BufEnter
|
||||||
|
endfor
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Closing a window might cause an endless loop
|
" Closing a window might cause an endless loop
|
||||||
|
@ -187,4 +187,24 @@ func Test_deletebufline_select_mode()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_setbufline_startup_nofile()
|
||||||
|
let before =<< trim [CODE]
|
||||||
|
set shortmess+=F
|
||||||
|
file Xresult
|
||||||
|
set buftype=nofile
|
||||||
|
call setbufline('', 1, 'success')
|
||||||
|
[CODE]
|
||||||
|
let after =<< trim [CODE]
|
||||||
|
set buftype=
|
||||||
|
write
|
||||||
|
quit
|
||||||
|
[CODE]
|
||||||
|
|
||||||
|
if !RunVim(before, after, '--clean')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call assert_equal(['success'], readfile('Xresult'))
|
||||||
|
call delete('Xresult')
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -1880,12 +1880,21 @@ func Test_bufadd_bufload()
|
|||||||
exe 'bwipe ' .. buf2
|
exe 'bwipe ' .. buf2
|
||||||
call assert_equal(0, bufexists(buf2))
|
call assert_equal(0, bufexists(buf2))
|
||||||
|
|
||||||
" when 'buftype' is "nofile" then bufload() does not read the file
|
" When 'buftype' is "nofile" then bufload() does not read the file.
|
||||||
bwipe! XotherName
|
" Other values too.
|
||||||
let buf = bufadd('XotherName')
|
for val in [['nofile', 0],
|
||||||
call setbufvar(buf, '&bt', 'nofile')
|
\ ['nowrite', 1],
|
||||||
call bufload(buf)
|
\ ['acwrite', 1],
|
||||||
call assert_equal([''], getbufline(buf, 1, '$'))
|
\ ['quickfix', 0],
|
||||||
|
\ ['help', 1],
|
||||||
|
\ ['prompt', 0],
|
||||||
|
\ ]
|
||||||
|
bwipe! XotherName
|
||||||
|
let buf = bufadd('XotherName')
|
||||||
|
call setbufvar(buf, '&bt', val[0])
|
||||||
|
call bufload(buf)
|
||||||
|
call assert_equal(val[1] ? ['some', 'text'] : [''], getbufline(buf, 1, '$'), val[0])
|
||||||
|
endfor
|
||||||
|
|
||||||
bwipe someName
|
bwipe someName
|
||||||
bwipe XotherName
|
bwipe XotherName
|
||||||
|
Loading…
Reference in New Issue
Block a user