aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-07-27 07:25:13 +0800
committerGitHub <noreply@github.com>2022-07-27 07:25:13 +0800
commit2fdb0de1975b015d8745141eaa18e62af793e0ef (patch)
treeda96e28622a4caf0a304f1827439b01a88829778 /src
parent49d2256ae5b747830160a1dd1f3f532cf726b394 (diff)
parentfc55f8263c6c8d8851fa2b6290083a64da1ebd28 (diff)
downloadrneovim-2fdb0de1975b015d8745141eaa18e62af793e0ef.tar.gz
rneovim-2fdb0de1975b015d8745141eaa18e62af793e0ef.tar.bz2
rneovim-2fdb0de1975b015d8745141eaa18e62af793e0ef.zip
Merge pull request #19528 from zeertzjq/vim-9.0.0051
vim-patch:9.0.{0051,0082,0083,0086}: cmdline fixes
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval/funcs.c1
-rw-r--r--src/nvim/ex_getln.c13
-rw-r--r--src/nvim/testdir/test_autocmd.vim104
-rw-r--r--src/nvim/testdir/test_cmdline.vim16
-rw-r--r--src/nvim/testdir/test_edit.vim91
-rw-r--r--src/nvim/testdir/test_ex_mode.vim24
-rw-r--r--src/nvim/testdir/test_global.vim30
7 files changed, 187 insertions, 92 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 7d5404d782..fb59a3da4c 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -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",
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 3038e7bd04..906e52f183 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -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);
}
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 438851a0ad..cf14c85d03 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -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
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 276bb7fb71..a0907d79ac 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -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
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index 42c77518e4..a09346a595 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -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
diff --git a/src/nvim/testdir/test_ex_mode.vim b/src/nvim/testdir/test_ex_mode.vim
index c06d143425..2f734cba26 100644
--- a/src/nvim/testdir/test_ex_mode.vim
+++ b/src/nvim/testdir/test_ex_mode.vim
@@ -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')
diff --git a/src/nvim/testdir/test_global.vim b/src/nvim/testdir/test_global.vim
index feddf85346..947f7efc7c 100644
--- a/src/nvim/testdir/test_global.vim
+++ b/src/nvim/testdir/test_global.vim
@@ -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