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:
zeertzjq 2022-08-27 06:32:41 +08:00 committed by GitHub
commit d5e0883712
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 114 additions and 23 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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