diff options
-rw-r--r-- | autoload/ale/completion.vim | 66 | ||||
-rw-r--r-- | test/completion/test_completion_events.vader | 32 |
2 files changed, 70 insertions, 28 deletions
diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index 0f9ae4e0..e7da4028 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -1,6 +1,17 @@ " Author: w0rp <devw0rp@gmail.com> " Description: Completion support for LSP linters +" The omnicompletion menu is shown through a special Plug mapping which is +" only valid in Insert mode. This way, feedkeys() won't send these keys if you +" quit Insert mode quickly enough. +inoremap <silent> <Plug>(ale_show_completion_menu) <C-x><C-o> +" If we hit the key sequence in normal mode, then we won't show the menu, so +" we should restore the old settings right away. +nnoremap <silent> <Plug>(ale_show_completion_menu) :call ale#completion#RestoreCompletionOptions()<CR> +cnoremap <silent> <Plug>(ale_show_completion_menu) <Nop> +vnoremap <silent> <Plug>(ale_show_completion_menu) <Nop> +onoremap <silent> <Plug>(ale_show_completion_menu) <Nop> + let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100) let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', []) let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50) @@ -129,7 +140,16 @@ function! ale#completion#Filter(buffer, suggestions, prefix) abort return l:filtered_suggestions endfunction -function! s:ReplaceCompleteopt() abort +function! s:ReplaceCompletionOptions() abort + " Remember the old omnifunc value, if there is one. + " If we don't store an old one, we'll just never reset the option. + " This will stop some random exceptions from appearing. + if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc) + let b:ale_old_omnifunc = &l:omnifunc + endif + + let &l:omnifunc = 'ale#completion#OmniFunc' + if !exists('b:ale_old_completopt') let b:ale_old_completopt = &l:completeopt endif @@ -141,6 +161,22 @@ function! s:ReplaceCompleteopt() abort endif endfunction +function! ale#completion#RestoreCompletionOptions() abort + " Reset settings when completion is done. + if exists('b:ale_old_omnifunc') + if b:ale_old_omnifunc isnot# 'pythoncomplete#Complete' + let &l:omnifunc = b:ale_old_omnifunc + endif + + unlet b:ale_old_omnifunc + endif + + if exists('b:ale_old_completopt') + let &l:completeopt = b:ale_old_completopt + unlet b:ale_old_completopt + endif +endfunction + function! ale#completion#OmniFunc(findstart, base) abort if a:findstart let l:line = b:ale_completion_info.line @@ -163,7 +199,7 @@ function! ale#completion#OmniFunc(findstart, base) abort let b:ale_completion_result = function(l:parser)(l:response) endif - call s:ReplaceCompleteopt() + call s:ReplaceCompletionOptions() return get(b:, 'ale_completion_result', []) endif @@ -174,20 +210,12 @@ function! ale#completion#Show(response, completion_parser) abort return endif - " Remember the old omnifunc value, if there is one. - " If we don't store an old one, we'll just never reset the option. - " This will stop some random exceptions from appearing. - if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc) - let b:ale_old_omnifunc = &l:omnifunc - endif - " Set the list in the buffer, temporarily replace omnifunc with our " function, and then start omni-completion. let b:ale_completion_response = a:response let b:ale_completion_parser = a:completion_parser - let &l:omnifunc = 'ale#completion#OmniFunc' - call s:ReplaceCompleteopt() - call ale#util#FeedKeys("\<C-x>\<C-o>", 'n') + call s:ReplaceCompletionOptions() + call ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)") endfunction function! s:CompletionStillValid(request_id) abort @@ -523,19 +551,7 @@ endfunction function! ale#completion#Done() abort silent! pclose - " Reset settings when completion is done. - if exists('b:ale_old_omnifunc') - if b:ale_old_omnifunc isnot# 'pythoncomplete#Complete' - let &l:omnifunc = b:ale_old_omnifunc - endif - - unlet b:ale_old_omnifunc - endif - - if exists('b:ale_old_completopt') - let &l:completeopt = b:ale_old_completopt - unlet b:ale_old_completopt - endif + call ale#completion#RestoreCompletionOptions() let s:last_done_pos = getcurpos()[1:2] endfunction diff --git a/test/completion/test_completion_events.vader b/test/completion/test_completion_events.vader index 504d79c2..f8cf268c 100644 --- a/test/completion/test_completion_events.vader +++ b/test/completion/test_completion_events.vader @@ -14,8 +14,8 @@ Before: runtime autoload/ale/util.vim - function! ale#util#FeedKeys(string, mode) abort - call add(g:feedkeys_calls, [a:string, a:mode]) + function! ale#util#FeedKeys(string) abort + call add(g:feedkeys_calls, [a:string]) endfunction " Pretend we're in insert mode for most tests. @@ -41,6 +41,7 @@ Before: After: Restore + unlet! g:output unlet! g:fake_mode unlet! g:get_completions_called unlet! b:ale_old_omnifunc @@ -155,7 +156,7 @@ Execute(ale#completion#OmniFunc() should set the preview option if it's set): Execute(ale#completion#Show() should make the correct feedkeys() call): call ale#completion#Show('Response', 'Parser') - AssertEqual [["\<C-x>\<C-o>", 'n']], g:feedkeys_calls + AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls Execute(ale#completion#Show() shouldn't do anything if you switch back to normal mode): let &l:completeopt = 'menu,preview' @@ -225,3 +226,28 @@ Execute(b:ale_completion_info should be set up correctly when requesting complet \ 'prefix': 'ab', \ }, \ b:ale_completion_info + +Execute(The correct keybinds should be configured): + redir => g:output + silent map <Plug>(ale_show_completion_menu) + redir END + + AssertEqual + \ [ + \ 'n <Plug>(ale_show_completion_menu) * :call ale#completion#RestoreCompletionOptions()<CR>', + \ 'o <Plug>(ale_show_completion_menu) * <Nop>', + \ 'v <Plug>(ale_show_completion_menu) * <Nop>', + \ ], + \ sort(split(g:output, "\n")) + +Execute(Running the normal mode <Plug> keybind should reset the settings): + let b:ale_old_omnifunc = 'FooBar' + let b:ale_old_completopt = 'menu' + + " We can't run the keybind, but we can call the function. + call ale#completion#RestoreCompletionOptions() + + AssertEqual 'FooBar', &l:omnifunc + AssertEqual 'menu', &l:completeopt + Assert !has_key(b:, 'ale_old_omnifunc') + Assert !has_key(b:, 'ale_old_completopt') |