paste: workaround typeahead race

Workaround this failure:

    [  ERROR   ] test/functional/terminal/tui_spec.lua @ 192: TUI paste: exactly 64 bytes
    test/functional/helpers.lua:403:
    retry() attempts: 478
    test/functional/terminal/tui_spec.lua:201: Expected objects to be the same.
    Passed in:
    (table: 0x47cd77e8) {
     *[1] = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz endz' }
    Expected:
    (table: 0x47cd7830) {
     *[1] = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz end' }

This happens because `curwin->w_cursor.col` is sometimes decremented at
the end of `do_put`... because the editor is in Normal-mode instead of
the expected Insert-mode.

Caused by "typeahead race" (#10826): there may be queued input in the
main thread not yet processed, thus the editor mode (`State` global)
will be "wrong" during paste. Example: input "i" followed immediately by
a paste sequence:

    i<start-paste>...<stop-paste>
    ^
     "i" does not get processed in time, so the editor is in
     Normal-mode instead of Insert-mode while handling the paste.

Attempted workarounds:
- vim.api.nvim_feedkeys('','x',false) in vim._paste()
- exec_normal() in tinput_wait_enqueue()
- LOOP_PROCESS_EVENTS(&main_loop,…,0) in tinput_wait_enqueue()

ref #10826
This commit is contained in:
Justin M. Keyes
2019-08-22 00:19:46 +02:00
parent 5ae6849517
commit c95f5d166f

View File

@@ -191,8 +191,14 @@ describe('TUI', function()
it('paste: exactly 64 bytes #10311', function() it('paste: exactly 64 bytes #10311', function()
local expected = string.rep('z', 64) local expected = string.rep('z', 64)
feed_data('i')
-- Wait for Insert-mode (avoid "typeahead race" #10826).
retry(nil, nil, function()
local _, m = child_session:request('nvim_get_mode')
eq('i', m.mode)
end)
-- "bracketed paste" -- "bracketed paste"
feed_data('i\027[200~'..expected..'\027[201~') feed_data('\027[200~'..expected..'\027[201~')
feed_data(' end') feed_data(' end')
expected = expected..' end' expected = expected..' end'
retry(nil, nil, function() retry(nil, nil, function()
@@ -217,8 +223,14 @@ describe('TUI', function()
for i = 1, 3000 do for i = 1, 3000 do
t[i] = 'item ' .. tostring(i) t[i] = 'item ' .. tostring(i)
end end
feed_data('i')
-- Wait for Insert-mode (avoid "typeahead race" #10826).
retry(nil, nil, function()
local _, m = child_session:request('nvim_get_mode')
eq('i', m.mode)
end)
-- "bracketed paste" -- "bracketed paste"
feed_data('i\027[200~'..table.concat(t, '\n')..'\027[201~') feed_data('\027[200~'..table.concat(t, '\n')..'\027[201~')
retry(nil, nil, function() retry(nil, nil, function()
local _, buflines = child_session:request( local _, buflines = child_session:request(
'nvim_buf_get_lines', 0, 0, -1, false) 'nvim_buf_get_lines', 0, 0, -1, false)