vim-patch:9.1.0049: Make "[Command Line]" a special buffer name

Problem:  E95 is possible if a buffer called "[Command Line]" already
          exists when opening the cmdwin. This can also happen if the
          cmdwin's buffer could not be deleted when closing.

Solution: Un-name the cmdwin buffer, and give it a special name instead,
          similar to what's done for quickfix buffers and for unnamed
          prompt and scratch buffers. As a result, BufFilePre/Post are
          no longer fired when opening the cmdwin. Add a "command" key
          to the dictionary returned by getbufinfo() to differentiate
          the cmdwin buffer instead. (Sean Dewar)

Cherry-pick test_normal changes from v9.0.0954.

1fb4103206
This commit is contained in:
Sean Dewar
2023-08-15 19:38:52 +01:00
parent 7bb0dd08db
commit d85f180f26
8 changed files with 39 additions and 8 deletions

View File

@@ -2079,6 +2079,8 @@ getbufinfo([{dict}]) *getbufinfo()*
bufnr Buffer number. bufnr Buffer number.
changed TRUE if the buffer is modified. changed TRUE if the buffer is modified.
changedtick Number of changes made to the buffer. changedtick Number of changes made to the buffer.
command TRUE if the buffer belongs to the
command-line window |cmdwin|.
hidden TRUE if the buffer is hidden. hidden TRUE if the buffer is hidden.
lastused Timestamp in seconds, like lastused Timestamp in seconds, like
|localtime()|, when the buffer was |localtime()|, when the buffer was

View File

@@ -2562,6 +2562,8 @@ function vim.fn.getbufinfo(buf) end
--- bufnr Buffer number. --- bufnr Buffer number.
--- changed TRUE if the buffer is modified. --- changed TRUE if the buffer is modified.
--- changedtick Number of changes made to the buffer. --- changedtick Number of changes made to the buffer.
--- command TRUE if the buffer belongs to the
--- command-line window |cmdwin|.
--- hidden TRUE if the buffer is hidden. --- hidden TRUE if the buffer is hidden.
--- lastused Timestamp in seconds, like --- lastused Timestamp in seconds, like
--- |localtime()|, when the buffer was --- |localtime()|, when the buffer was

View File

@@ -4012,6 +4012,9 @@ char *buf_spname(buf_T *buf)
if (buf->b_fname != NULL) { if (buf->b_fname != NULL) {
return buf->b_fname; return buf->b_fname;
} }
if (buf == cmdwin_buf) {
return _("[Command Line]");
}
if (bt_prompt(buf)) { if (bt_prompt(buf)) {
return _("[Prompt]"); return _("[Prompt]");
} }
@@ -4129,6 +4132,7 @@ void wipe_buffer(buf_T *buf, bool aucmd)
/// - Always considered 'nomodified' /// - Always considered 'nomodified'
/// ///
/// @param bufnr Buffer to switch to, or 0 to create a new buffer. /// @param bufnr Buffer to switch to, or 0 to create a new buffer.
/// @param bufname Buffer name, or NULL.
/// ///
/// @see curbufIsChanged() /// @see curbufIsChanged()
/// ///
@@ -4138,9 +4142,11 @@ int buf_open_scratch(handle_T bufnr, char *bufname)
if (do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL) == FAIL) { if (do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL) == FAIL) {
return FAIL; return FAIL;
} }
apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf); if (bufname != NULL) {
setfname(curbuf, bufname, NULL, true); apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf);
apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf); setfname(curbuf, bufname, NULL, true);
apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf);
}
set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL);
set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL);
set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL);

View File

@@ -3219,6 +3219,8 @@ M.funcs = {
bufnr Buffer number. bufnr Buffer number.
changed TRUE if the buffer is modified. changed TRUE if the buffer is modified.
changedtick Number of changes made to the buffer. changedtick Number of changes made to the buffer.
command TRUE if the buffer belongs to the
command-line window |cmdwin|.
hidden TRUE if the buffer is hidden. hidden TRUE if the buffer is hidden.
lastused Timestamp in seconds, like lastused Timestamp in seconds, like
|localtime()|, when the buffer was |localtime()|, when the buffer was

View File

@@ -494,6 +494,7 @@ static dict_T *get_buffer_info(buf_T *buf)
tv_dict_add_nr(dict, S_LEN("changed"), bufIsChanged(buf)); tv_dict_add_nr(dict, S_LEN("changed"), bufIsChanged(buf));
tv_dict_add_nr(dict, S_LEN("changedtick"), buf_get_changedtick(buf)); tv_dict_add_nr(dict, S_LEN("changedtick"), buf_get_changedtick(buf));
tv_dict_add_nr(dict, S_LEN("hidden"), buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0); tv_dict_add_nr(dict, S_LEN("hidden"), buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0);
tv_dict_add_nr(dict, S_LEN("command"), buf == cmdwin_buf);
// Get a reference to buffer variables // Get a reference to buffer variables
tv_dict_add_dict(dict, S_LEN("variables"), buf->b_vars); tv_dict_add_dict(dict, S_LEN("variables"), buf->b_vars);

View File

@@ -4345,7 +4345,7 @@ static int open_cmdwin(void)
// Create empty command-line buffer. Be especially cautious of BufLeave // Create empty command-line buffer. Be especially cautious of BufLeave
// autocommands from do_ecmd(), as cmdwin restrictions do not apply to them! // autocommands from do_ecmd(), as cmdwin restrictions do not apply to them!
const int newbuf_status = buf_open_scratch(0, _("[Command Line]")); const int newbuf_status = buf_open_scratch(0, NULL);
const bool cmdwin_valid = win_valid(cmdwin_win); const bool cmdwin_valid = win_valid(cmdwin_win);
if (newbuf_status == FAIL || !cmdwin_valid || curwin != cmdwin_win || !win_valid(old_curwin) if (newbuf_status == FAIL || !cmdwin_valid || curwin != cmdwin_win || !win_valid(old_curwin)
|| !bufref_valid(&old_curbuf) || old_curwin->w_buffer != old_curbuf.br_buf) { || !bufref_valid(&old_curbuf) || old_curwin->w_buffer != old_curbuf.br_buf) {

View File

@@ -192,4 +192,17 @@ func Test_cmdwin_interrupted()
delfunc CheckInterrupted delfunc CheckInterrupted
endfunc endfunc
func Test_cmdwin_existing_bufname()
func CheckName()
call assert_equal(1, getbufinfo('')[0].command)
call assert_equal(0, getbufinfo('[Command Line]')[0].command)
call assert_match('#a\s*"\[Command Line\]"', execute('ls'))
call assert_match('%a\s*"\[Command Line\]"', execute('ls'))
endfunc
file [Command Line]
call feedkeys("q::call CheckName()\<CR>:q\<CR>", 'ntx')
0file
delfunc CheckName
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -3167,15 +3167,18 @@ endfunc
func Test_normal50_commandline() func Test_normal50_commandline()
CheckFeature timers CheckFeature timers
CheckFeature cmdline_hist CheckFeature cmdline_hist
func! DoTimerWork(id) func! DoTimerWork(id)
call assert_equal('[Command Line]', bufname('')) call assert_equal(1, getbufinfo('')[0].command)
" should fail, with E11, but does fail with E23? " should fail, with E11, but does fail with E23?
"call feedkeys("\<c-^>", 'tm') "call feedkeys("\<c-^>", 'tm')
" should also fail with E11 " should fail with E11 - "Invalid in command-line window"
call assert_fails(":wincmd p", 'E11') call assert_fails(":wincmd p", 'E11')
" return from commandline window
call feedkeys("\<cr>") " Return from commandline window.
call feedkeys("\<CR>", 't')
endfunc endfunc
let oldlang=v:lang let oldlang=v:lang
@@ -3188,7 +3191,9 @@ func Test_normal50_commandline()
catch /E23/ catch /E23/
" no-op " no-op
endtry endtry
" clean up " clean up
delfunc DoTimerWork
set updatetime=4000 set updatetime=4000
exe "lang" oldlang exe "lang" oldlang
bw! bw!