summaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
Diffstat (limited to 'autoload')
-rw-r--r--autoload/ale/completion.vim39
-rw-r--r--autoload/ale/completion/python.vim3
-rw-r--r--autoload/ale/definition.vim20
-rw-r--r--autoload/ale/linter.vim8
-rw-r--r--autoload/ale/preview.vim54
-rw-r--r--autoload/ale/util.vim21
6 files changed, 117 insertions, 28 deletions
diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim
index 7ad7f9da..29b1df1f 100644
--- a/autoload/ale/completion.vim
+++ b/autoload/ale/completion.vim
@@ -28,6 +28,7 @@ let s:LSP_COMPLETION_REFERENCE_KIND = 18
" the insert cursor is. If one of these matches, we'll check for completions.
let s:should_complete_map = {
\ '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$',
+\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
\}
" Regular expressions for finding the start column to replace with completion.
@@ -38,6 +39,7 @@ let s:omni_start_map = {
" A map of exact characters for triggering LSP completions.
let s:trigger_character_map = {
\ '<default>': ['.'],
+\ 'rust': ['.', '::'],
\}
function! s:GetFiletypeValue(map, filetype) abort
@@ -215,7 +217,21 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
return l:results
endfunction
+function! ale#completion#NullFilter(buffer, item) abort
+ return 1
+endfunction
+
function! ale#completion#ParseLSPCompletions(response) abort
+ let l:buffer = bufnr('')
+ let l:info = get(b:, 'ale_completion_info', {})
+ let l:Filter = get(l:info, 'completion_filter', v:null)
+
+ if l:Filter is v:null
+ let l:Filter = function('ale#completion#NullFilter')
+ else
+ let l:Filter = ale#util#GetFunction(l:Filter)
+ endif
+
let l:item_list = []
if type(get(a:response, 'result')) is type([])
@@ -228,6 +244,16 @@ function! ale#completion#ParseLSPCompletions(response) abort
let l:results = []
for l:item in l:item_list
+ if !call(l:Filter, [l:buffer, l:item])
+ continue
+ endif
+
+ let l:word = matchstr(l:item.label, '\v^[^(]+')
+
+ if empty(l:word)
+ continue
+ endif
+
" See :help complete-items for Vim completion kinds
if l:item.kind is s:LSP_COMPLETION_METHOD_KIND
let l:kind = 'm'
@@ -244,11 +270,11 @@ function! ale#completion#ParseLSPCompletions(response) abort
endif
call add(l:results, {
- \ 'word': l:item.label,
+ \ 'word': l:word,
\ 'kind': l:kind,
\ 'icase': 1,
\ 'menu': l:item.detail,
- \ 'info': l:item.documentation,
+ \ 'info': get(l:item, 'documentation', ''),
\})
endfor
@@ -349,6 +375,10 @@ function! s:GetLSPCompletions(linter) abort
if l:request_id
let b:ale_completion_info.conn_id = l:id
let b:ale_completion_info.request_id = l:request_id
+
+ if has_key(a:linter, 'completion_filter')
+ let b:ale_completion_info.completion_filter = a:linter.completion_filter
+ endif
endif
endfunction
@@ -378,10 +408,7 @@ function! ale#completion#GetCompletions() abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
- if l:linter.lsp is# 'tsserver'
- \|| get(g:, 'ale_completion_experimental_lsp_support', 0)
- call s:GetLSPCompletions(l:linter)
- endif
+ call s:GetLSPCompletions(l:linter)
endif
endfor
endfunction
diff --git a/autoload/ale/completion/python.vim b/autoload/ale/completion/python.vim
new file mode 100644
index 00000000..6b65c5b5
--- /dev/null
+++ b/autoload/ale/completion/python.vim
@@ -0,0 +1,3 @@
+function! ale#completion#python#CompletionItemFilter(buffer, item) abort
+ return a:item.label !~# '\v^__[a-z_]+__'
+endfunction
diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim
index 521cd0b1..a3bfcd17 100644
--- a/autoload/ale/definition.vim
+++ b/autoload/ale/definition.vim
@@ -13,26 +13,10 @@ function! ale#definition#SetMap(map) abort
let s:go_to_definition_map = a:map
endfunction
-" This function is used so we can check the execution of commands without
-" running them.
-function! ale#definition#Execute(expr) abort
- execute a:expr
-endfunction
-
function! ale#definition#ClearLSPData() abort
let s:go_to_definition_map = {}
endfunction
-function! ale#definition#Open(options, filename, line, column) abort
- if a:options.open_in_tab
- call ale#definition#Execute('tabedit ' . fnameescape(a:filename))
- else
- call ale#definition#Execute('edit ' . fnameescape(a:filename))
- endif
-
- call cursor(a:line, a:column)
-endfunction
-
function! ale#definition#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') is# 'definition'
\&& has_key(s:go_to_definition_map, a:response.request_seq)
@@ -43,7 +27,7 @@ function! ale#definition#HandleTSServerResponse(conn_id, response) abort
let l:line = a:response.body[0].start.line
let l:column = a:response.body[0].start.offset
- call ale#definition#Open(l:options, l:filename, l:line, l:column)
+ call ale#util#Open(l:filename, l:line, l:column, l:options)
endif
endif
endfunction
@@ -67,7 +51,7 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
let l:line = l:item.range.start.line + 1
let l:column = l:item.range.start.character
- call ale#definition#Open(l:options, l:filename, l:line, l:column)
+ call ale#util#Open(l:filename, l:line, l:column, l:options)
break
endfor
endif
diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim
index d059a12d..7e32b7bc 100644
--- a/autoload/ale/linter.vim
+++ b/autoload/ale/linter.vim
@@ -194,6 +194,14 @@ function! ale#linter#PreProcess(linter) abort
if !s:IsCallback(l:obj.project_root_callback)
throw '`project_root_callback` must be a callback for LSP linters'
endif
+
+ if has_key(a:linter, 'completion_filter')
+ let l:obj.completion_filter = a:linter.completion_filter
+
+ if !s:IsCallback(l:obj.completion_filter)
+ throw '`completion_filter` must be a callback'
+ endif
+ endif
endif
let l:obj.output_stream = get(a:linter, 'output_stream', 'stdout')
diff --git a/autoload/ale/preview.vim b/autoload/ale/preview.vim
index 3b1c16a6..c03cfe51 100644
--- a/autoload/ale/preview.vim
+++ b/autoload/ale/preview.vim
@@ -2,13 +2,16 @@
" Description: Preview windows for showing whatever information in.
" Open a preview window and show some lines in it.
-function! ale#preview#Show(lines) abort
+" An optional second argument can set an alternative filetype for the window.
+function! ale#preview#Show(lines, ...) abort
+ let l:filetype = get(a:000, 0, 'ale-preview')
+
silent pedit ALEPreviewWindow
wincmd P
setlocal modifiable
setlocal noreadonly
setlocal nobuflisted
- setlocal filetype=ale-preview
+ let &l:filetype = l:filetype
setlocal buftype=nofile
setlocal bufhidden=wipe
:%d
@@ -16,3 +19,50 @@ function! ale#preview#Show(lines) abort
setlocal nomodifiable
setlocal readonly
endfunction
+
+" Show a location selection preview window, given some items.
+" Each item should have 'filename', 'line', and 'column' keys.
+function! ale#preview#ShowSelection(item_list) abort
+ let l:lines = []
+
+ " Create lines to display to users.
+ for l:item in a:item_list
+ call add(
+ \ l:lines,
+ \ l:item.filename
+ \ . ':' . l:item.line
+ \ . ':' . l:item.column,
+ \)
+ endfor
+
+ call ale#preview#Show(l:lines, 'ale-preview-selection')
+ let b:ale_preview_item_list = a:item_list
+endfunction
+
+function! s:Open(open_in_tab) abort
+ let l:item_list = get(b:, 'ale_preview_item_list', [])
+ let l:item = get(l:item_list, getcurpos()[1] - 1, {})
+
+ if empty(l:item)
+ return
+ endif
+
+ if !a:open_in_tab
+ :q!
+ endif
+
+ call ale#util#Open(
+ \ l:item.filename,
+ \ l:item.line,
+ \ l:item.column,
+ \ {'open_in_tab': a:open_in_tab},
+ \)
+endfunction
+
+function! ale#preview#OpenSelectionInBuffer() abort
+ call s:Open(0)
+endfunction
+
+function! ale#preview#OpenSelectionInTab() abort
+ call s:Open(1)
+endfunction
diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim
index d160b34c..55d9d743 100644
--- a/autoload/ale/util.vim
+++ b/autoload/ale/util.vim
@@ -11,6 +11,11 @@ function! ale#util#FeedKeys(...) abort
return call('feedkeys', a:000)
endfunction
+" A wrapper function for execute, so we can test executing some commands.
+function! ale#util#Execute(expr) abort
+ execute a:expr
+endfunction
+
if !exists('g:ale#util#nul_file')
" A null file for sending output to nothing.
let g:ale#util#nul_file = '/dev/null'
@@ -33,6 +38,16 @@ function! ale#util#GetFunction(string_or_ref) abort
return a:string_or_ref
endfunction
+function! ale#util#Open(filename, line, column, options) abort
+ if get(a:options, 'open_in_tab', 0)
+ call ale#util#Execute('tabedit ' . fnameescape(a:filename))
+ else
+ call ale#util#Execute('edit ' . fnameescape(a:filename))
+ endif
+
+ call cursor(a:line, a:column)
+endfunction
+
let g:ale#util#error_priority = 5
let g:ale#util#warning_priority = 4
let g:ale#util#info_priority = 3
@@ -341,8 +356,10 @@ if !exists('s:patial_timers')
endif
function! s:ApplyPartialTimer(timer_id) abort
- let [l:Callback, l:args] = remove(s:partial_timers, a:timer_id)
- call call(l:Callback, [a:timer_id] + l:args)
+ if has_key(s:partial_timers, a:timer_id)
+ let [l:Callback, l:args] = remove(s:partial_timers, a:timer_id)
+ call call(l:Callback, [a:timer_id] + l:args)
+ endif
endfunction
" Given a delay, a callback, a List of arguments, start a timer with