summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoload/ale/completion.vim164
-rw-r--r--doc/ale.txt78
-rw-r--r--test/completion/test_lsp_completion_parsing.vader20
-rw-r--r--test/completion/test_tsserver_completion_parsing.vader10
4 files changed, 211 insertions, 61 deletions
diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim
index fb87f1bb..da24e839 100644
--- a/autoload/ale/completion.vim
+++ b/autoload/ale/completion.vim
@@ -1,5 +1,6 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Completion support for LSP linters
+scriptencoding utf-8
" 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
@@ -21,24 +22,101 @@ let s:timer_id = -1
let s:last_done_pos = []
" CompletionItemKind values from the LSP protocol.
-let s:LSP_COMPLETION_TEXT_KIND = 1
-let s:LSP_COMPLETION_METHOD_KIND = 2
-let s:LSP_COMPLETION_FUNCTION_KIND = 3
-let s:LSP_COMPLETION_CONSTRUCTOR_KIND = 4
-let s:LSP_COMPLETION_FIELD_KIND = 5
-let s:LSP_COMPLETION_VARIABLE_KIND = 6
-let s:LSP_COMPLETION_CLASS_KIND = 7
-let s:LSP_COMPLETION_INTERFACE_KIND = 8
-let s:LSP_COMPLETION_MODULE_KIND = 9
-let s:LSP_COMPLETION_PROPERTY_KIND = 10
-let s:LSP_COMPLETION_UNIT_KIND = 11
-let s:LSP_COMPLETION_VALUE_KIND = 12
-let s:LSP_COMPLETION_ENUM_KIND = 13
-let s:LSP_COMPLETION_KEYWORD_KIND = 14
-let s:LSP_COMPLETION_SNIPPET_KIND = 15
-let s:LSP_COMPLETION_COLOR_KIND = 16
-let s:LSP_COMPLETION_FILE_KIND = 17
-let s:LSP_COMPLETION_REFERENCE_KIND = 18
+let g:ale_lsp_types = {
+\ 1: 'text',
+\ 2: 'method',
+\ 3: 'function',
+\ 4: 'constructor',
+\ 5: 'field',
+\ 6: 'variable',
+\ 7: 'class',
+\ 8: 'interface',
+\ 9: 'module',
+\ 10: 'property',
+\ 11: 'unit',
+\ 12: 'value',
+\ 13: 'enum',
+\ 14: 'keyword',
+\ 15: 'snippet',
+\ 16: 'color',
+\ 17: 'file',
+\ 18: 'reference',
+\ 19: 'folder',
+\ 20: 'enum_member',
+\ 21: 'constant',
+\ 22: 'struct',
+\ 23: 'event',
+\ 24: 'operator',
+\ 25: 'type_parameter',
+\ }
+
+" from https://github.com/microsoft/TypeScript/blob/29becf05012bfa7ba20d50b0d16813971e46b8a6/lib/protocol.d.ts#L2472
+let g:ale_tsserver_types = {
+\ 'warning': 'text',
+\ 'keyword': 'keyword',
+\ 'script': 'file',
+\ 'module': 'module',
+\ 'class': 'class',
+\ 'local class': 'class',
+\ 'interface': 'interface',
+\ 'type': 'class',
+\ 'enum': 'enum',
+\ 'enum member': 'enum_member',
+\ 'var': 'variable',
+\ 'local var': 'variable',
+\ 'function': 'function',
+\ 'local function': 'function',
+\ 'method': 'method',
+\ 'getter': 'property',
+\ 'setter': 'method',
+\ 'property': 'property',
+\ 'constructor': 'constructor',
+\ 'call': 'method',
+\ 'index': 'index',
+\ 'construct': 'constructor',
+\ 'parameter': 'parameter',
+\ 'type parameter': 'type_parameter',
+\ 'primitive type': 'unit',
+\ 'label': 'text',
+\ 'alias': 'class',
+\ 'const': 'constant',
+\ 'let': 'variable',
+\ 'directory': 'folder',
+\ 'external module name': 'text',
+\ 'JSX attribute': 'parameter',
+\ 'string': 'text'
+\ }
+
+" For compatibility reasons, we only use built in VIM completion kinds
+" See :help complete-items for Vim completion kinds
+let g:ale_completion_symbols = get(g:, 'ale_completion_symbols', {
+\ 'text': 'v',
+\ 'method': 'f',
+\ 'function': 'f',
+\ 'constructor': 'f',
+\ 'field': 'm',
+\ 'variable': 'v',
+\ 'class': 't',
+\ 'interface': 't',
+\ 'module': 'd',
+\ 'property': 'm',
+\ 'unit': 'v',
+\ 'value': 'v',
+\ 'enum': 't',
+\ 'keyword': 'v',
+\ 'snippet': 'v',
+\ 'color': 'v',
+\ 'file': 'v',
+\ 'reference': 'v',
+\ 'folder': 'v',
+\ 'enum_member': 'm',
+\ 'constant': 'm',
+\ 'struct': 't',
+\ 'event': 'v',
+\ 'operator': 'f',
+\ 'type_parameter': 'p',
+\ '<default>': 'v'
+\ })
let s:LSP_INSERT_TEXT_FORMAT_PLAIN = 1
let s:LSP_INSERT_TEXT_FORMAT_SNIPPET = 2
@@ -278,6 +356,27 @@ function! ale#completion#GetAllTriggers() abort
return deepcopy(s:trigger_character_map)
endfunction
+function! ale#completion#GetCompletionKind(kind) abort
+ let l:lsp_symbol = get(g:ale_lsp_types, a:kind, '')
+
+ if !empty(l:lsp_symbol)
+ return l:lsp_symbol
+ endif
+
+ return get(g:ale_tsserver_types, a:kind, '')
+endfunction
+
+function! ale#completion#GetCompletionSymbols(kind) abort
+ let l:kind = ale#completion#GetCompletionKind(a:kind)
+ let l:symbol = get(g:ale_completion_symbols, l:kind, '')
+
+ if !empty(l:symbol)
+ return l:symbol
+ endif
+
+ return get(g:ale_completion_symbols, '<default>', 'v')
+endfunction
+
function! s:CompletionStillValid(request_id) abort
let [l:line, l:column] = getpos('.')[1:2]
@@ -329,18 +428,10 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
call add(l:documentationParts, l:part.text)
endfor
- if l:suggestion.kind is# 'className'
- let l:kind = 'f'
- elseif l:suggestion.kind is# 'parameterName'
- let l:kind = 'f'
- else
- let l:kind = 'v'
- endif
-
" See :help complete-items
let l:result = {
\ 'word': l:suggestion.name,
- \ 'kind': l:kind,
+ \ 'kind': ale#completion#GetCompletionSymbols(l:suggestion.kind),
\ 'icase': 1,
\ 'menu': join(l:displayParts, ''),
\ 'dup': g:ale_completion_tsserver_autoimport,
@@ -425,23 +516,6 @@ function! ale#completion#ParseLSPCompletions(response) abort
continue
endif
- " See :help complete-items for Vim completion kinds
- if !has_key(l:item, 'kind')
- let l:kind = 'v'
- elseif l:item.kind is s:LSP_COMPLETION_METHOD_KIND
- let l:kind = 'm'
- elseif l:item.kind is s:LSP_COMPLETION_CONSTRUCTOR_KIND
- let l:kind = 'm'
- elseif l:item.kind is s:LSP_COMPLETION_FUNCTION_KIND
- let l:kind = 'f'
- elseif l:item.kind is s:LSP_COMPLETION_CLASS_KIND
- let l:kind = 'f'
- elseif l:item.kind is s:LSP_COMPLETION_INTERFACE_KIND
- let l:kind = 'f'
- else
- let l:kind = 'v'
- endif
-
let l:doc = get(l:item, 'documentation', '')
if type(l:doc) is v:t_dict && has_key(l:doc, 'value')
@@ -450,7 +524,7 @@ function! ale#completion#ParseLSPCompletions(response) abort
call add(l:results, {
\ 'word': l:word,
- \ 'kind': l:kind,
+ \ 'kind': ale#completion#GetCompletionSymbols(get(l:item, 'kind', '')),
\ 'icase': 1,
\ 'menu': get(l:item, 'detail', ''),
\ 'info': (type(l:doc) is v:t_string ? l:doc : ''),
diff --git a/doc/ale.txt b/doc/ale.txt
index 593aae11..847a9777 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -432,7 +432,42 @@ vimrc, and your issues should go away. >
set completeopt=menu,menuone,preview,noselect,noinsert
<
-
+ *ale-symbols*
+
+ALE provides a set of basic completion symbols. If you want to replace those
+symbols with others, you can set the variable |g:ale_completion_symbols| with
+a mapping of the type of completion to the symbol or other string that you
+would like to use. An example here shows the available options for symbols >
+
+ let g:ale_completion_symbols = {
+ \ 'text': '',
+ \ 'method': '',
+ \ 'function': '',
+ \ 'constructor': '',
+ \ 'field': '',
+ \ 'variable': '',
+ \ 'class': '',
+ \ 'interface': '',
+ \ 'module': '',
+ \ 'property': '',
+ \ 'unit': 'unit',
+ \ 'value': 'val',
+ \ 'enum': '',
+ \ 'keyword': 'keyword',
+ \ 'snippet': '',
+ \ 'color': 'color',
+ \ 'file': '',
+ \ 'reference': 'ref',
+ \ 'folder': '',
+ \ 'enum member': '',
+ \ 'constant': '',
+ \ 'struct': '',
+ \ 'event': 'event',
+ \ 'operator': '',
+ \ 'type_parameter': 'type param',
+ \ '<default>': 'v'
+ \ }
+<
-------------------------------------------------------------------------------
5.2 Go To Definition *ale-go-to-definition*
@@ -671,6 +706,47 @@ g:ale_completion_excluded_words *g:ale_completion_excluded_words*
let b:ale_completion_excluded_words = ['it', 'describe']
<
+g:ale_completion_symbols *g:ale_completion_symbols*
+
+ Type: |Dictionary|
+
+
+ A mapping from completion types to symbols for completions. See
+ |ale-symbols| for more information.
+
+ By default, this mapping only uses built in Vim completion kinds, but it can
+ be updated to use any unicode character for the completion kind. For
+ example: >
+ let g:ale_completion_symbols = {
+ \ 'text': '',
+ \ 'method': '',
+ \ 'function': '',
+ \ 'constructor': '',
+ \ 'field': '',
+ \ 'variable': '',
+ \ 'class': '',
+ \ 'interface': '',
+ \ 'module': '',
+ \ 'property': '',
+ \ 'unit': 'v',
+ \ 'value': 'v',
+ \ 'enum': 't',
+ \ 'keyword': 'v',
+ \ 'snippet': 'v',
+ \ 'color': 'v',
+ \ 'file': 'v',
+ \ 'reference': 'v',
+ \ 'folder': 'v',
+ \ 'enum_member': 'm',
+ \ 'constant': 'm',
+ \ 'struct': 't',
+ \ 'event': 'v',
+ \ 'operator': 'f',
+ \ 'type_parameter': 'p',
+ \ '<default>': 'v'
+ \ })
+<
+
g:ale_completion_max_suggestions *g:ale_completion_max_suggestions*
Type: |Number|
diff --git a/test/completion/test_lsp_completion_parsing.vader b/test/completion/test_lsp_completion_parsing.vader
index ef954564..1fdbbd96 100644
--- a/test/completion/test_lsp_completion_parsing.vader
+++ b/test/completion/test_lsp_completion_parsing.vader
@@ -17,17 +17,17 @@ Execute(Should handle Rust completion results correctly):
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a str>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = Cow<''a, str>>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Searcher', 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 'f', 'icase': 1},
+ \ {'word': 'Searcher', 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1},
\ {'word': 'default', 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = String;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Err', 'menu': 'type Err = ParseError;', 'info': '', 'kind': 'f', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Err', 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1},
\ {'word': 'from_str', 'menu': 'fn from_str(s: &str) -> Result<String, ParseError>', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'from', 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'from', 'menu': 'fn from(s: Box<str>) -> String', 'info': '', 'kind': 'f', 'icase': 1},
diff --git a/test/completion/test_tsserver_completion_parsing.vader b/test/completion/test_tsserver_completion_parsing.vader
index dbb8de32..6beb7b0a 100644
--- a/test/completion/test_tsserver_completion_parsing.vader
+++ b/test/completion/test_tsserver_completion_parsing.vader
@@ -36,7 +36,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'abc',
\ 'menu': '(property) Foo.abc: number',
\ 'info': '',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -44,7 +44,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'def',
\ 'menu': '(property) Foo.def: number',
\ 'info': 'foo bar baz',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -52,7 +52,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'ghi',
\ 'menu': '(class) Foo',
\ 'info': '',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -124,7 +124,7 @@ Execute(Entries without details should be included in the responses):
\ 'word': 'abc',
\ 'menu': 'import { def } from "./Foo"; (property) Foo.abc: number',
\ 'info': '',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'user_data': json_encode({
\ 'codeActions': [{
@@ -138,7 +138,7 @@ Execute(Entries without details should be included in the responses):
\ 'word': 'def',
\ 'menu': '(property) Foo.def: number',
\ 'info': 'foo bar baz',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },