Add g:ale_completion_excluded_words for completion filtering

This commit is contained in:
w0rp 2018-05-03 11:17:41 +01:00
parent e59cd6b7c0
commit e2c33f2f6c
No known key found for this signature in database
GPG Key ID: 0FC1ECAA8C81CD83
3 changed files with 135 additions and 22 deletions

View File

@ -1,6 +1,8 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Completion support for LSP linters
call ale#Set('completion_excluded_words', [])
let s:timer_id = -1
let s:last_done_pos = []
@ -76,33 +78,49 @@ function! ale#completion#GetTriggerCharacter(filetype, prefix) abort
return ''
endfunction
function! ale#completion#Filter(suggestions, prefix) abort
function! ale#completion#Filter(buffer, suggestions, prefix) abort
let l:excluded_words = ale#Var(a:buffer, 'completion_excluded_words')
" For completing...
" foo.
" ^
" We need to include all of the given suggestions.
if a:prefix is# '.'
return a:suggestions
let l:filtered_suggestions = a:suggestions
else
let l:filtered_suggestions = []
" Filter suggestions down to those starting with the prefix we used for
" finding suggestions in the first place.
"
" Some completion tools will include suggestions which don't even start
" with the characters we have already typed.
for l:item in a:suggestions
" A List of String values or a List of completion item Dictionaries
" is accepted here.
let l:word = type(l:item) == type('') ? l:item : l:item.word
" Add suggestions if the suggestion starts with a case-insensitive
" match for the prefix.
if l:word[: len(a:prefix) - 1] is? a:prefix
call add(l:filtered_suggestions, l:item)
endif
endfor
endif
let l:filtered_suggestions = []
" Filter suggestions down to those starting with the prefix we used for
" finding suggestions in the first place.
"
" Some completion tools will include suggestions which don't even start
" with the characters we have already typed.
for l:item in a:suggestions
" A List of String values or a List of completion item Dictionaries
" is accepted here.
let l:word = type(l:item) == type('') ? l:item : l:item.word
" Add suggestions if the suggestion starts with a case-insensitive
" match for the prefix.
if l:word[: len(a:prefix) - 1] is? a:prefix
call add(l:filtered_suggestions, l:item)
if !empty(l:excluded_words)
" Copy the List if needed. We don't want to modify the argument.
" We shouldn't make a copy if we don't need to.
if l:filtered_suggestions is a:suggestions
let l:filtered_suggestions = copy(a:suggestions)
endif
endfor
" Remove suggestions with words in the exclusion List.
call filter(
\ l:filtered_suggestions,
\ 'index(l:excluded_words, type(v:val) is type('''') ? v:val : v:val.word) < 0',
\)
endif
return l:filtered_suggestions
endfunction
@ -290,10 +308,12 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
return
endif
let l:buffer = bufnr('')
let l:command = get(a:response, 'command', '')
if l:command is# 'completions'
let l:names = ale#completion#Filter(
\ l:buffer,
\ ale#completion#ParseTSServerCompletions(a:response),
\ b:ale_completion_info.prefix,
\)[: g:ale_completion_max_suggestions - 1]
@ -302,7 +322,7 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
let b:ale_completion_info.request_id = ale#lsp#Send(
\ b:ale_completion_info.conn_id,
\ ale#lsp#tsserver_message#CompletionEntryDetails(
\ bufnr(''),
\ l:buffer,
\ b:ale_completion_info.line,
\ b:ale_completion_info.column,
\ l:names,

View File

@ -631,6 +631,9 @@ delay for completion can be configured with |g:ale_completion_delay|. ALE will
only suggest so many possible matches for completion. The maximum number of
items can be controlled with |g:ale_completion_max_suggestions|.
If you don't like some of the suggestions you see, you can filter them out
with |g:ale_completion_excluded_words| or |b:ale_completion_excluded_words|.
-------------------------------------------------------------------------------
5.2 Go To Definition *ale-go-to-definition*
@ -763,6 +766,24 @@ g:ale_completion_enabled *g:ale_completion_enabled*
See |ale-completion|
g:ale_completion_excluded_words *g:ale_completion_excluded_words*
*b:ale_completion_excluded_words*
Type: |List|
Default: `[]`
This option can be set to a list of |String| values for "words" to exclude
from completion results, as in the words for |complete-items|. The strings
will be matched exactly in a case-sensitive manner. (|==#|)
This setting can be configured in ftplugin files with buffer variables, so
that different lists can be used for different filetypes. For example: >
" In ~/.vim/ftplugin/typescript.vim
" Don't suggest `it` or `describe` so we can use snippets for those words.
let b:ale_completion_excluded_words = ['it', 'describe']
<
g:ale_completion_max_suggestions *g:ale_completion_max_suggestions*
Type: |Number|

View File

@ -1,15 +1,27 @@
Before:
Save g:ale_completion_excluded_words
let g:ale_completion_excluded_words = []
After:
Restore
unlet! b:ale_completion_excluded_words
unlet! b:suggestions
Execute(Prefix filtering should work for Lists of strings):
AssertEqual
\ ['FooBar', 'foo'],
\ ale#completion#Filter(['FooBar', 'FongBar', 'baz', 'foo'], 'foo')
\ ale#completion#Filter(bufnr(''), ['FooBar', 'FongBar', 'baz', 'foo'], 'foo')
AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'],
\ ale#completion#Filter(['FooBar', 'FongBar', 'baz', 'foo'], '.')
\ ale#completion#Filter(bufnr(''), ['FooBar', 'FongBar', 'baz', 'foo'], '.')
Execute(Prefix filtering should work for completion items):
AssertEqual
\ [{'word': 'FooBar'}, {'word': 'foo'}],
\ ale#completion#Filter(
\ bufnr(''),
\ [
\ {'word': 'FooBar'},
\ {'word': 'FongBar'},
@ -18,6 +30,7 @@ Execute(Prefix filtering should work for completion items):
\ ],
\ 'foo'
\ )
AssertEqual
\ [
\ {'word': 'FooBar'},
@ -26,6 +39,7 @@ Execute(Prefix filtering should work for completion items):
\ {'word': 'foo'},
\ ],
\ ale#completion#Filter(
\ bufnr(''),
\ [
\ {'word': 'FooBar'},
\ {'word': 'FongBar'},
@ -34,3 +48,61 @@ Execute(Prefix filtering should work for completion items):
\ ],
\ '.'
\ )
Execute(Excluding words from completion results should work):
let b:ale_completion_excluded_words = ['it', 'describe']
AssertEqual
\ [{'word': 'Italian'}],
\ ale#completion#Filter(
\ bufnr(''),
\ [
\ {'word': 'Italian'},
\ {'word': 'it'},
\ ],
\ 'it'
\ )
AssertEqual
\ [{'word': 'Deutsch'}],
\ ale#completion#Filter(
\ bufnr(''),
\ [
\ {'word': 'describe'},
\ {'word': 'Deutsch'},
\ ],
\ 'de'
\ )
AssertEqual
\ [{'word': 'Deutsch'}],
\ ale#completion#Filter(
\ bufnr(''),
\ [
\ {'word': 'describe'},
\ {'word': 'Deutsch'},
\ ],
\ '.'
\ )
Execute(Excluding words from completion results should work with lists of Strings):
let b:ale_completion_excluded_words = ['it', 'describe']
AssertEqual
\ ['Italian'],
\ ale#completion#Filter(bufnr(''), ['Italian', 'it'], 'it')
AssertEqual
\ ['Deutsch'],
\ ale#completion#Filter(bufnr(''), ['describe', 'Deutsch'], 'de')
AssertEqual
\ ['Deutsch'],
\ ale#completion#Filter(bufnr(''), ['describe', 'Deutsch'], '.')
Execute(Filtering shouldn't modify the original list):
let b:ale_completion_excluded_words = ['it', 'describe']
let b:suggestions = [{'word': 'describe'}]
AssertEqual [], ale#completion#Filter(bufnr(''), b:suggestions, '.')
AssertEqual b:suggestions, [{'word': 'describe'}]
AssertEqual [], ale#completion#Filter(bufnr(''), b:suggestions, 'de')
AssertEqual b:suggestions, [{'word': 'describe'}]