mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #5384 from bfredl/getchar_event
allow event processing in getchar()
This commit is contained in:
commit
9477c5bb5b
@ -9527,24 +9527,35 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
varnumber_T n;
|
||||
int error = FALSE;
|
||||
|
||||
/* Position the cursor. Needed after a message that ends in a space. */
|
||||
ui_cursor_goto(msg_row, msg_col);
|
||||
|
||||
++no_mapping;
|
||||
++allow_keys;
|
||||
for (;; ) {
|
||||
if (argvars[0].v_type == VAR_UNKNOWN)
|
||||
/* getchar(): blocking wait. */
|
||||
// Position the cursor. Needed after a message that ends in a space,
|
||||
// or if event processing caused a redraw.
|
||||
ui_cursor_goto(msg_row, msg_col);
|
||||
|
||||
if (argvars[0].v_type == VAR_UNKNOWN) {
|
||||
// getchar(): blocking wait.
|
||||
if (!(char_avail() || using_script() || input_available())) {
|
||||
input_enable_events();
|
||||
(void)os_inchar(NULL, 0, -1, 0);
|
||||
input_disable_events();
|
||||
if (!multiqueue_empty(main_loop.events)) {
|
||||
multiqueue_process_events(main_loop.events);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
n = safe_vgetc();
|
||||
else if (get_tv_number_chk(&argvars[0], &error) == 1)
|
||||
/* getchar(1): only check if char avail */
|
||||
} else if (get_tv_number_chk(&argvars[0], &error) == 1) {
|
||||
// getchar(1): only check if char avail
|
||||
n = vpeekc_any();
|
||||
else if (error || vpeekc_any() == NUL)
|
||||
/* illegal argument or getchar(0) and no char avail: return zero */
|
||||
} else if (error || vpeekc_any() == NUL) {
|
||||
// illegal argument or getchar(0) and no char avail: return zero
|
||||
n = 0;
|
||||
else
|
||||
/* getchar(0) and char avail: return char */
|
||||
} else {
|
||||
// getchar(0) and char avail: return char
|
||||
n = safe_vgetc();
|
||||
}
|
||||
|
||||
if (n == K_IGNORE)
|
||||
continue;
|
||||
|
@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
|
||||
local ok, feed, eq, eval = helpers.ok, helpers.feed, helpers.eq, helpers.eval
|
||||
local source, nvim_async, run = helpers.source, helpers.nvim_async, helpers.run
|
||||
local clear, execute, funcs = helpers.clear, helpers.execute, helpers.funcs
|
||||
local curbufmeths = helpers.curbufmeths
|
||||
|
||||
describe('timers', function()
|
||||
before_each(function()
|
||||
@ -62,19 +63,76 @@ describe('timers', function()
|
||||
end)
|
||||
|
||||
it('are paused when event processing is disabled', function()
|
||||
-- this is not the intended behavior, but at least there will
|
||||
-- not be a burst of queued up callbacks
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
run(nil, nil, nil, 100)
|
||||
local count = eval("g:val")
|
||||
-- shows two line error message and thus invokes the return prompt.
|
||||
-- if we start to allow event processing here, we need to change this test.
|
||||
execute("throw 'fatal error'")
|
||||
run(nil, nil, nil, 300)
|
||||
feed("<cr>")
|
||||
local diff = eval("g:val") - count
|
||||
ok(0 <= diff and diff <= 4)
|
||||
end)
|
||||
|
||||
it('are triggered in blocking getchar() call', function()
|
||||
execute("call timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
nvim_async("command", "let g:c = getchar()")
|
||||
run(nil, nil, nil, 300)
|
||||
feed("c")
|
||||
local diff = eval("g:val") - count
|
||||
ok(0 <= diff and diff <= 2)
|
||||
local count = eval("g:val")
|
||||
ok(count >= 5)
|
||||
eq(99, eval("g:c"))
|
||||
end)
|
||||
|
||||
it('can invoke redraw in blocking getchar() call', function()
|
||||
local screen = Screen.new(40, 6)
|
||||
screen:attach()
|
||||
screen:set_default_attr_ids({
|
||||
[1] = {bold=true, foreground=Screen.colors.Blue},
|
||||
})
|
||||
|
||||
curbufmeths.set_lines(0, -1, true, {"ITEM 1", "ITEM 2"})
|
||||
source([[
|
||||
func! AddItem(timer)
|
||||
call nvim_buf_set_lines(0, 2, 2, v:true, ['ITEM 3'])
|
||||
redraw
|
||||
endfunc
|
||||
call timer_start(200, 'AddItem')
|
||||
]])
|
||||
nvim_async("command", "let g:c2 = getchar()")
|
||||
|
||||
screen:expect([[
|
||||
ITEM 1 |
|
||||
ITEM 2 |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
^ |
|
||||
]])
|
||||
|
||||
screen:sleep(200)
|
||||
screen:expect([[
|
||||
ITEM 1 |
|
||||
ITEM 2 |
|
||||
ITEM 3 |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
^ |
|
||||
]])
|
||||
|
||||
feed("3")
|
||||
eq(51, eval("g:c2"))
|
||||
screen:expect([[
|
||||
^ITEM 1 |
|
||||
ITEM 2 |
|
||||
ITEM 3 |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can be stopped', function()
|
||||
local t = eval("timer_start(50, 'MyHandler', {'repeat': -1})")
|
||||
eq(0,eval("g:val"))
|
||||
|
Loading…
Reference in New Issue
Block a user