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> " Author: w0rp <devw0rp@gmail.com>
" Description: Completion support for LSP linters " Description: Completion support for LSP linters
call ale#Set('completion_excluded_words', [])
let s:timer_id = -1 let s:timer_id = -1
let s:last_done_pos = [] let s:last_done_pos = []
@ -76,33 +78,49 @@ function! ale#completion#GetTriggerCharacter(filetype, prefix) abort
return '' return ''
endfunction 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... " For completing...
" foo. " foo.
" ^ " ^
" We need to include all of the given suggestions. " We need to include all of the given suggestions.
if a:prefix is# '.' 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 endif
let l:filtered_suggestions = [] if !empty(l:excluded_words)
" Copy the List if needed. We don't want to modify the argument.
" Filter suggestions down to those starting with the prefix we used for " We shouldn't make a copy if we don't need to.
" finding suggestions in the first place. if l:filtered_suggestions is a:suggestions
" let l:filtered_suggestions = copy(a:suggestions)
" 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 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 return l:filtered_suggestions
endfunction endfunction
@ -290,10 +308,12 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
return return
endif endif
let l:buffer = bufnr('')
let l:command = get(a:response, 'command', '') let l:command = get(a:response, 'command', '')
if l:command is# 'completions' if l:command is# 'completions'
let l:names = ale#completion#Filter( let l:names = ale#completion#Filter(
\ l:buffer,
\ ale#completion#ParseTSServerCompletions(a:response), \ ale#completion#ParseTSServerCompletions(a:response),
\ b:ale_completion_info.prefix, \ b:ale_completion_info.prefix,
\)[: g:ale_completion_max_suggestions - 1] \)[: 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( let b:ale_completion_info.request_id = ale#lsp#Send(
\ b:ale_completion_info.conn_id, \ b:ale_completion_info.conn_id,
\ ale#lsp#tsserver_message#CompletionEntryDetails( \ ale#lsp#tsserver_message#CompletionEntryDetails(
\ bufnr(''), \ l:buffer,
\ b:ale_completion_info.line, \ b:ale_completion_info.line,
\ b:ale_completion_info.column, \ b:ale_completion_info.column,
\ l:names, \ 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 only suggest so many possible matches for completion. The maximum number of
items can be controlled with |g:ale_completion_max_suggestions|. 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* 5.2 Go To Definition *ale-go-to-definition*
@ -763,6 +766,24 @@ g:ale_completion_enabled *g:ale_completion_enabled*
See |ale-completion| 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* g:ale_completion_max_suggestions *g:ale_completion_max_suggestions*
Type: |Number| 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): Execute(Prefix filtering should work for Lists of strings):
AssertEqual AssertEqual
\ ['FooBar', 'foo'], \ ['FooBar', 'foo'],
\ ale#completion#Filter(['FooBar', 'FongBar', 'baz', 'foo'], 'foo') \ ale#completion#Filter(bufnr(''), ['FooBar', 'FongBar', 'baz', 'foo'], 'foo')
AssertEqual AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'], \ ['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): Execute(Prefix filtering should work for completion items):
AssertEqual AssertEqual
\ [{'word': 'FooBar'}, {'word': 'foo'}], \ [{'word': 'FooBar'}, {'word': 'foo'}],
\ ale#completion#Filter( \ ale#completion#Filter(
\ bufnr(''),
\ [ \ [
\ {'word': 'FooBar'}, \ {'word': 'FooBar'},
\ {'word': 'FongBar'}, \ {'word': 'FongBar'},
@ -18,6 +30,7 @@ Execute(Prefix filtering should work for completion items):
\ ], \ ],
\ 'foo' \ 'foo'
\ ) \ )
AssertEqual AssertEqual
\ [ \ [
\ {'word': 'FooBar'}, \ {'word': 'FooBar'},
@ -26,6 +39,7 @@ Execute(Prefix filtering should work for completion items):
\ {'word': 'foo'}, \ {'word': 'foo'},
\ ], \ ],
\ ale#completion#Filter( \ ale#completion#Filter(
\ bufnr(''),
\ [ \ [
\ {'word': 'FooBar'}, \ {'word': 'FooBar'},
\ {'word': 'FongBar'}, \ {'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'}]