mirror of
https://github.com/dense-analysis/ale.git
synced 2026-06-16 04:26:27 +08:00
Fix infinite autocompletion loop (#5130)
CI / Build (push) Has been cancelled
CI / Neovim 0.10 Windows (push) Has been cancelled
CI / Neovim 0.12 Windows (push) Has been cancelled
CI / Vim 8.2 Windows (push) Has been cancelled
CI / Vim 9.2 Windows (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Lua (push) Has been cancelled
CI / Neovim 0.10 Linux (push) Has been cancelled
CI / Neovim 0.12 Linux (push) Has been cancelled
CI / Vim 8.2 Linux (push) Has been cancelled
CI / Vim 9.2 Linux (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Neovim 0.10 Windows (push) Has been cancelled
CI / Neovim 0.12 Windows (push) Has been cancelled
CI / Vim 8.2 Windows (push) Has been cancelled
CI / Vim 9.2 Windows (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Lua (push) Has been cancelled
CI / Neovim 0.10 Linux (push) Has been cancelled
CI / Neovim 0.12 Linux (push) Has been cancelled
CI / Vim 8.2 Linux (push) Has been cancelled
CI / Vim 9.2 Linux (push) Has been cancelled
* Check for timeout while waiting for language server result * Return empty result if language server has no completion capabilities * Add test for OmniFunc timeout * Add documentation for timeout option
This commit is contained in:
@@ -764,6 +764,9 @@ function! s:OnReady(linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'completion')
|
||||
" Return at least an empty result to avoid OmniFunc timeout
|
||||
call ale#completion#Show([])
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
@@ -945,9 +948,18 @@ function! ale#completion#OmniFunc(findstart, base) abort
|
||||
else
|
||||
let l:result = ale#completion#GetCompletionResult()
|
||||
|
||||
let l:timeout = get(g:, 'ale_completion_timeout', 3)
|
||||
let l:timeout_start = reltime()
|
||||
|
||||
while l:result is v:null && !complete_check()
|
||||
sleep 2ms
|
||||
let l:result = ale#completion#GetCompletionResult()
|
||||
|
||||
if reltimefloat(reltime(l:timeout_start)) > l:timeout
|
||||
" no-custom-checks
|
||||
echoerr 'no result within timeout (' . l:timeout . 's)'
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
return l:result isnot v:null ? l:result : []
|
||||
|
||||
+14
@@ -1143,6 +1143,20 @@ g:ale_completion_max_suggestions
|
||||
Adjust this option as needed, depending on the complexity of your codebase
|
||||
and your available processing power.
|
||||
|
||||
*ale-options.completion_timeout*
|
||||
*g:ale_completion_timeout*
|
||||
completion_timeout
|
||||
g:ale_completion_timeout
|
||||
Type: |Number|
|
||||
Default: `3`
|
||||
|
||||
The maximum time in seconds ale#completion#OmniFunc() will wait for a
|
||||
completion result from the language server.
|
||||
|
||||
When the timeout is exceeded ale#completion#OmniFunc() will print an error
|
||||
message and return an empty result. Setting a higher value allows longer
|
||||
response times, but it may also keep Vim unresponsible for a longer time.
|
||||
|
||||
*ale-options.cursor_detail*
|
||||
*g:ale_cursor_detail*
|
||||
cursor_detail
|
||||
|
||||
@@ -58,3 +58,10 @@ Execute(The omnifunc function should parse and return async responses):
|
||||
|
||||
AssertEqual ['foo'], ale#completion#OmniFunc(0, '')
|
||||
endif
|
||||
|
||||
Execute (The omnifunc function should timeout with an error, if no result is returned):
|
||||
" WARNING: This will lock the whole test-suite, if the timeout does not work!
|
||||
let g:ale_completion_timeout = 0.2
|
||||
|
||||
AssertThrows call ale#completion#OmniFunc(0, '')
|
||||
AssertEqual 'Vim(echoerr):no result within timeout (0.2s)', g:vader_exception
|
||||
|
||||
Reference in New Issue
Block a user