vim-patch:9.2.0739: completion: 'autocompletedelay' blocks the main loop and drops autocommands

Problem:  With a non-zero 'autocompletedelay', Insert-mode autocommands
          (TextChangedI, TextChangedP, CursorMovedI) are delayed, and
          while typing faster than the delay they are dropped entirely,
          because the delay blocks the main loop.
Solution: Make 'autocompletedelay' non-blocking: instead of busy-waiting
          before showing the popup menu, defer it with an input-wait
          timeout (K_COMPLETE_DELAY) modeled on CursorHoldI, so typing
          stays responsive and the Insert-mode autocommands fire normally.

The delay timer coexists with 'updatetime': the main loop waits for the
sooner of the two and triggers the event whose deadline was reached, so
'autocompletedelay' no longer shadows CursorHold timing.  Changing the
completion leader, for example with Backspace, updates the visible popup
immediately like a zero delay; only the first popup is deferred.

Update the 'autocompletedelay' screendumps for the non-blocking display.
One test opened the menu with CTRL-N right after the delay expired and
could race with the deferred popup, so it now waits a little longer than
the delay before sending the key.

fixes:  vim/vim#20591
closes: vim/vim#20598

8ce43ea4e3

Also include some insexpand.c and ui.c changes from patch 9.2.0750.

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
zeertzjq
2026-07-01 17:00:08 +08:00
parent 7a4186e1d5
commit 14f2a86cd6
6 changed files with 117 additions and 56 deletions

View File

@@ -1552,15 +1552,6 @@ describe('completion', function()
{5:-- INSERT --} |
]])
feed('<BS>')
screen:expect([[
foo |
foobar |
foobarbaz |
f^ |
{1:~ }|*5
{5:-- INSERT --} |
]])
vim.uv.sleep(500)
screen:expect([[
foo |
foobar |
@@ -1572,6 +1563,8 @@ describe('completion', function()
{1:~ }|*2
{5:-- INSERT --} |
]])
vim.uv.sleep(500)
screen:expect_unchanged()
-- During delay wait, user can open menu using CTRL_N completion
feed('<Esc>')
@@ -1589,7 +1582,9 @@ describe('completion', function()
{5:-- Keyword completion (^N^P) }{6:match 1 of 3} |
]])
-- After the menu is open, ^N/^P and Up/Down should not delay
-- After the menu is open, ^N/^P and Up/Down should not delay.
-- Wait a bit longer than 'autocompletedelay' so the popup is surely shown
-- before sending CTRL-N, otherwise the keys race with the deferred popup.
feed('<Esc>')
command('set completeopt=menu')
feed('Sf')
@@ -1601,7 +1596,7 @@ describe('completion', function()
{1:~ }|*5
{5:-- INSERT --} |
]])
vim.uv.sleep(500)
vim.uv.sleep(600)
screen:expect([[
foo |
foobar |
@@ -1734,7 +1729,7 @@ describe('completion', function()
screen:expect([[
autocomplete |
autocomxxx |
au{102:^tocom} |
au^ |
{1:~ }|*4
{5:-- INSERT --} |
]])
@@ -1742,7 +1737,7 @@ describe('completion', function()
screen:expect([[
autocomplete |
autocomxxx |
autoc{102:^om} |
autoc^ |
{1:~ }|*4
{5:-- INSERT --} |
]])
@@ -1762,7 +1757,7 @@ describe('completion', function()
screen:expect([[
autocomplete |
autocomxxx |
aut{102:^ocom} |
aut^ |
{1:~ }|*4
{5:-- INSERT --} |
]])
@@ -1770,7 +1765,7 @@ describe('completion', function()
screen:expect([[
autocomplete |
autocomxxx |
au{102:^tocom} |
au^ |
{1:~ }|*4
{5:-- INSERT --} |
]])
@@ -1793,7 +1788,7 @@ describe('completion', function()
screen:expect([[
autocomplete |
autocomxxx |
au{102:^tocomplete} |
au^ |
{1:~ }|*4
{5:-- INSERT --} |
]])