mirror of
https://github.com/dense-analysis/ale.git
synced 2026-08-12 02:42:30 +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
|
let l:id = a:lsp_details.connection_id
|
||||||
|
|
||||||
if !ale#lsp#HasCapability(l:id, 'completion')
|
if !ale#lsp#HasCapability(l:id, 'completion')
|
||||||
|
" Return at least an empty result to avoid OmniFunc timeout
|
||||||
|
call ale#completion#Show([])
|
||||||
|
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -945,9 +948,18 @@ function! ale#completion#OmniFunc(findstart, base) abort
|
|||||||
else
|
else
|
||||||
let l:result = ale#completion#GetCompletionResult()
|
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()
|
while l:result is v:null && !complete_check()
|
||||||
sleep 2ms
|
sleep 2ms
|
||||||
let l:result = ale#completion#GetCompletionResult()
|
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
|
endwhile
|
||||||
|
|
||||||
return l:result isnot v:null ? l:result : []
|
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
|
Adjust this option as needed, depending on the complexity of your codebase
|
||||||
and your available processing power.
|
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*
|
*ale-options.cursor_detail*
|
||||||
*g:ale_cursor_detail*
|
*g:ale_cursor_detail*
|
||||||
cursor_detail
|
cursor_detail
|
||||||
|
|||||||
@@ -58,3 +58,10 @@ Execute(The omnifunc function should parse and return async responses):
|
|||||||
|
|
||||||
AssertEqual ['foo'], ale#completion#OmniFunc(0, '')
|
AssertEqual ['foo'], ale#completion#OmniFunc(0, '')
|
||||||
endif
|
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