diff options
-rw-r--r-- | README.md | 27 | ||||
-rw-r--r-- | autoload/ale/completion.vim | 60 | ||||
-rw-r--r-- | autoload/ale/fix.vim | 4 | ||||
-rw-r--r-- | doc/ale.txt | 21 | ||||
-rw-r--r-- | test/completion/test_completion_filtering.vader | 76 |
5 files changed, 157 insertions, 31 deletions
@@ -16,8 +16,18 @@ back to a filesystem. In other words, this plugin allows you to lint while you type. -In addition to linting support, ALE offers some support for fixing code with -formatting tools, and some Language Server Protocol and `tsserver` features. +ALE offers support for fixing code with command line tools in a non-blocking +manner with the `:ALEFix` feature, supporting tools in many languages, like +`prettier`, `eslint`, `autopep8`, and more. + +ALE acts as a "language client" to support a variety of Language Server Protocol +features, including: + +* Diagnostics (via Language Server Protocol linters) +* Go To Definition (`:ALEGoToDefinition`) +* Completion (`let g:ale_completion_enabled = 1`) +* Finding references (`:ALEFindReferences`) +* Hover information (`:ALEHover`) ## Table of Contents @@ -116,7 +126,7 @@ formatting. | HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) | | Idris | [idris](http://www.idris-lang.org/) | | Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/) | -| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo) +| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo) | JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) | | Kotlin | [kotlinc](https://kotlinlang.org) !!, [ktlint](https://ktlint.github.io) !! see `:help ale-integration-kotlin` for configuration instructions | | LaTeX | [alex](https://github.com/wooorm/alex) !!, [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | @@ -238,7 +248,8 @@ See `:help ale-completion` for more information. ### 2.iv Go To Definition ALE supports jumping to the definition of words under your cursor with the -`:ALEGoToDefinition` command using any enabled LSP linters and `tsserver`. +`:ALEGoToDefinition` command using any enabled Language Server Protocol linters +and `tsserver`. See `:help ale-go-to-definition` for more information. @@ -247,7 +258,8 @@ See `:help ale-go-to-definition` for more information. ### 2.v Find References ALE supports finding references for words under your cursor with the -`:ALEFindReferences` command using any enabled LSP linters and `tsserver`. +`:ALEFindReferences` command using any enabled Language Server Protocol linters +and `tsserver`. See `:help ale-find-references` for more information. @@ -255,8 +267,9 @@ See `:help ale-find-references` for more information. ### 2.vi Hovering -ALE supports "hover" information for printing brief information about symbols -at the cursor taken from LSP linters with the `ALEHover` command. +ALE supports "hover" information for printing brief information about symbols at +the cursor taken from Language Server Protocol linters and `tsserver` with the +`ALEHover` command. See `:help ale-hover` for more information. diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index 29b1df1f..c15a4867 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -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, diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim index 03855ef8..51df1458 100644 --- a/autoload/ale/fix.vim +++ b/autoload/ale/fix.vim @@ -28,8 +28,6 @@ function! ale#fix#ApplyQueuedFixes() abort call remove(g:ale_fix_buffer_data, l:buffer) if l:data.changes_made - call setline(1, l:data.output) - let l:start_line = len(l:data.output) + 1 let l:end_line = len(l:data.lines_before) @@ -39,6 +37,8 @@ function! ale#fix#ApplyQueuedFixes() abort call winrestview(l:save) endif + call setline(1, l:data.output) + if l:data.should_save if empty(&buftype) noautocmd :w! diff --git a/doc/ale.txt b/doc/ale.txt index f1e784ae..4a926386 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -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| diff --git a/test/completion/test_completion_filtering.vader b/test/completion/test_completion_filtering.vader index 3e461aef..ae91a952 100644 --- a/test/completion/test_completion_filtering.vader +++ b/test/completion/test_completion_filtering.vader @@ -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'}] |