mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
fix(f_wait): flush UI before blocking (#25962)
This commit is contained in:
parent
bf5cf8ae82
commit
d5a85d737a
@ -2911,6 +2911,9 @@ static void f_wait(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
bool error = false;
|
bool error = false;
|
||||||
const int called_emsg_before = called_emsg;
|
const int called_emsg_before = called_emsg;
|
||||||
|
|
||||||
|
// Flush screen updates before blocking.
|
||||||
|
ui_flush();
|
||||||
|
|
||||||
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, timeout,
|
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, timeout,
|
||||||
eval_expr_typval(&expr, false, &argv, 0, &exprval) != OK
|
eval_expr_typval(&expr, false, &argv, 0, &exprval) != OK
|
||||||
|| tv_get_number_chk(&exprval, &error)
|
|| tv_get_number_chk(&exprval, &error)
|
||||||
|
@ -1723,7 +1723,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
|
|||||||
// getchar(): blocking wait.
|
// getchar(): blocking wait.
|
||||||
// TODO(bfredl): deduplicate shared logic with state_enter ?
|
// TODO(bfredl): deduplicate shared logic with state_enter ?
|
||||||
if (!char_avail()) {
|
if (!char_avail()) {
|
||||||
// flush output before waiting
|
// Flush screen updates before blocking.
|
||||||
ui_flush();
|
ui_flush();
|
||||||
(void)os_inchar(NULL, 0, -1, typebuf.tb_change_cnt, main_loop.events);
|
(void)os_inchar(NULL, 0, -1, typebuf.tb_change_cnt, main_loop.events);
|
||||||
if (!multiqueue_empty(main_loop.events)) {
|
if (!multiqueue_empty(main_loop.events)) {
|
||||||
|
@ -463,7 +463,7 @@ static int nlua_wait(lua_State *lstate)
|
|||||||
int pcall_status = 0;
|
int pcall_status = 0;
|
||||||
bool callback_result = false;
|
bool callback_result = false;
|
||||||
|
|
||||||
// Flush UI before blocking
|
// Flush screen updates before blocking.
|
||||||
ui_flush();
|
ui_flush();
|
||||||
|
|
||||||
LOOP_PROCESS_EVENTS_UNTIL(&main_loop,
|
LOOP_PROCESS_EVENTS_UNTIL(&main_loop,
|
||||||
|
@ -70,7 +70,7 @@ getkey:
|
|||||||
update_screen();
|
update_screen();
|
||||||
setcursor(); // put cursor back where it belongs
|
setcursor(); // put cursor back where it belongs
|
||||||
}
|
}
|
||||||
// Flush screen updates before blocking
|
// Flush screen updates before blocking.
|
||||||
ui_flush();
|
ui_flush();
|
||||||
// Call `os_inchar` directly to block for events or user input without
|
// Call `os_inchar` directly to block for events or user input without
|
||||||
// consuming anything from `input_buffer`(os/input.c) or calling the
|
// consuming anything from `input_buffer`(os/input.c) or calling the
|
||||||
|
@ -875,25 +875,41 @@ describe('jobs', function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('hides cursor when waiting', function()
|
it('hides cursor and flushes messages before blocking', function()
|
||||||
local screen = Screen.new(30, 3)
|
local screen = Screen.new(50, 6)
|
||||||
screen:set_default_attr_ids({
|
screen:set_default_attr_ids({
|
||||||
[0] = {foreground = Screen.colors.Blue1, bold = true};
|
[0] = {foreground = Screen.colors.Blue, bold = true}; -- NonText
|
||||||
|
[1] = {bold = true, reverse = true}; -- MsgSeparator
|
||||||
|
[2] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg
|
||||||
})
|
})
|
||||||
screen:attach()
|
screen:attach()
|
||||||
command([[let g:id = jobstart([v:progpath, '--clean', '--headless'])]])
|
command([[let g:id = jobstart([v:progpath, '--clean', '--headless'])]])
|
||||||
feed_command('call jobwait([g:id], 300)')
|
source([[
|
||||||
|
func PrintAndWait()
|
||||||
|
echon "aaa\nbbb"
|
||||||
|
call jobwait([g:id], 300)
|
||||||
|
echon "\nccc"
|
||||||
|
endfunc
|
||||||
|
]])
|
||||||
|
feed_command('call PrintAndWait()')
|
||||||
screen:expect{grid=[[
|
screen:expect{grid=[[
|
||||||
|
|
|
|
||||||
{0:~ }|
|
{0:~ }|
|
||||||
:call jobwait([g:id], 300) |
|
{0:~ }|
|
||||||
|
{1: }|
|
||||||
|
aaa |
|
||||||
|
bbb |
|
||||||
]], timeout=100}
|
]], timeout=100}
|
||||||
funcs.jobstop(meths.get_var('id'))
|
|
||||||
screen:expect{grid=[[
|
screen:expect{grid=[[
|
||||||
^ |
|
|
|
||||||
{0:~ }|
|
{1: }|
|
||||||
:call jobwait([g:id], 300) |
|
aaa |
|
||||||
|
bbb |
|
||||||
|
ccc |
|
||||||
|
{2:Press ENTER or type command to continue}^ |
|
||||||
]]}
|
]]}
|
||||||
|
feed('<CR>')
|
||||||
|
funcs.jobstop(meths.get_var('id'))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -2559,7 +2559,6 @@ describe('lua stdlib', function()
|
|||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
it('should not block other events', function()
|
it('should not block other events', function()
|
||||||
eq({time = true, wait_result = true}, exec_lua[[
|
eq({time = true, wait_result = true}, exec_lua[[
|
||||||
start_time = get_time()
|
start_time = get_time()
|
||||||
@ -2601,6 +2600,7 @@ describe('lua stdlib', function()
|
|||||||
}
|
}
|
||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('should work with vim.defer_fn', function()
|
it('should work with vim.defer_fn', function()
|
||||||
eq({time = true, wait_result = true}, exec_lua[[
|
eq({time = true, wait_result = true}, exec_lua[[
|
||||||
start_time = get_time()
|
start_time = get_time()
|
||||||
|
@ -1312,17 +1312,54 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim
|
|||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('echo messages are shown correctly when getchar() immediately follows', function()
|
describe('echo messages are shown when immediately followed by', function()
|
||||||
feed([[:echo 'foo' | echo 'bar' | call getchar()<CR>]])
|
--- @param to_block string command to cause a blocking wait
|
||||||
screen:expect([[
|
--- @param to_unblock number|string number: timeout for blocking screen
|
||||||
|
|
--- string: keys to stop the blocking wait
|
||||||
{1:~ }|
|
local function test_flush_before_block(to_block, to_unblock)
|
||||||
{1:~ }|
|
local timeout = type(to_unblock) == 'number' and to_unblock or nil
|
||||||
{1:~ }|
|
exec(([[
|
||||||
{3: }|
|
func PrintAndWait()
|
||||||
foo |
|
echon "aaa\nbbb"
|
||||||
bar^ |
|
%s
|
||||||
]])
|
echon "\nccc"
|
||||||
|
endfunc
|
||||||
|
]]):format(to_block))
|
||||||
|
feed(':call PrintAndWait()<CR>')
|
||||||
|
screen:expect{grid=[[
|
||||||
|
|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{3: }|
|
||||||
|
aaa |
|
||||||
|
bbb^ |
|
||||||
|
]], timeout=timeout}
|
||||||
|
if type(to_unblock) == 'string' then
|
||||||
|
feed(to_unblock)
|
||||||
|
end
|
||||||
|
screen:expect{grid=[[
|
||||||
|
|
|
||||||
|
{1:~ }|
|
||||||
|
{3: }|
|
||||||
|
aaa |
|
||||||
|
bbb |
|
||||||
|
ccc |
|
||||||
|
{4:Press ENTER or type command to continue}^ |
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
|
||||||
|
it('getchar()', function()
|
||||||
|
test_flush_before_block([[call getchar()]], 'k')
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('wait()', function()
|
||||||
|
test_flush_before_block([[call wait(300, '0')]], 100)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('lua vim.wait()', function()
|
||||||
|
test_flush_before_block([[lua vim.wait(300, function() end)]], 100)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('consecutive calls to win_move_statusline() work after multiline message #21014',function()
|
it('consecutive calls to win_move_statusline() work after multiline message #21014',function()
|
||||||
|
Loading…
Reference in New Issue
Block a user