aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/builtin.txt1
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua1
-rw-r--r--src/nvim/api/vim.c15
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/message.c10
-rw-r--r--src/nvim/os/input.c7
-rw-r--r--test/functional/legacy/buffer_spec.lua59
-rw-r--r--test/functional/legacy/filechanged_spec.lua142
-rw-r--r--test/functional/vimscript/input_spec.lua16
-rw-r--r--test/old/testdir/test_buffer.vim4
-rw-r--r--test/old/testdir/test_filechanged.vim6
-rw-r--r--test/old/testdir/test_functions.vim2
12 files changed, 30 insertions, 234 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index c88513ad75..20cdb396e1 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1588,6 +1588,7 @@ feedkeys({string} [, {mode}]) *feedkeys()*
't' Handle keys as if typed; otherwise they are handled as
if coming from a mapping. This matters for undo,
opening folds, etc.
+ 'L' Lowlevel input. Other flags are not used.
'i' Insert the string instead of appending (see above).
'x' Execute commands until typeahead is empty. This is
similar to using ":normal!". You can call feedkeys()
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index caddd4dde2..887c4b3cbe 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -1959,6 +1959,7 @@ function vim.fn.extendnew(expr1, expr2, expr3) end
--- 't' Handle keys as if typed; otherwise they are handled as
--- if coming from a mapping. This matters for undo,
--- opening folds, etc.
+--- 'L' Lowlevel input. Other flags are not used.
--- 'i' Insert the string instead of appending (see above).
--- 'x' Execute commands until typeahead is empty. This is
--- similar to using ":normal!". You can call feedkeys()
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 2fb8f3d554..82e9ddff2d 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -277,6 +277,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks)
bool typed = false;
bool execute = false;
bool dangerous = false;
+ bool lowlevel = false;
for (size_t i = 0; i < mode.size; i++) {
switch (mode.data[i]) {
@@ -292,6 +293,8 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks)
execute = true; break;
case '!':
dangerous = true; break;
+ case 'L':
+ lowlevel = true; break;
}
}
@@ -307,10 +310,14 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks)
} else {
keys_esc = keys.data;
}
- ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
- insert ? 0 : typebuf.tb_len, !typed, false);
- if (vgetc_busy) {
- typebuf_was_filled = true;
+ if (lowlevel) {
+ input_enqueue_raw(cstr_as_string(keys_esc));
+ } else {
+ ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
+ insert ? 0 : typebuf.tb_len, !typed, false);
+ if (vgetc_busy) {
+ typebuf_was_filled = true;
+ }
}
if (escape_ks) {
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 6a3eabc467..e40e81f8f2 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -2481,6 +2481,7 @@ M.funcs = {
't' Handle keys as if typed; otherwise they are handled as
if coming from a mapping. This matters for undo,
opening folds, etc.
+ 'L' Lowlevel input. Other flags are not used.
'i' Insert the string instead of appending (see above).
'x' Execute commands until typeahead is empty. This is
similar to using ":normal!". You can call feedkeys()
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 68a8b8e88b..362dc2c05a 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -3395,9 +3395,7 @@ int do_dialog(int type, const char *title, const char *message, const char *butt
int retval = 0;
int i;
- if (silent_mode // No dialogs in silent mode ("ex -s")
- || !ui_active() // Without a UI Nvim waits for input forever.
- ) {
+ if (silent_mode) { // No dialogs in silent mode ("ex -s")
return dfltbutton; // return default option
}
@@ -3414,6 +3412,12 @@ int do_dialog(int type, const char *title, const char *message, const char *butt
char *hotkeys = msg_show_console_dialog(message, buttons, dfltbutton);
while (true) {
+ // Without a UI Nvim waits for input forever.
+ if (!ui_active() && !input_available()) {
+ retval = dfltbutton;
+ break;
+ }
+
// Get a typed character directly from the user.
int c = get_keystroke(NULL);
switch (c) {
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index 5218e50df6..60b5b48745 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -247,6 +247,13 @@ bool os_isatty(int fd)
return uv_guess_handle(fd) == UV_TTY;
}
+void input_enqueue_raw(String keys)
+{
+ if (keys.size > 0) {
+ rbuffer_write(input_buffer, keys.data, keys.size);
+ }
+}
+
size_t input_enqueue(String keys)
{
const char *ptr = keys.data;
diff --git a/test/functional/legacy/buffer_spec.lua b/test/functional/legacy/buffer_spec.lua
deleted file mode 100644
index b3964540f0..0000000000
--- a/test/functional/legacy/buffer_spec.lua
+++ /dev/null
@@ -1,59 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear, source = helpers.clear, helpers.source
-local call, eq, api = helpers.call, helpers.eq, helpers.api
-
-local function expected_empty()
- eq({}, api.nvim_get_vvar('errors'))
-end
-
-describe('buffer', function()
- before_each(function()
- clear()
- api.nvim_ui_attach(80, 24, {})
- api.nvim_set_option_value('hidden', false, {})
- end)
-
- it('deleting a modified buffer with :confirm', function()
- source([[
- func Test_bdel_with_confirm()
- new
- call setline(1, 'test')
- call assert_fails('bdel', 'E89:')
- call nvim_input('c')
- confirm bdel
- call assert_equal(2, winnr('$'))
- call assert_equal(1, &modified)
- call nvim_input('n')
- confirm bdel
- call assert_equal(1, winnr('$'))
- endfunc
- ]])
- call('Test_bdel_with_confirm')
- expected_empty()
- end)
-
- it('editing another buffer from a modified buffer with :confirm', function()
- source([[
- func Test_goto_buf_with_confirm()
- new Xfile
- enew
- call setline(1, 'test')
- call assert_fails('b Xfile', 'E37:')
- call nvim_input('c')
- call assert_fails('confirm b Xfile', 'E37:')
- call assert_equal(1, &modified)
- call assert_equal('', @%)
- call nvim_input('y')
- call assert_fails('confirm b Xfile', 'E37:')
- call assert_equal(1, &modified)
- call assert_equal('', @%)
- call nvim_input('n')
- confirm b Xfile
- call assert_equal('Xfile', @%)
- close!
- endfunc
- ]])
- call('Test_goto_buf_with_confirm')
- expected_empty()
- end)
-end)
diff --git a/test/functional/legacy/filechanged_spec.lua b/test/functional/legacy/filechanged_spec.lua
deleted file mode 100644
index 46ecfdcd63..0000000000
--- a/test/functional/legacy/filechanged_spec.lua
+++ /dev/null
@@ -1,142 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear, source = helpers.clear, helpers.source
-local call, eq, api = helpers.call, helpers.eq, helpers.api
-local is_os = helpers.is_os
-local skip = helpers.skip
-
-local function expected_empty()
- eq({}, api.nvim_get_vvar('errors'))
-end
-
-describe('file changed dialog', function()
- before_each(function()
- clear()
- api.nvim_ui_attach(80, 24, {})
- api.nvim_set_option_value('autoread', false, {})
- api.nvim_set_option_value('fsync', true, {})
- end)
-
- it('works', function()
- skip(is_os('win'))
- source([[
- func Test_file_changed_dialog()
- au! FileChangedShell
-
- new Xchanged_d
- call setline(1, 'reload this')
- write
- " Need to wait until the timestamp would change by at least a second.
- sleep 2
- silent !echo 'extra line' >>Xchanged_d
- call nvim_input('L')
- checktime
- call assert_match('W11:', v:warningmsg)
- call assert_equal(2, line('$'))
- call assert_equal('reload this', getline(1))
- call assert_equal('extra line', getline(2))
-
- " delete buffer, only shows an error, no prompt
- silent !rm Xchanged_d
- checktime
- call assert_match('E211:', v:warningmsg)
- call assert_equal(2, line('$'))
- call assert_equal('extra line', getline(2))
- let v:warningmsg = 'empty'
-
- " change buffer, recreate the file and reload
- call setline(1, 'buffer is changed')
- silent !echo 'new line' >Xchanged_d
- call nvim_input('L')
- checktime
- call assert_match('W12:', v:warningmsg)
- call assert_equal(1, line('$'))
- call assert_equal('new line', getline(1))
-
- " Only mode changed, reload
- silent !chmod +x Xchanged_d
- call nvim_input('L')
- checktime
- call assert_match('W16:', v:warningmsg)
- call assert_equal(1, line('$'))
- call assert_equal('new line', getline(1))
-
- " Only time changed, no prompt
- sleep 2
- silent !touch Xchanged_d
- let v:warningmsg = ''
- checktime Xchanged_d
- call assert_equal('', v:warningmsg)
- call assert_equal(1, line('$'))
- call assert_equal('new line', getline(1))
-
- " File created after starting to edit it
- call delete('Xchanged_d')
- new Xchanged_d
- call writefile(['one'], 'Xchanged_d')
- call nvim_input('L')
- checktime Xchanged_d
- call assert_equal(['one'], getline(1, '$'))
- close!
-
- bwipe!
- call delete('Xchanged_d')
- endfunc
- ]])
- call('Test_file_changed_dialog')
- expected_empty()
- end)
-
- it('works with FileChangedShell', function()
- source([[
- func Test_FileChangedShell_edit_dialog()
- new Xchanged_r
- call setline(1, 'reload this')
- set fileformat=unix
- silent write " Use :silent to prevent a hit-enter prompt
-
- " File format changed, reload (content only) via prompt
- augroup testreload
- au!
- au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
- augroup END
- call assert_equal(&fileformat, 'unix')
- sleep 10m " make the test less flaky in Nvim
- call writefile(["line1\r", "line2\r"], 'Xchanged_r')
- let g:reason = ''
- call nvim_input('L') " load file content only
- checktime
- call assert_equal('changed', g:reason)
- call assert_equal(&fileformat, 'unix')
- call assert_equal("line1\r", getline(1))
- call assert_equal("line2\r", getline(2))
- %s/\r
- silent write " Use :silent to prevent a hit-enter prompt
-
- " File format changed, reload (file and options) via prompt
- augroup testreload
- au!
- au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
- augroup END
- call assert_equal(&fileformat, 'unix')
- sleep 10m " make the test less flaky in Nvim
- call writefile(["line1\r", "line2\r"], 'Xchanged_r')
- let g:reason = ''
- call nvim_input('a') " load file content and options
- checktime
- call assert_equal('changed', g:reason)
- call assert_equal(&fileformat, 'dos')
- call assert_equal("line1", getline(1))
- call assert_equal("line2", getline(2))
- set fileformat=unix
- silent write " Use :silent to prevent a hit-enter prompt
-
- au! testreload
- bwipe!
- call delete(undofile('Xchanged_r'))
- call delete('Xchanged_r')
- endfunc
- ]])
- call('Test_FileChangedShell_edit_dialog')
- expected_empty()
- end)
-end)
diff --git a/test/functional/vimscript/input_spec.lua b/test/functional/vimscript/input_spec.lua
index b749d5a7f0..d64ae3b0f1 100644
--- a/test/functional/vimscript/input_spec.lua
+++ b/test/functional/vimscript/input_spec.lua
@@ -8,7 +8,6 @@ local clear = helpers.clear
local source = helpers.source
local command = helpers.command
local exc_exec = helpers.exc_exec
-local pcall_err = helpers.pcall_err
local async_meths = helpers.async_meths
local NIL = vim.NIL
@@ -407,7 +406,6 @@ describe('inputdialog()', function()
end)
describe('confirm()', function()
- -- oldtest: Test_confirm()
it('works', function()
api.nvim_set_option_value('more', false, {}) -- Avoid hit-enter prompt
api.nvim_set_option_value('laststatus', 2, {})
@@ -470,20 +468,6 @@ describe('confirm()', function()
screen:expect({ any = '%[No Name%]' })
eq(1, api.nvim_get_var('a'))
end
-
- eq('Vim(call):E730: Using a List as a String', pcall_err(command, 'call confirm([])'))
- eq(
- 'Vim(call):E730: Using a List as a String',
- pcall_err(command, 'call confirm("Are you sure?", [])')
- )
- eq(
- 'Vim(call):E745: Using a List as a Number',
- pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", [])')
- )
- eq(
- 'Vim(call):E730: Using a List as a String',
- pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", 0, [])')
- )
end)
it('shows dialog even if :silent #8788', function()
diff --git a/test/old/testdir/test_buffer.vim b/test/old/testdir/test_buffer.vim
index bb8394997d..f2a5a228b8 100644
--- a/test/old/testdir/test_buffer.vim
+++ b/test/old/testdir/test_buffer.vim
@@ -232,8 +232,6 @@ endfunc
" Test for deleting a modified buffer with :confirm
func Test_bdel_with_confirm()
- " requires a UI to be active
- throw 'Skipped: use test/functional/legacy/buffer_spec.lua'
CheckUnix
CheckNotGui
CheckFeature dialog_con
@@ -251,8 +249,6 @@ endfunc
" Test for editing another buffer from a modified buffer with :confirm
func Test_goto_buf_with_confirm()
- " requires a UI to be active
- throw 'Skipped: use test/functional/legacy/buffer_spec.lua'
CheckUnix
CheckNotGui
CheckFeature dialog_con
diff --git a/test/old/testdir/test_filechanged.vim b/test/old/testdir/test_filechanged.vim
index fef0eb732f..b9f8d4c37a 100644
--- a/test/old/testdir/test_filechanged.vim
+++ b/test/old/testdir/test_filechanged.vim
@@ -140,8 +140,6 @@ func Test_FileChangedShell_edit()
endfunc
func Test_FileChangedShell_edit_dialog()
- " requires a UI to be active
- throw 'Skipped: use test/functional/legacy/filechanged_spec.lua'
CheckNotGui
CheckUnix " Using low level feedkeys() does not work on MS-Windows.
@@ -156,6 +154,7 @@ func Test_FileChangedShell_edit_dialog()
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
augroup END
call assert_equal(&fileformat, 'unix')
+ sleep 10m " make the test less flaky in Nvim
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
let g:reason = ''
call feedkeys('L', 'L') " load file content only
@@ -173,6 +172,7 @@ func Test_FileChangedShell_edit_dialog()
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
augroup END
call assert_equal(&fileformat, 'unix')
+ sleep 10m " make the test less flaky in Nvim
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
let g:reason = ''
call feedkeys('a', 'L') " load file content and options
@@ -191,8 +191,6 @@ func Test_FileChangedShell_edit_dialog()
endfunc
func Test_file_changed_dialog()
- " requires a UI to be active
- throw 'Skipped: use test/functional/legacy/filechanged_spec.lua'
CheckUnix
CheckNotGui
au! FileChangedShell
diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim
index fdcd93a264..ea0e3790cc 100644
--- a/test/old/testdir/test_functions.vim
+++ b/test/old/testdir/test_functions.vim
@@ -2590,8 +2590,6 @@ endfunc
" Test confirm({msg} [, {choices} [, {default} [, {type}]]])
func Test_confirm()
- " requires a UI to be active
- throw 'Skipped: use test/functional/vimscript/input_spec.lua'
CheckUnix
CheckNotGui