Merge pull request #19528 from zeertzjq/vim-9.0.0051

vim-patch:9.0.{0051,0082,0083,0086}: cmdline fixes
This commit is contained in:
zeertzjq 2022-07-27 07:25:13 +08:00 committed by GitHub
commit 2fdb0de197
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 316 additions and 94 deletions

View File

@ -4025,6 +4025,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"cindent",
"cmdline_compl",
"cmdline_hist",
"cmdwin",
"comments",
"conceal",
"cscope",

View File

@ -880,6 +880,12 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
found_one = true;
}
}
if (*p_tal != NUL) {
redraw_tabline = true;
found_one = true;
}
if (found_one) {
redraw_statuslines();
}
@ -1068,7 +1074,8 @@ static int command_line_execute(VimState *state, int key)
// Don't ignore it for the input() function.
if ((s->c == Ctrl_C)
&& s->firstc != '@'
&& !s->break_ctrl_c
// do clear got_int in Ex mode to avoid infinite Ctrl-C loop
&& (!s->break_ctrl_c || exmode_active)
&& !global_busy) {
got_int = false;
}
@ -6804,9 +6811,13 @@ static int open_cmdwin(void)
// Avoid command-line window first character being concealed.
curwin->w_p_cole = 0;
// First go back to the original window.
wp = curwin;
set_bufref(&bufref, curbuf);
win_goto(old_curwin);
// win_goto() may trigger an autocommand that already closes the
// cmdline window.
if (win_valid(wp) && wp != curwin) {
win_close(wp, true, false);
}

View File

@ -2851,6 +2851,110 @@ func Test_v_event_readonly()
au! TextYankPost
endfunc
" Test for ModeChanged pattern
func Test_mode_changes()
let g:index = 0
let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'i', 'ix', 'i', 'ic', 'i', 'n', 'no', 'n', 'V', 'v', 's', 'n']
func! TestMode()
call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode"))
call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode"))
call assert_equal(mode(1), get(v:event, "new_mode"))
let g:index += 1
endfunc
au ModeChanged * :call TestMode()
let g:n_to_any = 0
au ModeChanged n:* let g:n_to_any += 1
call feedkeys("i\<esc>vVca\<CR>\<C-X>\<C-L>\<esc>ggdG", 'tnix')
let g:V_to_v = 0
au ModeChanged V:v let g:V_to_v += 1
call feedkeys("Vv\<C-G>\<esc>", 'tnix')
call assert_equal(len(filter(g:mode_seq[1:], {idx, val -> val == 'n'})), g:n_to_any)
call assert_equal(1, g:V_to_v)
call assert_equal(len(g:mode_seq) - 1, g:index)
let g:n_to_i = 0
au ModeChanged n:i let g:n_to_i += 1
let g:n_to_niI = 0
au ModeChanged i:niI let g:n_to_niI += 1
let g:niI_to_i = 0
au ModeChanged niI:i let g:niI_to_i += 1
let g:nany_to_i = 0
au ModeChanged n*:i let g:nany_to_i += 1
let g:i_to_n = 0
au ModeChanged i:n let g:i_to_n += 1
let g:nori_to_any = 0
au ModeChanged [ni]:* let g:nori_to_any += 1
let g:i_to_any = 0
au ModeChanged i:* let g:i_to_any += 1
let g:index = 0
let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
call feedkeys("a\<C-O>l\<esc>", 'tnix')
call assert_equal(len(g:mode_seq) - 1, g:index)
call assert_equal(1, g:n_to_i)
call assert_equal(1, g:n_to_niI)
call assert_equal(1, g:niI_to_i)
call assert_equal(2, g:nany_to_i)
call assert_equal(1, g:i_to_n)
call assert_equal(2, g:i_to_any)
call assert_equal(3, g:nori_to_any)
if has('terminal')
let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n']
call feedkeys(":term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
call assert_equal(len(g:mode_seq) - 1, g:index)
call assert_equal(1, g:n_to_i)
call assert_equal(1, g:n_to_niI)
call assert_equal(1, g:niI_to_i)
call assert_equal(2, g:nany_to_i)
call assert_equal(1, g:i_to_n)
call assert_equal(2, g:i_to_any)
call assert_equal(5, g:nori_to_any)
endif
if has('cmdwin')
let g:n_to_c = 0
au ModeChanged n:c let g:n_to_c += 1
let g:c_to_n = 0
au ModeChanged c:n let g:c_to_n += 1
let g:mode_seq += ['c', 'n', 'c', 'n']
call feedkeys("q:\<C-C>\<Esc>", 'tnix')
call assert_equal(len(g:mode_seq) - 1, g:index)
call assert_equal(2, g:n_to_c)
call assert_equal(2, g:c_to_n)
unlet g:n_to_c
unlet g:c_to_n
endif
au! ModeChanged
delfunc TestMode
unlet! g:mode_seq
unlet! g:index
unlet! g:n_to_any
unlet! g:V_to_v
unlet! g:n_to_i
unlet! g:n_to_niI
unlet! g:niI_to_i
unlet! g:nany_to_i
unlet! g:i_to_n
unlet! g:nori_to_any
unlet! g:i_to_any
endfunc
func Test_recursive_ModeChanged()
au! ModeChanged * norm 0u
sil! norm 
au! ModeChanged
endfunc
func Test_ModeChanged_starts_visual()
" This was triggering ModeChanged before setting VIsual, causing a crash.
au! ModeChanged * norm 0u
sil! norm 
au! ModeChanged
endfunc
func Test_noname_autocmd()
augroup test_noname_autocmd_group

View File

@ -1846,4 +1846,20 @@ func Test_long_error_message()
silent! norm Q00000000000000     000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000                                                                                                                                                                                                                        
endfunc
func Test_cmdline_redraw_tabline()
CheckRunVimInTerminal
let lines =<< trim END
set showtabline=2
autocmd CmdlineEnter * set tabline=foo
END
call writefile(lines, 'Xcmdline_redraw_tabline')
let buf = RunVimInTerminal('-S Xcmdline_redraw_tabline', #{rows: 6})
call term_sendkeys(buf, ':')
call WaitForAssert({-> assert_match('^foo', term_getline(buf, 1))})
call StopVimInTerminal(buf)
call delete('Xcmdline_redraw_tabline')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -1811,95 +1811,4 @@ func Test_read_invalid()
set encoding=utf-8
endfunc
" Test for ModeChanged pattern
func Test_mode_changes()
let g:index = 0
let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'i', 'ix', 'i', 'ic', 'i', 'n', 'no', 'n', 'V', 'v', 's', 'n']
func! TestMode()
call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode"))
call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode"))
call assert_equal(mode(1), get(v:event, "new_mode"))
let g:index += 1
endfunc
au ModeChanged * :call TestMode()
let g:n_to_any = 0
au ModeChanged n:* let g:n_to_any += 1
call feedkeys("i\<esc>vVca\<CR>\<C-X>\<C-L>\<esc>ggdG", 'tnix')
let g:V_to_v = 0
au ModeChanged V:v let g:V_to_v += 1
call feedkeys("Vv\<C-G>\<esc>", 'tnix')
call assert_equal(len(filter(g:mode_seq[1:], {idx, val -> val == 'n'})), g:n_to_any)
call assert_equal(1, g:V_to_v)
call assert_equal(len(g:mode_seq) - 1, g:index)
let g:n_to_i = 0
au ModeChanged n:i let g:n_to_i += 1
let g:n_to_niI = 0
au ModeChanged i:niI let g:n_to_niI += 1
let g:niI_to_i = 0
au ModeChanged niI:i let g:niI_to_i += 1
let g:nany_to_i = 0
au ModeChanged n*:i let g:nany_to_i += 1
let g:i_to_n = 0
au ModeChanged i:n let g:i_to_n += 1
let g:nori_to_any = 0
au ModeChanged [ni]:* let g:nori_to_any += 1
let g:i_to_any = 0
au ModeChanged i:* let g:i_to_any += 1
let g:index = 0
let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
call feedkeys("a\<C-O>l\<esc>", 'tnix')
call assert_equal(len(g:mode_seq) - 1, g:index)
call assert_equal(1, g:n_to_i)
call assert_equal(1, g:n_to_niI)
call assert_equal(1, g:niI_to_i)
call assert_equal(2, g:nany_to_i)
call assert_equal(1, g:i_to_n)
call assert_equal(2, g:i_to_any)
call assert_equal(3, g:nori_to_any)
if has('terminal')
let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n']
call feedkeys(":term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
call assert_equal(len(g:mode_seq) - 1, g:index)
call assert_equal(1, g:n_to_i)
call assert_equal(1, g:n_to_niI)
call assert_equal(1, g:niI_to_i)
call assert_equal(2, g:nany_to_i)
call assert_equal(1, g:i_to_n)
call assert_equal(2, g:i_to_any)
call assert_equal(5, g:nori_to_any)
endif
au! ModeChanged
delfunc TestMode
unlet! g:mode_seq
unlet! g:index
unlet! g:n_to_any
unlet! g:V_to_v
unlet! g:n_to_i
unlet! g:n_to_niI
unlet! g:niI_to_i
unlet! g:nany_to_i
unlet! g:i_to_n
unlet! g:nori_to_any
unlet! g:i_to_any
endfunc
func Test_recursive_ModeChanged()
au! ModeChanged * norm 0u
sil! norm 
au!
endfunc
func Test_ModeChanged_starts_visual()
" This was triggering ModeChanged before setting VIsual, causing a crash.
au! ModeChanged * norm 0u
sil! norm 
au! ModeChanged
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -135,6 +135,30 @@ func Test_Ex_global()
bwipe!
endfunc
" Test for pressing Ctrl-C in :append inside a loop in Ex mode
" This used to hang Vim
func Test_Ex_append_in_loop()
CheckRunVimInTerminal
let buf = RunVimInTerminal('', {'rows': 6})
call term_sendkeys(buf, "gQ")
call term_sendkeys(buf, "for i in range(1)\<CR>")
call term_sendkeys(buf, "append\<CR>")
call WaitForAssert({-> assert_match(': append', term_getline(buf, 5))}, 1000)
call term_sendkeys(buf, "\<C-C>")
" Wait for input to be flushed
call term_wait(buf)
call term_sendkeys(buf, "foo\<CR>")
call WaitForAssert({-> assert_match('foo', term_getline(buf, 5))}, 1000)
call term_sendkeys(buf, ".\<CR>")
call WaitForAssert({-> assert_match('.', term_getline(buf, 5))}, 1000)
call term_sendkeys(buf, "endfor\<CR>")
call term_sendkeys(buf, "vi\<CR>")
call WaitForAssert({-> assert_match('foo', term_getline(buf, 1))}, 1000)
call StopVimInTerminal(buf)
endfunc
" In Ex-mode, a backslash escapes a newline
func Test_Ex_escape_enter()
call feedkeys("gQlet l = \"a\\\<kEnter>b\"\<cr>vi\<cr>", 'xt')

View File

@ -1,4 +1,7 @@
" Test for :global and :vglobal
source check.vim
source term_util.vim
func Test_yank_put_clipboard()
new
@ -82,4 +85,31 @@ func Test_wrong_delimiter()
call assert_fails('g x^bxd', 'E146:')
endfunc
" Test for interrupting :global using Ctrl-C
func Test_interrupt_global()
CheckRunVimInTerminal
let lines =<< trim END
cnoremap ; <Cmd>sleep 10<CR>
call setline(1, repeat(['foo'], 5))
END
call writefile(lines, 'Xtest_interrupt_global')
let buf = RunVimInTerminal('-S Xtest_interrupt_global', {'rows': 6})
call term_sendkeys(buf, ":g/foo/norm :\<C-V>;\<CR>")
" Wait for :sleep to start
call term_wait(buf)
call term_sendkeys(buf, "\<C-C>")
call WaitForAssert({-> assert_match('Interrupted', term_getline(buf, 6))}, 1000)
" Also test in Ex mode
call term_sendkeys(buf, "gQg/foo/norm :\<C-V>;\<CR>")
" Wait for :sleep to start
call term_wait(buf)
call term_sendkeys(buf, "\<C-C>")
call WaitForAssert({-> assert_match('Interrupted', term_getline(buf, 5))}, 1000)
call StopVimInTerminal(buf)
call delete('Xtest_interrupt_global')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -3,11 +3,12 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local feed = helpers.feed
local feed_command = helpers.feed_command
local source = helpers.source
local exec = helpers.exec
describe('cmdline', function()
before_each(clear)
-- oldtest: Test_cmdlineclear_tabenter()
it('is cleared when switching tabs', function()
local screen = Screen.new(30, 10)
screen:attach()
@ -91,10 +92,11 @@ describe('cmdline', function()
]])
end)
-- oldtest: Test_verbose_option()
it('prints every executed Ex command if verbose >= 16', function()
local screen = Screen.new(60, 12)
screen:attach()
source([[
exec([[
command DoSomething echo 'hello' |set ts=4 |let v = '123' |echo v
call feedkeys("\r", 't') " for the hit-enter prompt
set verbose=20
@ -115,4 +117,27 @@ describe('cmdline', function()
Press ENTER or type command to continue^ |
]])
end)
-- oldtest: Test_cmdline_redraw_tabline()
it('tabline is redrawn on entering cmdline', function()
local screen = Screen.new(30, 6)
screen:set_default_attr_ids({
[0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
[1] = {reverse = true}, -- TabLineFill
})
screen:attach()
exec([[
set showtabline=2
autocmd CmdlineEnter * set tabline=foo
]])
feed(':')
screen:expect([[
{1:foo }|
|
{0:~ }|
{0:~ }|
{0:~ }|
:^ |
]])
end)
end)

View File

@ -6,6 +6,7 @@ local eq = helpers.eq
local eval = helpers.eval
local feed = helpers.feed
local meths = helpers.meths
local sleep = helpers.sleep
before_each(clear)
@ -122,4 +123,54 @@ describe('Ex mode', function()
|
]])
end)
it('pressing Ctrl-C in :append inside a loop in Ex mode does not hang', function()
local screen = Screen.new(60, 6)
screen:set_default_attr_ids({
[0] = {bold = true, reverse = true}, -- MsgSeparator
[1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
})
screen:attach()
feed('gQ')
feed('for i in range(1)<CR>')
feed('append<CR>')
screen:expect([[
{0: }|
Entering Ex mode. Type "visual" to go to Normal mode. |
:for i in range(1) |
|
: append |
^ |
]])
feed('<C-C>')
sleep(10) -- Wait for input to be flushed
feed('foo<CR>')
screen:expect([[
Entering Ex mode. Type "visual" to go to Normal mode. |
:for i in range(1) |
|
: append |
foo |
^ |
]])
feed('.<CR>')
screen:expect([[
:for i in range(1) |
|
: append |
foo |
. |
: ^ |
]])
feed('endfor<CR>')
feed('vi<CR>')
screen:expect([[
^foo |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]])
end)
end)

View File

@ -0,0 +1,51 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local exec = helpers.exec
local feed = helpers.feed
local sleep = helpers.sleep
before_each(clear)
describe(':global', function()
-- oldtest: Test_interrupt_global()
it('can be interrupted using Ctrl-C in cmdline mode vim-patch:9.0.0082', function()
local screen = Screen.new(75, 6)
screen:set_default_attr_ids({
[0] = {bold = true, reverse = true}, -- MsgSeparator
[1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
})
screen:attach()
exec([[
set nohlsearch noincsearch
cnoremap ; <Cmd>sleep 10<CR>
call setline(1, repeat(['foo'], 5))
]])
feed(':g/foo/norm :<C-V>;<CR>')
sleep(10) -- Wait for :sleep to start
feed('<C-C>')
screen:expect([[
^foo |
foo |
foo |
foo |
foo |
{1:Interrupted} |
]])
-- Also test in Ex mode
feed('gQg/foo/norm :<C-V>;<CR>')
sleep(10) -- Wait for :sleep to start
feed('<C-C>')
screen:expect([[
{0: }|
Entering Ex mode. Type "visual" to go to Normal mode. |
:g/foo/norm :; |
|
{1:Interrupted} |
:^ |
]])
end)
end)