Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
1781b1eab0
32 changed files with 1326 additions and 257 deletions
|
@ -2,4 +2,4 @@
|
|||
" Description: languagetool for asciidoc files, copied from markdown.
|
||||
|
||||
|
||||
call ale#handlers#languagetool#DefineLinter('asciidoctor')
|
||||
call ale#handlers#languagetool#DefineLinter('asciidoc')
|
||||
|
|
|
@ -19,11 +19,11 @@ endfunction
|
|||
|
||||
function! ale_linters#handlebars#embertemplatelint#GetCommandWithVersionCheck(buffer) abort
|
||||
return ale#semver#RunWithVersionCheck(
|
||||
\ a:buffer,
|
||||
\ ale_linters#handlebars#embertemplatelint#GetExecutable(a:buffer),
|
||||
\ '%e --version',
|
||||
\ function('ale_linters#handlebars#embertemplatelint#GetCommand'),
|
||||
\ )
|
||||
\ a:buffer,
|
||||
\ ale_linters#handlebars#embertemplatelint#GetExecutable(a:buffer),
|
||||
\ '%e --version',
|
||||
\ function('ale_linters#handlebars#embertemplatelint#GetCommand'),
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale_linters#handlebars#embertemplatelint#Handle(buffer, lines) abort
|
||||
|
@ -52,7 +52,8 @@ function! ale_linters#handlebars#embertemplatelint#Handle(buffer, lines) abort
|
|||
endfunction
|
||||
|
||||
call ale#linter#Define('handlebars', {
|
||||
\ 'name': 'ember-template-lint',
|
||||
\ 'name': 'embertemplatelint',
|
||||
\ 'aliases': ['ember-template-lint'],
|
||||
\ 'executable': function('ale_linters#handlebars#embertemplatelint#GetExecutable'),
|
||||
\ 'command': function('ale_linters#handlebars#embertemplatelint#GetCommandWithVersionCheck'),
|
||||
\ 'callback': 'ale_linters#handlebars#embertemplatelint#Handle',
|
||||
|
|
|
@ -17,7 +17,7 @@ function! ale_linters#python#pylint#GetExecutable(buffer) abort
|
|||
return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint'])
|
||||
endfunction
|
||||
|
||||
function! ale_linters#python#pylint#GetCommand(buffer) abort
|
||||
function! ale_linters#python#pylint#GetCommand(buffer, version) abort
|
||||
let l:cd_string = ''
|
||||
|
||||
if ale#Var(a:buffer, 'python_pylint_change_directory')
|
||||
|
@ -38,17 +38,23 @@ function! ale_linters#python#pylint#GetCommand(buffer) abort
|
|||
|
||||
return l:cd_string
|
||||
\ . ale#Escape(l:executable) . l:exec_args
|
||||
\ . ' ' . ale#Var(a:buffer, 'python_pylint_options')
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'python_pylint_options'))
|
||||
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n'
|
||||
\ . (ale#semver#GTE(a:version, [2, 4, 0]) ? ' --from-stdin' : '')
|
||||
\ . ' %s'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#python#pylint#Handle(buffer, lines) abort
|
||||
let l:output = ale#python#HandleTraceback(a:lines, 10)
|
||||
|
||||
if !empty(l:output)
|
||||
return l:output
|
||||
endif
|
||||
|
||||
" Matches patterns like the following:
|
||||
"
|
||||
" test.py:4:4: W0101 (unreachable) Unreachable code
|
||||
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+): ([[:alnum:]]+) \(([^(]*)\) (.*)$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
"let l:failed = append(0, l:match)
|
||||
|
@ -71,13 +77,19 @@ function! ale_linters#python#pylint#Handle(buffer, lines) abort
|
|||
let l:code_out = l:match[4]
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
let l:item = {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 1,
|
||||
\ 'text': l:match[5],
|
||||
\ 'code': l:code_out,
|
||||
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
|
||||
\})
|
||||
\ 'type': 'W',
|
||||
\}
|
||||
|
||||
if l:code[:0] is# 'E'
|
||||
let l:item.type = 'E'
|
||||
endif
|
||||
|
||||
call add(l:output, l:item)
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
|
@ -86,7 +98,17 @@ endfunction
|
|||
call ale#linter#Define('python', {
|
||||
\ 'name': 'pylint',
|
||||
\ 'executable': function('ale_linters#python#pylint#GetExecutable'),
|
||||
\ 'command': function('ale_linters#python#pylint#GetCommand'),
|
||||
\ 'lint_file': {buffer -> ale#semver#RunWithVersionCheck(
|
||||
\ buffer,
|
||||
\ ale#Var(buffer, 'python_pylint_executable'),
|
||||
\ '%e --version',
|
||||
\ {buffer, version -> !ale#semver#GTE(version, [2, 4, 0])},
|
||||
\ )},
|
||||
\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
|
||||
\ buffer,
|
||||
\ ale#Var(buffer, 'python_pylint_executable'),
|
||||
\ '%e --version',
|
||||
\ function('ale_linters#python#pylint#GetCommand'),
|
||||
\ )},
|
||||
\ 'callback': 'ale_linters#python#pylint#Handle',
|
||||
\ 'lint_file': 1,
|
||||
\})
|
||||
|
|
|
@ -13,12 +13,17 @@ function! ale_linters#vim#vint#GetCommand(buffer, version) abort
|
|||
|
||||
let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w'
|
||||
|
||||
" Use the --stdin-display-name argument if supported, temp file otherwise.
|
||||
let l:stdin_or_temp = ale#semver#GTE(a:version, [0, 4, 0])
|
||||
\ ? ' --stdin-display-name %s -'
|
||||
\ : ' %t'
|
||||
|
||||
return '%e'
|
||||
\ . ' ' . l:warning_flag
|
||||
\ . (l:can_use_no_color_flag ? ' --no-color' : '')
|
||||
\ . s:enable_neovim
|
||||
\ . ' ' . s:format
|
||||
\ . ' %t'
|
||||
\ . l:stdin_or_temp
|
||||
endfunction
|
||||
|
||||
let s:word_regex_list = [
|
||||
|
|
|
@ -100,13 +100,7 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
|
|||
" Use the filetype from the buffer
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
let l:linters = ale#linter#Get(l:filetype)
|
||||
|
||||
" Apply ignore lists for linters only if needed.
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
let l:linters = !empty(l:ignore_config) || l:disable_lsp
|
||||
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config, l:disable_lsp)
|
||||
\ : l:linters
|
||||
let l:linters = ale#linter#RemoveIgnored(a:buffer, l:filetype, l:linters)
|
||||
|
||||
" Tell other sources that they can start checking the buffer now.
|
||||
let g:ale_want_results_buffer = a:buffer
|
||||
|
@ -163,7 +157,7 @@ function! ale#Queue(delay, ...) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
let s:current_ale_version = [2, 7, 0]
|
||||
let s:current_ale_version = [3, 0, 0]
|
||||
|
||||
" A function used to check for ALE features in files outside of the project.
|
||||
function! ale#Has(feature) abort
|
||||
|
|
|
@ -188,7 +188,13 @@ function! ale#completion#GetTriggerCharacter(filetype, prefix) abort
|
|||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort
|
||||
function! ale#completion#Filter(
|
||||
\ buffer,
|
||||
\ filetype,
|
||||
\ suggestions,
|
||||
\ prefix,
|
||||
\ exact_prefix_match,
|
||||
\) abort
|
||||
let l:excluded_words = ale#Var(a:buffer, 'completion_excluded_words')
|
||||
|
||||
if empty(a:prefix)
|
||||
|
@ -215,10 +221,17 @@ function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort
|
|||
" Dictionaries is accepted here.
|
||||
let l:word = type(l:item) is v:t_string ? 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 a:exact_prefix_match
|
||||
" Add suggestions if the word is an exact match.
|
||||
if l:word is# a:prefix
|
||||
call add(l:filtered_suggestions, l:item)
|
||||
endif
|
||||
else
|
||||
" 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
|
||||
endif
|
||||
|
@ -241,21 +254,17 @@ function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort
|
|||
return l:filtered_suggestions
|
||||
endfunction
|
||||
|
||||
function! s:ReplaceCompletionOptions() abort
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
|
||||
" Remember the old omnifunc value, if there is one.
|
||||
" If we don't store an old one, we'll just never reset the option.
|
||||
" This will stop some random exceptions from appearing.
|
||||
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
|
||||
let b:ale_old_omnifunc = &l:omnifunc
|
||||
endif
|
||||
|
||||
let &l:omnifunc = 'ale#completion#AutomaticOmniFunc'
|
||||
function! s:ReplaceCompletionOptions(source) abort
|
||||
" Remember the old omnifunc value, if there is one.
|
||||
" If we don't store an old one, we'll just never reset the option.
|
||||
" This will stop some random exceptions from appearing.
|
||||
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
|
||||
let b:ale_old_omnifunc = &l:omnifunc
|
||||
endif
|
||||
|
||||
if l:source is# 'ale-automatic'
|
||||
let &l:omnifunc = 'ale#completion#AutomaticOmniFunc'
|
||||
|
||||
if a:source is# 'ale-automatic'
|
||||
if !exists('b:ale_old_completeopt')
|
||||
let b:ale_old_completeopt = &l:completeopt
|
||||
endif
|
||||
|
@ -318,7 +327,11 @@ function! ale#completion#AutomaticOmniFunc(findstart, base) abort
|
|||
else
|
||||
let l:result = ale#completion#GetCompletionResult()
|
||||
|
||||
call s:ReplaceCompletionOptions()
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
|
||||
call s:ReplaceCompletionOptions(l:source)
|
||||
endif
|
||||
|
||||
return l:result isnot v:null ? l:result : []
|
||||
endif
|
||||
|
@ -331,31 +344,53 @@ function! s:OpenCompletionMenu(...) abort
|
|||
endfunction
|
||||
|
||||
function! ale#completion#Show(result) abort
|
||||
if ale#util#Mode() isnot# 'i'
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if ale#util#Mode() isnot# 'i' && l:source isnot# 'ale-import'
|
||||
return
|
||||
endif
|
||||
|
||||
" Set the list in the buffer, temporarily replace omnifunc with our
|
||||
" function, and then start omni-completion.
|
||||
" Set the list in the buffer.
|
||||
let b:ale_completion_result = a:result
|
||||
|
||||
" Don't try to open the completion menu if there's nothing to show.
|
||||
if empty(b:ale_completion_result)
|
||||
if l:source is# 'ale-import'
|
||||
" If we ran completion from :ALEImport,
|
||||
" tell the user that nothing is going to happen.
|
||||
call s:message('No possible imports found.')
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
" Replace completion options shortly before opening the menu.
|
||||
call s:ReplaceCompletionOptions()
|
||||
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
|
||||
call s:ReplaceCompletionOptions(l:source)
|
||||
|
||||
call timer_start(0, function('s:OpenCompletionMenu'))
|
||||
endif
|
||||
|
||||
if l:source is# 'ale-callback'
|
||||
call b:CompleteCallback(b:ale_completion_result)
|
||||
endif
|
||||
|
||||
if l:source is# 'ale-import'
|
||||
call ale#completion#HandleUserData(b:ale_completion_result[0])
|
||||
|
||||
let l:text_changed = '' . g:ale_lint_on_text_changed
|
||||
|
||||
" Check the buffer again right away, if linting is enabled.
|
||||
if g:ale_enabled
|
||||
\&& (
|
||||
\ l:text_changed is# '1'
|
||||
\ || l:text_changed is# 'always'
|
||||
\ || l:text_changed is# 'normal'
|
||||
\ || l:text_changed is# 'insert'
|
||||
\)
|
||||
call ale#Queue(0, '')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetAllTriggers() abort
|
||||
|
@ -386,14 +421,18 @@ endfunction
|
|||
function! s:CompletionStillValid(request_id) abort
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
return ale#util#Mode() is# 'i'
|
||||
\&& has_key(b:, 'ale_completion_info')
|
||||
return has_key(b:, 'ale_completion_info')
|
||||
\&& (
|
||||
\ ale#util#Mode() is# 'i'
|
||||
\ || b:ale_completion_info.source is# 'ale-import'
|
||||
\)
|
||||
\&& b:ale_completion_info.request_id == a:request_id
|
||||
\&& b:ale_completion_info.line == l:line
|
||||
\&& (
|
||||
\ b:ale_completion_info.column == l:column
|
||||
\ || b:ale_completion_info.source is# 'ale-omnifunc'
|
||||
\ || b:ale_completion_info.source is# 'ale-callback'
|
||||
\ || b:ale_completion_info.source is# 'ale-import'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
|
@ -418,6 +457,7 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
|||
let l:buffer = bufnr('')
|
||||
let l:results = []
|
||||
let l:names_with_details = []
|
||||
let l:info = get(b:, 'ale_completion_info', {})
|
||||
|
||||
for l:suggestion in a:response.body
|
||||
let l:displayParts = []
|
||||
|
@ -459,17 +499,25 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
|||
\ 'kind': ale#completion#GetCompletionSymbols(l:suggestion.kind),
|
||||
\ 'icase': 1,
|
||||
\ 'menu': join(l:displayParts, ''),
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ 'dup': get(l:info, 'additional_edits_only', 0)
|
||||
\ || g:ale_completion_autoimport,
|
||||
\ 'info': join(l:documentationParts, ''),
|
||||
\}
|
||||
" This flag is used to tell if this completion came from ALE or not.
|
||||
let l:user_data = {'_ale_completion_item': 1}
|
||||
|
||||
if has_key(l:suggestion, 'codeActions')
|
||||
let l:result.user_data = json_encode({
|
||||
\ 'codeActions': l:suggestion.codeActions,
|
||||
\ })
|
||||
let l:user_data.code_actions = l:suggestion.codeActions
|
||||
endif
|
||||
|
||||
call add(l:results, l:result)
|
||||
let l:result.user_data = json_encode(l:user_data)
|
||||
|
||||
" Include this item if we'll accept any items,
|
||||
" or if we only want items with additional edits, and this has them.
|
||||
if !get(l:info, 'additional_edits_only', 0)
|
||||
\|| has_key(l:user_data, 'code_actions')
|
||||
call add(l:results, l:result)
|
||||
endif
|
||||
endfor
|
||||
|
||||
let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', [])
|
||||
|
@ -488,6 +536,7 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
|||
\ 'icase': 1,
|
||||
\ 'menu': '',
|
||||
\ 'info': '',
|
||||
\ 'user_data': json_encode({'_ale_completion_item': 1}),
|
||||
\})
|
||||
endfor
|
||||
endif
|
||||
|
@ -544,7 +593,10 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||
" Don't use LSP items with additional text edits when autoimport for
|
||||
" completions is turned off.
|
||||
if !empty(get(l:item, 'additionalTextEdits'))
|
||||
\&& !g:ale_completion_autoimport
|
||||
\&& !(
|
||||
\ get(l:info, 'additional_edits_only', 0)
|
||||
\ || g:ale_completion_autoimport
|
||||
\)
|
||||
continue
|
||||
endif
|
||||
|
||||
|
@ -561,6 +613,8 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||
\ 'menu': get(l:item, 'detail', ''),
|
||||
\ 'info': (type(l:doc) is v:t_string ? l:doc : ''),
|
||||
\}
|
||||
" This flag is used to tell if this completion came from ALE or not.
|
||||
let l:user_data = {'_ale_completion_item': 1}
|
||||
|
||||
if has_key(l:item, 'additionalTextEdits')
|
||||
let l:text_changes = []
|
||||
|
@ -580,25 +634,36 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||
endfor
|
||||
|
||||
if !empty(l:text_changes)
|
||||
let l:result.user_data = json_encode({
|
||||
\ 'codeActions': [{
|
||||
\ 'description': 'completion',
|
||||
\ 'changes': [
|
||||
\ {
|
||||
\ 'fileName': expand('#' . l:buffer . ':p'),
|
||||
\ 'textChanges': l:text_changes,
|
||||
\ }
|
||||
\ ],
|
||||
\ }],
|
||||
\})
|
||||
let l:user_data.code_actions = [{
|
||||
\ 'description': 'completion',
|
||||
\ 'changes': [
|
||||
\ {
|
||||
\ 'fileName': expand('#' . l:buffer . ':p'),
|
||||
\ 'textChanges': l:text_changes,
|
||||
\ },
|
||||
\ ],
|
||||
\}]
|
||||
endif
|
||||
endif
|
||||
|
||||
call add(l:results, l:result)
|
||||
let l:result.user_data = json_encode(l:user_data)
|
||||
|
||||
" Include this item if we'll accept any items,
|
||||
" or if we only want items with additional edits, and this has them.
|
||||
if !get(l:info, 'additional_edits_only', 0)
|
||||
\|| has_key(l:user_data, 'code_actions')
|
||||
call add(l:results, l:result)
|
||||
endif
|
||||
endfor
|
||||
|
||||
if has_key(l:info, 'prefix')
|
||||
let l:results = ale#completion#Filter(l:buffer, &filetype, l:results, l:info.prefix)
|
||||
let l:results = ale#completion#Filter(
|
||||
\ l:buffer,
|
||||
\ &filetype,
|
||||
\ l:results,
|
||||
\ l:info.prefix,
|
||||
\ get(l:info, 'additional_edits_only', 0),
|
||||
\)
|
||||
endif
|
||||
|
||||
return l:results[: g:ale_completion_max_suggestions - 1]
|
||||
|
@ -622,13 +687,18 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
|
|||
\ &filetype,
|
||||
\ ale#completion#ParseTSServerCompletions(a:response),
|
||||
\ b:ale_completion_info.prefix,
|
||||
\ get(b:ale_completion_info, 'additional_edits_only', 0),
|
||||
\)[: g:ale_completion_max_suggestions - 1]
|
||||
|
||||
" We need to remember some names for tsserver, as it doesn't send
|
||||
" details back for everything we send.
|
||||
call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names)
|
||||
|
||||
if !empty(l:names)
|
||||
if empty(l:names)
|
||||
" Response with no results now and skip making a redundant request
|
||||
" for nothing.
|
||||
call ale#completion#Show([])
|
||||
else
|
||||
let l:identifiers = []
|
||||
|
||||
for l:name in l:names
|
||||
|
@ -702,7 +772,8 @@ function! s:OnReady(linter, lsp_details) abort
|
|||
\ b:ale_completion_info.line,
|
||||
\ b:ale_completion_info.column,
|
||||
\ b:ale_completion_info.prefix,
|
||||
\ g:ale_completion_autoimport,
|
||||
\ get(b:ale_completion_info, 'additional_edits_only', 0)
|
||||
\ || g:ale_completion_autoimport,
|
||||
\)
|
||||
else
|
||||
" Send a message saying the buffer has changed first, otherwise
|
||||
|
@ -761,9 +832,19 @@ function! ale#completion#GetCompletions(...) abort
|
|||
let b:CompleteCallback = l:CompleteCallback
|
||||
endif
|
||||
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
if has_key(l:options, 'line') && has_key(l:options, 'column')
|
||||
" Use a provided line and column, if given.
|
||||
let l:line = l:options.line
|
||||
let l:column = l:options.column
|
||||
else
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
endif
|
||||
|
||||
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
|
||||
if has_key(l:options, 'prefix')
|
||||
let l:prefix = l:options.prefix
|
||||
else
|
||||
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
|
||||
endif
|
||||
|
||||
if l:source is# 'ale-automatic' && empty(l:prefix)
|
||||
return 0
|
||||
|
@ -782,6 +863,11 @@ function! ale#completion#GetCompletions(...) abort
|
|||
\}
|
||||
unlet! b:ale_completion_result
|
||||
|
||||
if has_key(l:options, 'additional_edits_only')
|
||||
let b:ale_completion_info.additional_edits_only =
|
||||
\ l:options.additional_edits_only
|
||||
endif
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let l:Callback = function('s:OnReady')
|
||||
|
||||
|
@ -798,6 +884,37 @@ function! ale#completion#GetCompletions(...) abort
|
|||
return l:started
|
||||
endfunction
|
||||
|
||||
function! s:message(message) abort
|
||||
call ale#util#Execute('echom ' . string(a:message))
|
||||
endfunction
|
||||
|
||||
" This function implements the :ALEImport command.
|
||||
function! ale#completion#Import() abort
|
||||
let l:word = expand('<cword>')
|
||||
|
||||
if empty(l:word)
|
||||
call s:message('Nothing to complete at cursor!')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
let l:column = searchpos('\V' . escape(l:word, '/\'), 'bn', l:line)[1]
|
||||
|
||||
if l:column isnot 0
|
||||
let l:started = ale#completion#GetCompletions('ale-import', {
|
||||
\ 'line': l:line,
|
||||
\ 'column': l:column,
|
||||
\ 'prefix': l:word,
|
||||
\ 'additional_edits_only': 1,
|
||||
\})
|
||||
|
||||
if !l:started
|
||||
call s:message('No completion providers are available.')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#completion#OmniFunc(findstart, base) abort
|
||||
if a:findstart
|
||||
let l:started = ale#completion#GetCompletions('ale-omnifunc')
|
||||
|
@ -871,29 +988,29 @@ function! ale#completion#Queue() abort
|
|||
endfunction
|
||||
|
||||
function! ale#completion#HandleUserData(completed_item) abort
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source isnot# 'ale-automatic'
|
||||
\&& l:source isnot# 'ale-manual'
|
||||
\&& l:source isnot# 'ale-callback'
|
||||
return
|
||||
endif
|
||||
|
||||
let l:user_data_json = get(a:completed_item, 'user_data', '')
|
||||
|
||||
if empty(l:user_data_json)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:user_data = json_decode(l:user_data_json)
|
||||
let l:user_data = !empty(l:user_data_json)
|
||||
\ ? json_decode(l:user_data_json)
|
||||
\ : v:null
|
||||
|
||||
if type(l:user_data) isnot v:t_dict
|
||||
\|| get(l:user_data, '_ale_completion_item', 0) isnot 1
|
||||
return
|
||||
endif
|
||||
|
||||
for l:code_action in get(l:user_data, 'codeActions', [])
|
||||
call ale#code_action#HandleCodeAction(l:code_action, v:false)
|
||||
endfor
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source is# 'ale-automatic'
|
||||
\|| l:source is# 'ale-manual'
|
||||
\|| l:source is# 'ale-callback'
|
||||
\|| l:source is# 'ale-import'
|
||||
\|| l:source is# 'ale-omnifunc'
|
||||
for l:code_action in get(l:user_data, 'code_actions', [])
|
||||
call ale#code_action#HandleCodeAction(l:code_action, v:false)
|
||||
endfor
|
||||
endif
|
||||
|
||||
silent doautocmd <nomodeline> User ALECompletePost
|
||||
endfunction
|
||||
|
||||
function! ale#completion#Done() abort
|
||||
|
|
|
@ -8,6 +8,7 @@ let s:global_variable_list = [
|
|||
\ 'ale_completion_delay',
|
||||
\ 'ale_completion_enabled',
|
||||
\ 'ale_completion_max_suggestions',
|
||||
\ 'ale_disable_lsp',
|
||||
\ 'ale_echo_cursor',
|
||||
\ 'ale_echo_msg_error_str',
|
||||
\ 'ale_echo_msg_format',
|
||||
|
@ -28,6 +29,7 @@ let s:global_variable_list = [
|
|||
\ 'ale_linter_aliases',
|
||||
\ 'ale_linters',
|
||||
\ 'ale_linters_explicit',
|
||||
\ 'ale_linters_ignore',
|
||||
\ 'ale_list_vertical',
|
||||
\ 'ale_list_window_size',
|
||||
\ 'ale_loclist_msg_format',
|
||||
|
@ -196,6 +198,7 @@ function! s:EchoLSPErrorMessages(all_linter_names) abort
|
|||
endfunction
|
||||
|
||||
function! ale#debugging#Info() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:filetype = &filetype
|
||||
|
||||
" We get the list of enabled linters for free by the above function.
|
||||
|
@ -222,10 +225,20 @@ function! ale#debugging#Info() abort
|
|||
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
|
||||
let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '')
|
||||
|
||||
let l:non_ignored_names = map(
|
||||
\ copy(ale#linter#RemoveIgnored(l:buffer, l:filetype, l:enabled_linters)),
|
||||
\ 'v:val[''name'']',
|
||||
\)
|
||||
let l:ignored_names = filter(
|
||||
\ copy(l:enabled_names),
|
||||
\ 'index(l:non_ignored_names, v:val) < 0'
|
||||
\)
|
||||
|
||||
call s:Echo(' Current Filetype: ' . l:filetype)
|
||||
call s:Echo('Available Linters: ' . string(l:all_names))
|
||||
call s:EchoLinterAliases(l:all_linters)
|
||||
call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
|
||||
call s:Echo(' Ignored Linters: ' . string(l:ignored_names))
|
||||
call s:Echo(' Suggested Fixers: ' . l:fixers_string)
|
||||
call s:Echo(' Linter Variables:')
|
||||
call s:Echo('')
|
||||
|
|
|
@ -444,7 +444,7 @@ function! s:RunJob(command, options) abort
|
|||
return 1
|
||||
endfunction
|
||||
|
||||
function! s:StopCurrentJobs(buffer, clear_lint_file_jobs) abort
|
||||
function! s:StopCurrentJobs(buffer, clear_lint_file_jobs, linter_slots) abort
|
||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
call ale#command#StopJobs(a:buffer, 'linter')
|
||||
|
||||
|
@ -453,11 +453,25 @@ function! s:StopCurrentJobs(buffer, clear_lint_file_jobs) abort
|
|||
call ale#command#StopJobs(a:buffer, 'file_linter')
|
||||
let l:info.active_linter_list = []
|
||||
else
|
||||
let l:lint_file_map = {}
|
||||
|
||||
" Use a previously computed map of `lint_file` values to find
|
||||
" linters that are used for linting files.
|
||||
for [l:lint_file, l:linter] in a:linter_slots
|
||||
if l:lint_file is 1
|
||||
let l:lint_file_map[l:linter.name] = 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Keep jobs for linting files when we're only linting buffers.
|
||||
call filter(l:info.active_linter_list, 'get(v:val, ''lint_file'')')
|
||||
call filter(l:info.active_linter_list, 'get(l:lint_file_map, v:val.name)')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#Stop(buffer) abort
|
||||
call s:StopCurrentJobs(a:buffer, 1, [])
|
||||
endfunction
|
||||
|
||||
function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
||||
" Figure out which linters are still enabled, and remove
|
||||
" problems for linters which are no longer enabled.
|
||||
|
@ -558,6 +572,22 @@ function! s:RunLinter(buffer, linter, lint_file) abort
|
|||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:GetLintFileSlots(buffer, linters) abort
|
||||
let l:linter_slots = []
|
||||
|
||||
for l:linter in a:linters
|
||||
let l:LintFile = l:linter.lint_file
|
||||
|
||||
if type(l:LintFile) is v:t_func
|
||||
let l:LintFile = l:LintFile(a:buffer)
|
||||
endif
|
||||
|
||||
call add(l:linter_slots, [l:LintFile, l:linter])
|
||||
endfor
|
||||
|
||||
return l:linter_slots
|
||||
endfunction
|
||||
|
||||
function! s:GetLintFileValues(slots, Callback) abort
|
||||
let l:deferred_list = []
|
||||
let l:new_slots = []
|
||||
|
@ -591,12 +621,18 @@ endfunction
|
|||
|
||||
function! s:RunLinters(
|
||||
\ buffer,
|
||||
\ linters,
|
||||
\ slots,
|
||||
\ should_lint_file,
|
||||
\ new_buffer,
|
||||
\ can_clear_results
|
||||
\) abort
|
||||
let l:can_clear_results = a:can_clear_results
|
||||
call s:StopCurrentJobs(a:buffer, a:should_lint_file, a:slots)
|
||||
call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters)
|
||||
|
||||
" We can only clear the results if we aren't checking the buffer.
|
||||
let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||
|
||||
silent doautocmd <nomodeline> User ALELintPre
|
||||
|
||||
for [l:lint_file, l:linter] in a:slots
|
||||
" Only run lint_file linters if we should.
|
||||
|
@ -627,36 +663,19 @@ endfunction
|
|||
function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort
|
||||
" Initialise the buffer information if needed.
|
||||
let l:new_buffer = ale#engine#InitBufferInfo(a:buffer)
|
||||
call s:StopCurrentJobs(a:buffer, a:should_lint_file)
|
||||
call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters)
|
||||
|
||||
" We can only clear the results if we aren't checking the buffer.
|
||||
let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||
|
||||
silent doautocmd <nomodeline> User ALELintPre
|
||||
|
||||
" Handle `lint_file` callbacks first.
|
||||
let l:linter_slots = []
|
||||
|
||||
for l:linter in a:linters
|
||||
let l:LintFile = l:linter.lint_file
|
||||
|
||||
if type(l:LintFile) is v:t_func
|
||||
let l:LintFile = l:LintFile(a:buffer)
|
||||
endif
|
||||
|
||||
call add(l:linter_slots, [l:LintFile, l:linter])
|
||||
endfor
|
||||
|
||||
call s:GetLintFileValues(l:linter_slots, {
|
||||
\ new_slots -> s:RunLinters(
|
||||
\ a:buffer,
|
||||
\ new_slots,
|
||||
\ a:should_lint_file,
|
||||
\ l:new_buffer,
|
||||
\ l:can_clear_results,
|
||||
\ )
|
||||
\})
|
||||
call s:GetLintFileValues(
|
||||
\ s:GetLintFileSlots(a:buffer, a:linters),
|
||||
\ {
|
||||
\ slots -> s:RunLinters(
|
||||
\ a:buffer,
|
||||
\ a:linters,
|
||||
\ slots,
|
||||
\ a:should_lint_file,
|
||||
\ l:new_buffer,
|
||||
\ )
|
||||
\ }
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Clean up a buffer.
|
||||
|
|
|
@ -75,7 +75,10 @@ function! ale#fix#ApplyFixes(buffer, output) abort
|
|||
|
||||
if l:data.lines_before != l:lines
|
||||
call remove(g:ale_fix_buffer_data, a:buffer)
|
||||
execute 'echoerr ''The file was changed before fixing finished'''
|
||||
|
||||
if !l:data.ignore_file_changed_errors
|
||||
execute 'echoerr ''The file was changed before fixing finished'''
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
@ -329,6 +332,7 @@ function! ale#fix#InitBufferData(buffer, fixing_flag) abort
|
|||
\ 'lines_before': getbufline(a:buffer, 1, '$'),
|
||||
\ 'done': 0,
|
||||
\ 'should_save': a:fixing_flag is# 'save_file',
|
||||
\ 'ignore_file_changed_errors': a:fixing_flag is# '!',
|
||||
\ 'temporary_directory_list': [],
|
||||
\}
|
||||
endfunction
|
||||
|
@ -337,19 +341,23 @@ endfunction
|
|||
"
|
||||
" Returns 0 if no fixes can be applied, and 1 if fixing can be done.
|
||||
function! ale#fix#Fix(buffer, fixing_flag, ...) abort
|
||||
if a:fixing_flag isnot# '' && a:fixing_flag isnot# 'save_file'
|
||||
throw "fixing_flag must be either '' or 'save_file'"
|
||||
if a:fixing_flag isnot# ''
|
||||
\&& a:fixing_flag isnot# '!'
|
||||
\&& a:fixing_flag isnot# 'save_file'
|
||||
throw "fixing_flag must be '', '!', or 'save_file'"
|
||||
endif
|
||||
|
||||
try
|
||||
let l:callback_list = s:GetCallbacks(a:buffer, a:fixing_flag, a:000)
|
||||
catch /E700\|BADNAME/
|
||||
let l:function_name = join(split(split(v:exception, ':')[3]))
|
||||
let l:echo_message = printf(
|
||||
\ 'There is no fixer named `%s`. Check :ALEFixSuggest',
|
||||
\ l:function_name,
|
||||
\)
|
||||
execute 'echom l:echo_message'
|
||||
if a:fixing_flag isnot# '!'
|
||||
let l:function_name = join(split(split(v:exception, ':')[3]))
|
||||
let l:echo_message = printf(
|
||||
\ 'There is no fixer named `%s`. Check :ALEFixSuggest',
|
||||
\ l:function_name,
|
||||
\)
|
||||
execute 'echom l:echo_message'
|
||||
endif
|
||||
|
||||
return 0
|
||||
endtry
|
||||
|
|
|
@ -394,6 +394,16 @@ function! ale#linter#Get(original_filetypes) abort
|
|||
return reverse(l:combined_linters)
|
||||
endfunction
|
||||
|
||||
function! ale#linter#RemoveIgnored(buffer, filetype, linters) abort
|
||||
" Apply ignore lists for linters only if needed.
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
|
||||
return !empty(l:ignore_config) || l:disable_lsp
|
||||
\ ? ale#engine#ignore#Exclude(a:filetype, a:linters, l:ignore_config, l:disable_lsp)
|
||||
\ : a:linters
|
||||
endfunction
|
||||
|
||||
" Given a buffer and linter, get the executable String for the linter.
|
||||
function! ale#linter#GetExecutable(buffer, linter) abort
|
||||
let l:Executable = a:linter.executable
|
||||
|
|
|
@ -34,7 +34,11 @@ endfunction
|
|||
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
||||
let l:linter_name = s:lsp_linter_map[a:conn_id]
|
||||
let l:filename = ale#path#FromURI(a:response.params.uri)
|
||||
let l:buffer = bufnr('^' . l:filename . '$')
|
||||
let l:escaped_name = escape(
|
||||
\ fnameescape(l:filename),
|
||||
\ has('win32') ? '^' : '^,}]'
|
||||
\)
|
||||
let l:buffer = bufnr('^' . l:escaped_name . '$')
|
||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
|
@ -52,7 +56,11 @@ endfunction
|
|||
|
||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
let l:linter_name = 'tsserver'
|
||||
let l:buffer = bufnr('^' . a:response.body.file . '$')
|
||||
let l:escaped_name = escape(
|
||||
\ fnameescape(a:response.body.file),
|
||||
\ has('win32') ? '^' : '^,}]'
|
||||
\)
|
||||
let l:buffer = bufnr('^' . l:escaped_name . '$')
|
||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
|
|
|
@ -6,7 +6,7 @@ ALE Elixir Integration *ale-elixir-options*
|
|||
mix *ale-elixir-mix*
|
||||
|
||||
|
||||
The `mix` linter is disabled by default, as it can bee too expensive to run.
|
||||
The `mix` linter is disabled by default, as it can be too expensive to run.
|
||||
See `:help g:ale_linters`
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ ember-template-lint *ale-handlebars-embertemplatelint*
|
|||
|
||||
g:ale_handlebars_embertemplatelint_executable
|
||||
*g:ale_handlebars_embertemplatelint_executable*
|
||||
Type: |String| *b:ale_handlebars_embertemplatelint_executable*
|
||||
*b:ale_handlebars_embertemplatelint_executable*
|
||||
Type: |String|
|
||||
Default: `'ember-template-lint'`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
@ -22,7 +23,8 @@ g:ale_handlebars_embertemplatelint_executable
|
|||
|
||||
g:ale_handlebars_embertemplatelint_use_global
|
||||
*g:ale_handlebars_embertemplatelint_use_global*
|
||||
Type: |Number| *b:ale_handlebars_embertemplatelint_use_global*
|
||||
*b:ale_handlebars_embertemplatelint_use_global*
|
||||
Type: |Number|
|
||||
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
|
66
doc/ale.txt
66
doc/ale.txt
|
@ -147,6 +147,8 @@ ALE offers several options for controlling which linters are run.
|
|||
* Disabling only a subset of linters. - |g:ale_linters_ignore|
|
||||
* Disabling LSP linters and `tsserver`. - |g:ale_disable_lsp|
|
||||
|
||||
You can stop ALE any currently running linters with the |ALELintStop| command.
|
||||
Any existing problems will be kept.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
3.1 Linting On Other Machines *ale-lint-other-machines*
|
||||
|
@ -177,8 +179,11 @@ script like so. >
|
|||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
exec docker run --rm -v "$(pwd):/data" cytopia/pylint "$@"
|
||||
exec docker run -i --rm -v "$(pwd):/data" cytopia/pylint "$@"
|
||||
<
|
||||
|
||||
You will run to run Docker commands with `-i` in order to read from stdin.
|
||||
|
||||
With the above script in mind, you might configure ALE to lint your Python
|
||||
project with `pylint` by providing the path to the script to execute, and
|
||||
mappings which describe how to between the two file systems in your
|
||||
|
@ -526,6 +531,15 @@ completion information with Deoplete, consult Deoplete's documentation.
|
|||
ALE by can support automatic imports from external modules. This behavior can
|
||||
be enabled by setting the |g:ale_completion_autoimport| variable to `1`.
|
||||
|
||||
You can manually request imports for symbols at the cursor with the
|
||||
|ALEImport| command. The word at the cursor must be an exact match for some
|
||||
potential completion result which includes additional text to insert into the
|
||||
current buffer, which ALE will assume is code for an import line. This command
|
||||
can be useful when your code already contains something you need to import.
|
||||
|
||||
You can execute other commands whenever ALE inserts some completion text with
|
||||
the |ALECompletePost| event.
|
||||
|
||||
When working with TypeScript files, ALE can remove warnings from your
|
||||
completions by setting the |g:ale_completion_tsserver_remove_warnings|
|
||||
variable to 1.
|
||||
|
@ -2971,6 +2985,10 @@ ALEFix *ALEFix*
|
|||
|
||||
Fix problems with the current buffer. See |ale-fix| for more information.
|
||||
|
||||
If the command is run with a bang (`:ALEFix!`), all warnings will be
|
||||
suppressed, including warnings about no fixers being defined, and warnings
|
||||
about not being able to apply fixes to a file because it has been changed.
|
||||
|
||||
A plug mapping `<Plug>(ale_fix)` is defined for this command.
|
||||
|
||||
|
||||
|
@ -3053,6 +3071,23 @@ ALEHover *ALEHover*
|
|||
A plug mapping `<Plug>(ale_hover)` is defined for this command.
|
||||
|
||||
|
||||
ALEImport *ALEImport*
|
||||
|
||||
Try to import a symbol using `tsserver` or a Language Server.
|
||||
|
||||
ALE will look for completions for the word at the cursor which contain
|
||||
additional text edits that possible insert lines to import the symbol. The
|
||||
first match with additional text edits will be used, and may add other code
|
||||
to the current buffer other than import lines.
|
||||
|
||||
If linting is enabled, and |g:ale_lint_on_text_changed| is set to ever check
|
||||
buffers when text is changed, the buffer will be checked again after changes
|
||||
are made.
|
||||
|
||||
A Plug mapping `<Plug>(ale_import)` is defined for this command. This
|
||||
mapping should only be bound for normal mode.
|
||||
|
||||
|
||||
ALEOrganizeImports *ALEOrganizeImports*
|
||||
|
||||
Organize imports using tsserver. Currently not implemented for LSPs.
|
||||
|
@ -3060,9 +3095,10 @@ ALEOrganizeImports *ALEOrganizeImports*
|
|||
|
||||
ALERename *ALERename*
|
||||
|
||||
Rename a symbol using TypeScript server or Language Server.
|
||||
Rename a symbol using `tsserver` or a Language Server.
|
||||
|
||||
The user will be prompted for a new name.
|
||||
The symbol where the cursor is resting will be the symbol renamed, and a
|
||||
prompt will open to request a new name.
|
||||
|
||||
|
||||
ALERepeatSelection *ALERepeatSelection*
|
||||
|
@ -3092,6 +3128,13 @@ ALELint *ALELint*
|
|||
A plug mapping `<Plug>(ale_lint)` is defined for this command.
|
||||
|
||||
|
||||
ALELintStop *ALELintStop*
|
||||
|
||||
Stop any currently running jobs for checking the current buffer.
|
||||
|
||||
Any problems from previous linter results will continue to be shown.
|
||||
|
||||
|
||||
ALEPrevious *ALEPrevious*
|
||||
ALEPreviousWrap *ALEPreviousWrap*
|
||||
ALENext *ALENext*
|
||||
|
@ -3957,6 +4000,23 @@ g:ale_want_results_buffer *g:ale_want_results_buffer*
|
|||
figure out which buffer other sources should lint.
|
||||
|
||||
|
||||
ALECompletePost *ALECompletePost-autocmd*
|
||||
*ALECompletePost*
|
||||
|
||||
This |User| autocmd is triggered after ALE inserts an item on
|
||||
|CompleteDone|. This event can be used to run commands after a buffer
|
||||
is changed by ALE as the result of completion. For example, |ALEFix| can
|
||||
be configured to run automatically when completion is done: >
|
||||
|
||||
augroup FixAfterComplete
|
||||
autocmd!
|
||||
" Run ALEFix when completion items are added.
|
||||
autocmd User ALECompletePost ALEFix!
|
||||
" If ALE starts fixing a file, stop linters running for now.
|
||||
autocmd User ALEFixPre ALELintStop
|
||||
augroup END
|
||||
<
|
||||
|
||||
ALELintPre *ALELintPre-autocmd*
|
||||
*ALELintPre*
|
||||
ALELintPost *ALELintPost-autocmd*
|
||||
|
|
|
@ -195,6 +195,8 @@ command! -bar ALEStopAllLSPs :call ale#lsp#reset#StopAllLSPs()
|
|||
|
||||
" A command for linting manually.
|
||||
command! -bar ALELint :call ale#Queue(0, 'lint_file')
|
||||
" Stop current jobs when linting.
|
||||
command! -bar ALELintStop :call ale#engine#Stop(bufnr(''))
|
||||
|
||||
" Define a command to get information about current filetype.
|
||||
command! -bar ALEInfo :call ale#debugging#Info()
|
||||
|
@ -204,7 +206,7 @@ command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboard()
|
|||
command! -bar -nargs=1 ALEInfoToFile :call ale#debugging#InfoToFile(<f-args>)
|
||||
|
||||
" Fix problems in files.
|
||||
command! -bar -nargs=* -complete=customlist,ale#fix#registry#CompleteFixers ALEFix :call ale#fix#Fix(bufnr(''), '', <f-args>)
|
||||
command! -bar -bang -nargs=* -complete=customlist,ale#fix#registry#CompleteFixers ALEFix :call ale#fix#Fix(bufnr(''), '<bang>', <f-args>)
|
||||
" Suggest registered functions to use for fixing problems.
|
||||
command! -bar ALEFixSuggest :call ale#fix#registry#Suggest(&filetype)
|
||||
|
||||
|
@ -229,8 +231,12 @@ command! -bar ALEDocumentation :call ale#hover#ShowDocumentationAtCursor()
|
|||
" Search for appearances of a symbol, such as a type name or function name.
|
||||
command! -nargs=1 ALESymbolSearch :call ale#symbol#Search(<q-args>)
|
||||
|
||||
" Complete text with tsserver and LSP
|
||||
command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual')
|
||||
|
||||
" Try to find completions for the current symbol that add additional text.
|
||||
command! -bar ALEImport :call ale#completion#Import()
|
||||
|
||||
" Rename symbols using tsserver and LSP
|
||||
command! -bar ALERename :call ale#rename#Execute()
|
||||
|
||||
|
@ -275,6 +281,7 @@ nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return>
|
|||
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
|
||||
nnoremap <silent> <Plug>(ale_documentation) :ALEDocumentation<Return>
|
||||
inoremap <silent> <Plug>(ale_complete) <C-\><C-O>:ALEComplete<Return>
|
||||
nnoremap <silent> <Plug>(ale_import) :ALEImport<Return>
|
||||
nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
|
||||
nnoremap <silent> <Plug>(ale_repeat_selection) :ALERepeatSelection<Return>
|
||||
|
||||
|
|
|
@ -49,12 +49,13 @@ class Source(Base):
|
|||
|
||||
if event == 'Async':
|
||||
result = self.vim.call('ale#completion#GetCompletionResult')
|
||||
|
||||
return result or []
|
||||
|
||||
if context.get('is_refresh'):
|
||||
self.vim.command(
|
||||
"call ale#completion#GetCompletions('ale-callback', " + \
|
||||
"{'callback': {completions -> deoplete#auto_complete() }})"
|
||||
"call ale#completion#GetCompletions('ale-callback', "
|
||||
+ "{'callback': {completions -> deoplete#auto_complete() }})"
|
||||
)
|
||||
|
||||
return []
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
Before:
|
||||
call ale#assert#SetUpLinterTest('handlebars', 'embertemplatelint')
|
||||
|
||||
GivenCommandOutput ['1.6.0']
|
||||
|
||||
After:
|
||||
call ale#assert#TearDownLinterTest()
|
||||
|
||||
Execute(ember-template-lint executables runs the right command):
|
||||
AssertLinter 'ember-template-lint',
|
||||
\ ale#Escape('ember-template-lint') . ' --json --filename %s'
|
||||
|
||||
Execute(old ember-template-lint executables runs the right command):
|
||||
GivenCommandOutput []
|
||||
|
||||
AssertLinter 'ember-template-lint',
|
||||
\ ale#Escape('ember-template-lint') . ' --json %t'
|
|
@ -8,6 +8,8 @@ Before:
|
|||
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
||||
let b:command_tail = ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
|
||||
|
||||
GivenCommandOutput ['pylint 2.3.0']
|
||||
|
||||
After:
|
||||
unlet! b:bin_dir
|
||||
unlet! b:executable
|
||||
|
@ -17,26 +19,33 @@ After:
|
|||
|
||||
Execute(The pylint callbacks should return the correct default values):
|
||||
AssertLinter 'pylint',
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pylint') . ' ' . b:command_tail
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ . ale#Escape('pylint') . b:command_tail
|
||||
|
||||
Execute(Pylint should run with the --from-stdin in new enough versions):
|
||||
GivenCommandOutput ['pylint 2.4.0']
|
||||
|
||||
AssertLinter 'pylint',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ . ale#Escape('pylint') . b:command_tail[:-3] . '--from-stdin %s'
|
||||
|
||||
Execute(The option for disabling changing directories should work):
|
||||
let g:ale_python_pylint_change_directory = 0
|
||||
|
||||
AssertLinter 'pylint', ale#Escape('pylint') . ' ' . b:command_tail
|
||||
AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail
|
||||
|
||||
Execute(The pylint executable should be configurable, and escaped properly):
|
||||
let g:ale_python_pylint_executable = 'executable with spaces'
|
||||
|
||||
AssertLinter 'executable with spaces',
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('executable with spaces') . ' ' . b:command_tail
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ . ale#Escape('executable with spaces') . b:command_tail
|
||||
|
||||
Execute(The pylint command callback should let you set options):
|
||||
let g:ale_python_pylint_options = '--some-option'
|
||||
|
||||
AssertLinter 'pylint',
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ . ale#Escape('pylint') . ' --some-option' . b:command_tail
|
||||
|
||||
Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist):
|
||||
|
@ -44,7 +53,7 @@ Execute(The pylint callbacks shouldn't detect virtualenv directories where they
|
|||
|
||||
AssertLinter 'pylint',
|
||||
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir'))
|
||||
\ . ale#Escape('pylint') . ' ' . b:command_tail
|
||||
\ . ale#Escape('pylint') . b:command_tail
|
||||
|
||||
Execute(The pylint callbacks should detect virtualenv directories):
|
||||
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
|
||||
|
@ -55,7 +64,7 @@ Execute(The pylint callbacks should detect virtualenv directories):
|
|||
|
||||
AssertLinter b:executable,
|
||||
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
|
||||
\ . ale#Escape(b:executable) . ' ' . b:command_tail
|
||||
\ . ale#Escape(b:executable) . b:command_tail
|
||||
|
||||
Execute(You should able able to use the global pylint instead):
|
||||
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
|
||||
|
@ -63,7 +72,7 @@ Execute(You should able able to use the global pylint instead):
|
|||
|
||||
AssertLinter 'pylint',
|
||||
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
|
||||
\ . ale#Escape('pylint') . ' ' . b:command_tail
|
||||
\ . ale#Escape('pylint') . b:command_tail
|
||||
|
||||
Execute(Setting executable to 'pipenv' appends 'run pylint'):
|
||||
let g:ale_python_pylint_executable = 'path/to/pipenv'
|
||||
|
@ -71,7 +80,7 @@ Execute(Setting executable to 'pipenv' appends 'run pylint'):
|
|||
AssertLinter 'path/to/pipenv',
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('path/to/pipenv') . ' run pylint'
|
||||
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
|
||||
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
|
||||
|
||||
Execute(Pipenv is detected when python_pylint_auto_pipenv is set):
|
||||
let g:ale_python_pylint_auto_pipenv = 1
|
||||
|
@ -80,4 +89,4 @@ Execute(Pipenv is detected when python_pylint_auto_pipenv is set):
|
|||
AssertLinter 'pipenv',
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pipenv') . ' run pylint'
|
||||
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
|
||||
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
Before:
|
||||
call ale#assert#SetUpLinterTest('vim', 'vint')
|
||||
let b:command_tail = (has('nvim') ? ' --enable-neovim' : '')
|
||||
\ . ' -f "{file_path}:{line_number}:{column_number}: {severity}: {policy_name} - {description} (see {reference})" %t'
|
||||
let b:common_flags = (has('nvim') ? ' --enable-neovim' : '')
|
||||
\ . ' -f "{file_path}:{line_number}:{column_number}: {severity}: {policy_name} - {description} (see {reference})"'
|
||||
|
||||
After:
|
||||
unlet! b:bin_dir
|
||||
unlet! b:executable
|
||||
unlet! b:common_flags
|
||||
|
||||
call ale#assert#TearDownLinterTest()
|
||||
|
||||
Execute(The default command should be correct):
|
||||
AssertLinter 'vint', [
|
||||
\ ale#Escape('vint') .' --version',
|
||||
\ ale#Escape('vint') .' -s --no-color' . b:command_tail,
|
||||
\ ale#Escape('vint') .' -s --no-color' . b:common_flags . ' %t',
|
||||
\]
|
||||
|
||||
Execute(The executable should be configurable):
|
||||
|
@ -19,5 +19,16 @@ Execute(The executable should be configurable):
|
|||
|
||||
AssertLinter 'foobar', [
|
||||
\ ale#Escape('foobar') .' --version',
|
||||
\ ale#Escape('foobar') .' -s --no-color' . b:command_tail,
|
||||
\ ale#Escape('foobar') .' -s --no-color' . b:common_flags . ' %t',
|
||||
\]
|
||||
|
||||
Execute(The --no-color flag should not be used for older Vint versions):
|
||||
GivenCommandOutput ['v0.3.5']
|
||||
|
||||
AssertLinter 'vint', ale#Escape('vint') .' -s' . b:common_flags . ' %t'
|
||||
|
||||
Execute(--stdin-display-name should be used in newer versions):
|
||||
GivenCommandOutput ['v0.4.0']
|
||||
|
||||
AssertLinter 'vint', ale#Escape('vint') .' -s --no-color' . b:common_flags
|
||||
\ . ' --stdin-display-name %s -'
|
||||
|
|
562
test/completion/test_ale_import_command.vader
Normal file
562
test/completion/test_ale_import_command.vader
Normal file
|
@ -0,0 +1,562 @@
|
|||
Before:
|
||||
Save g:ale_enabled
|
||||
Save b:ale_enabled
|
||||
Save g:ale_lint_on_text_changed
|
||||
Save g:ale_completion_enabled
|
||||
Save g:ale_completion_autoimport
|
||||
Save g:ale_completion_max_suggestions
|
||||
Save g:ale_linters
|
||||
Save b:ale_linters
|
||||
|
||||
let g:ale_enabled = 0
|
||||
let b:ale_enabled = 0
|
||||
let g:ale_lint_on_text_changed = 'always'
|
||||
let g:ale_completion_enabled = 0
|
||||
let g:ale_completion_autoimport = 0
|
||||
let g:ale_completion_max_suggestions = 50
|
||||
let g:ale_linters = {'typescript': ['tsserver'], 'python': ['pyre']}
|
||||
unlet! b:ale_linters
|
||||
|
||||
let g:server_started_value = 1
|
||||
let g:request_id = 0
|
||||
let g:LastCallback = v:null
|
||||
let g:LastHandleCallback = v:null
|
||||
let g:sent_message_list = []
|
||||
let g:code_action_list = []
|
||||
let g:execute_list = []
|
||||
let g:ale_queue_call_list = []
|
||||
|
||||
runtime autoload/ale.vim
|
||||
runtime autoload/ale/util.vim
|
||||
runtime autoload/ale/code_action.vim
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/lsp_linter.vim
|
||||
|
||||
function! ale#util#Execute(expr) abort
|
||||
call add(g:execute_list, a:expr)
|
||||
endfunction
|
||||
|
||||
function! ale#Queue(...) abort
|
||||
call add(g:ale_queue_call_list, a:000)
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#RegisterCallback(id, Callback) abort
|
||||
let g:LastHandleCallback = a:Callback
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#NotifyForChanges(id, buffer) abort
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#HasCapability(id, capability) abort
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#Send(id, message) abort
|
||||
let g:request_id += 1
|
||||
|
||||
call add(g:sent_message_list, a:message)
|
||||
|
||||
return g:request_id
|
||||
endfunction
|
||||
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let g:LastCallback = a:Callback
|
||||
|
||||
return g:server_started_value
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#HandleCodeAction(code_action, should_save) abort
|
||||
Assert !a:should_save
|
||||
|
||||
call add(g:code_action_list, a:code_action)
|
||||
endfunction
|
||||
|
||||
function GetLastMessage()
|
||||
return get(g:execute_list, -1, '')
|
||||
endfunction
|
||||
|
||||
function CheckLintStates(conn_id, message)
|
||||
" Check that we request more linter results after adding completions.
|
||||
AssertEqual [[0, '']], g:ale_queue_call_list
|
||||
|
||||
let g:ale_enabled = 0
|
||||
|
||||
let g:ale_queue_call_list = []
|
||||
call g:LastHandleCallback(a:conn_id, a:message)
|
||||
AssertEqual [], g:ale_queue_call_list
|
||||
|
||||
let g:ale_enabled = 1
|
||||
let g:ale_lint_on_text_changed = 1
|
||||
|
||||
let g:ale_queue_call_list = []
|
||||
call g:LastHandleCallback(a:conn_id, a:message)
|
||||
AssertEqual [[0, '']], g:ale_queue_call_list
|
||||
|
||||
let g:ale_lint_on_text_changed = 'normal'
|
||||
|
||||
let g:ale_queue_call_list = []
|
||||
call g:LastHandleCallback(a:conn_id, a:message)
|
||||
AssertEqual [[0, '']], g:ale_queue_call_list
|
||||
|
||||
let g:ale_lint_on_text_changed = 'insert'
|
||||
|
||||
let g:ale_queue_call_list = []
|
||||
call g:LastHandleCallback(a:conn_id, a:message)
|
||||
AssertEqual [[0, '']], g:ale_queue_call_list
|
||||
|
||||
let g:ale_queue_call_list = []
|
||||
let g:ale_lint_on_text_changed = 'never'
|
||||
|
||||
call g:LastHandleCallback(a:conn_id, a:message)
|
||||
AssertEqual [], g:ale_queue_call_list
|
||||
|
||||
let g:ale_lint_on_text_changed = '0'
|
||||
|
||||
call g:LastHandleCallback(a:conn_id, a:message)
|
||||
AssertEqual [], g:ale_queue_call_list
|
||||
|
||||
let g:ale_lint_on_text_changed = 0
|
||||
|
||||
call g:LastHandleCallback(a:conn_id, a:message)
|
||||
AssertEqual [], g:ale_queue_call_list
|
||||
|
||||
let g:ale_lint_on_text_changed = 'xxx'
|
||||
|
||||
call g:LastHandleCallback(a:conn_id, a:message)
|
||||
AssertEqual [], g:ale_queue_call_list
|
||||
endfunction
|
||||
|
||||
After:
|
||||
call ale#linter#Reset()
|
||||
|
||||
Restore
|
||||
|
||||
delfunction GetLastMessage
|
||||
delfunction CheckLintStates
|
||||
|
||||
unlet! g:LastCallback
|
||||
unlet! g:LastHandleCallback
|
||||
unlet! g:request_id
|
||||
unlet! g:server_started_value
|
||||
unlet! g:sent_message_list
|
||||
unlet! g:code_action_list
|
||||
unlet! g:ale_queue_call_list
|
||||
unlet! g:execute_list
|
||||
unlet! g:received_message
|
||||
unlet! b:ale_old_omnifunc
|
||||
unlet! b:ale_old_completeopt
|
||||
unlet! b:ale_completion_info
|
||||
unlet! b:ale_completion_result
|
||||
unlet! b:ale_complete_done_time
|
||||
|
||||
runtime autoload/ale.vim
|
||||
runtime autoload/ale/util.vim
|
||||
runtime autoload/ale/code_action.vim
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/lsp_linter.vim
|
||||
|
||||
Given typescript(Some example TypeScript code):
|
||||
let xyz = 123
|
||||
let foo = missingword
|
||||
|
||||
let abc = 456
|
||||
|
||||
Execute(ALEImport should complain when there's no word at the cursor):
|
||||
call setpos('.', [bufnr(''), 3, 1, 0])
|
||||
ALEImport
|
||||
|
||||
AssertEqual 'echom ''Nothing to complete at cursor!''', GetLastMessage()
|
||||
|
||||
Execute(ALEImport should tell the user if no LSP is available):
|
||||
let g:server_started_value = 0
|
||||
|
||||
call setpos('.', [bufnr(''), 2, 16, 0])
|
||||
ALEImport
|
||||
|
||||
AssertEqual
|
||||
\ 'echom ''No completion providers are available.''',
|
||||
\ GetLastMessage()
|
||||
|
||||
Execute(ALEImport should request imports correctly for tsserver):
|
||||
call setpos('.', [bufnr(''), 2, 16, 0])
|
||||
|
||||
ALEImport
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'conn_id': 0,
|
||||
\ 'request_id': 0,
|
||||
\ 'source': 'ale-import',
|
||||
\ 'column': 11,
|
||||
\ 'line': 2,
|
||||
\ 'line_length': 21,
|
||||
\ 'prefix': 'missingword',
|
||||
\ 'additional_edits_only': 1,
|
||||
\ },
|
||||
\ b:ale_completion_info
|
||||
Assert g:LastCallback isnot v:null
|
||||
|
||||
call g:LastCallback(ale#linter#Get(&filetype)[0], {
|
||||
\ 'connection_id': 347,
|
||||
\ 'buffer': bufnr(''),
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'conn_id': 347,
|
||||
\ 'request_id': 1,
|
||||
\ 'source': 'ale-import',
|
||||
\ 'column': 11,
|
||||
\ 'line': 2,
|
||||
\ 'line_length': 21,
|
||||
\ 'prefix': 'missingword',
|
||||
\ 'additional_edits_only': 1,
|
||||
\ },
|
||||
\ b:ale_completion_info
|
||||
Assert g:LastHandleCallback isnot v:null
|
||||
|
||||
call g:LastHandleCallback(347, {
|
||||
\ 'request_seq': 1,
|
||||
\ 'command': 'completions',
|
||||
\ 'body': [
|
||||
\ {'name': 'missingwordIgnoreMe'},
|
||||
\ {'name': 'missingword'},
|
||||
\ ],
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [0, 'ts@completions', {
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'includeExternalModuleExports': 1,
|
||||
\ 'offset': 11,
|
||||
\ 'line': 2,
|
||||
\ 'prefix': 'missingword',
|
||||
\ }],
|
||||
\ [0, 'ts@completionEntryDetails', {
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'entryNames': [{'name': 'missingword'}],
|
||||
\ 'offset': 11,
|
||||
\ 'line': 2,
|
||||
\ }]
|
||||
\ ],
|
||||
\ g:sent_message_list
|
||||
AssertEqual 2, b:ale_completion_info.request_id
|
||||
|
||||
let g:ale_enabled = 1
|
||||
let g:received_message = {
|
||||
\ 'request_seq': 2,
|
||||
\ 'command': 'completionEntryDetails',
|
||||
\ 'body': [
|
||||
\ {
|
||||
\ 'name': 'missingword',
|
||||
\ 'kind': 'className',
|
||||
\ 'displayParts': [],
|
||||
\ 'codeActions': [{
|
||||
\ 'description': 'import { missingword } from "./Something";',
|
||||
\ 'changes': [],
|
||||
\ }],
|
||||
\ },
|
||||
\ ],
|
||||
\}
|
||||
call g:LastHandleCallback(347, g:received_message)
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'description': 'import { missingword } from "./Something";',
|
||||
\ 'changes': [],
|
||||
\ },
|
||||
\ ],
|
||||
\ g:code_action_list
|
||||
|
||||
call CheckLintStates(347, g:received_message)
|
||||
|
||||
Execute(ALEImport should tell the user when no completions were found from tsserver):
|
||||
call setpos('.', [bufnr(''), 2, 16, 0])
|
||||
|
||||
ALEImport
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'conn_id': 0,
|
||||
\ 'request_id': 0,
|
||||
\ 'source': 'ale-import',
|
||||
\ 'column': 11,
|
||||
\ 'line': 2,
|
||||
\ 'line_length': 21,
|
||||
\ 'prefix': 'missingword',
|
||||
\ 'additional_edits_only': 1,
|
||||
\ },
|
||||
\ b:ale_completion_info
|
||||
Assert g:LastCallback isnot v:null
|
||||
|
||||
call g:LastCallback(ale#linter#Get(&filetype)[0], {
|
||||
\ 'connection_id': 347,
|
||||
\ 'buffer': bufnr(''),
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'conn_id': 347,
|
||||
\ 'request_id': 1,
|
||||
\ 'source': 'ale-import',
|
||||
\ 'column': 11,
|
||||
\ 'line': 2,
|
||||
\ 'line_length': 21,
|
||||
\ 'prefix': 'missingword',
|
||||
\ 'additional_edits_only': 1,
|
||||
\ },
|
||||
\ b:ale_completion_info
|
||||
Assert g:LastHandleCallback isnot v:null
|
||||
|
||||
call g:LastHandleCallback(347, {
|
||||
\ 'request_seq': 1,
|
||||
\ 'command': 'completions',
|
||||
\ 'body': [
|
||||
\ {'name': 'missingwordIgnoreMe'},
|
||||
\ ],
|
||||
\})
|
||||
|
||||
AssertEqual 'echom ''No possible imports found.''', GetLastMessage()
|
||||
|
||||
Given python(Some example Python code):
|
||||
xyz = 123
|
||||
foo = missingword
|
||||
|
||||
abc = 456
|
||||
|
||||
Execute(ALEImport should request imports correctly for language servers):
|
||||
call setpos('.', [bufnr(''), 2, 12, 0])
|
||||
|
||||
ALEImport
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'conn_id': 0,
|
||||
\ 'request_id': 0,
|
||||
\ 'source': 'ale-import',
|
||||
\ 'column': 7,
|
||||
\ 'line': 2,
|
||||
\ 'line_length': 17,
|
||||
\ 'prefix': 'missingword',
|
||||
\ 'additional_edits_only': 1,
|
||||
\ },
|
||||
\ b:ale_completion_info
|
||||
Assert g:LastCallback isnot v:null
|
||||
|
||||
call g:LastCallback(ale#linter#Get(&filetype)[0], {
|
||||
\ 'connection_id': 347,
|
||||
\ 'buffer': bufnr(''),
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'conn_id': 347,
|
||||
\ 'request_id': 1,
|
||||
\ 'source': 'ale-import',
|
||||
\ 'column': 7,
|
||||
\ 'line': 2,
|
||||
\ 'line_length': 17,
|
||||
\ 'prefix': 'missingword',
|
||||
\ 'additional_edits_only': 1,
|
||||
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
|
||||
\ },
|
||||
\ b:ale_completion_info
|
||||
Assert g:LastHandleCallback isnot v:null
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [0, 'textDocument/completion', {
|
||||
\ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))},
|
||||
\ 'position': {'character': 6, 'line': 1}
|
||||
\ }],
|
||||
\ ],
|
||||
\ g:sent_message_list
|
||||
AssertEqual 1, b:ale_completion_info.request_id
|
||||
|
||||
let g:ale_enabled = 1
|
||||
let g:received_message = {
|
||||
\ 'id': 1,
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'result': {
|
||||
\ 'isIncomplete': v:false,
|
||||
\ 'items': [
|
||||
\ {
|
||||
\ 'detail': 'Some other word we should ignore',
|
||||
\ 'filterText': 'missingwordIgnoreMe',
|
||||
\ 'insertText': 'missingwordIgnoreMe',
|
||||
\ 'insertTextFormat': 1,
|
||||
\ 'kind': 6,
|
||||
\ 'label': ' missingwordIgnoreMe',
|
||||
\ 'sortText': '3ee19999missingword',
|
||||
\ 'additionalTextEdits': [
|
||||
\ {
|
||||
\ 'range': {
|
||||
\ 'start': {'line': 1, 'character': 1},
|
||||
\ 'end': {'line': 2, 'character': 1},
|
||||
\ },
|
||||
\ 'newText': 'from something import missingwordIgnoreMe',
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ {
|
||||
\ 'detail': 'Some word without text edits',
|
||||
\ 'filterText': 'missingword',
|
||||
\ 'insertText': 'missingword',
|
||||
\ 'insertTextFormat': 1,
|
||||
\ 'kind': 6,
|
||||
\ 'label': ' missingword',
|
||||
\ 'sortText': '3ee19999missingword',
|
||||
\ },
|
||||
\ {
|
||||
\ 'detail': 'The word we should use',
|
||||
\ 'filterText': 'missingword',
|
||||
\ 'insertText': 'missingword',
|
||||
\ 'insertTextFormat': 1,
|
||||
\ 'kind': 6,
|
||||
\ 'label': ' missingword',
|
||||
\ 'sortText': '3ee19999missingword',
|
||||
\ 'additionalTextEdits': [
|
||||
\ {
|
||||
\ 'range': {
|
||||
\ 'start': {'line': 1, 'character': 1},
|
||||
\ 'end': {'line': 2, 'character': 1},
|
||||
\ },
|
||||
\ 'newText': 'from something import missingword',
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ {
|
||||
\ 'detail': 'The other word we should not use',
|
||||
\ 'filterText': 'missingword',
|
||||
\ 'insertText': 'missingword',
|
||||
\ 'insertTextFormat': 1,
|
||||
\ 'kind': 6,
|
||||
\ 'label': ' missingword',
|
||||
\ 'sortText': '3ee19999missingword',
|
||||
\ 'additionalTextEdits': [
|
||||
\ {
|
||||
\ 'range': {
|
||||
\ 'start': {'line': 1, 'character': 1},
|
||||
\ 'end': {'line': 2, 'character': 1},
|
||||
\ },
|
||||
\ 'newText': 'from something_else import missingword',
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\}
|
||||
call g:LastHandleCallback(347, g:received_message)
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'description': 'completion',
|
||||
\ 'changes': [
|
||||
\ {
|
||||
\ 'fileName': expand('%:p'),
|
||||
\ 'textChanges': [
|
||||
\ {
|
||||
\ 'start': {'line': 2, 'offset': 2},
|
||||
\ 'end': {'line': 3, 'offset': 2},
|
||||
\ 'newText': 'from something import missingword',
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ ],
|
||||
\ g:code_action_list
|
||||
|
||||
call CheckLintStates(347, g:received_message)
|
||||
|
||||
Execute(ALEImport should tell the user when no completions were found from a language server):
|
||||
call setpos('.', [bufnr(''), 2, 12, 0])
|
||||
|
||||
ALEImport
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'conn_id': 0,
|
||||
\ 'request_id': 0,
|
||||
\ 'source': 'ale-import',
|
||||
\ 'column': 7,
|
||||
\ 'line': 2,
|
||||
\ 'line_length': 17,
|
||||
\ 'prefix': 'missingword',
|
||||
\ 'additional_edits_only': 1,
|
||||
\ },
|
||||
\ b:ale_completion_info
|
||||
Assert g:LastCallback isnot v:null
|
||||
|
||||
call g:LastCallback(ale#linter#Get(&filetype)[0], {
|
||||
\ 'connection_id': 347,
|
||||
\ 'buffer': bufnr(''),
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'conn_id': 347,
|
||||
\ 'request_id': 1,
|
||||
\ 'source': 'ale-import',
|
||||
\ 'column': 7,
|
||||
\ 'line': 2,
|
||||
\ 'line_length': 17,
|
||||
\ 'prefix': 'missingword',
|
||||
\ 'additional_edits_only': 1,
|
||||
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
|
||||
\ },
|
||||
\ b:ale_completion_info
|
||||
Assert g:LastHandleCallback isnot v:null
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [0, 'textDocument/completion', {
|
||||
\ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))},
|
||||
\ 'position': {'character': 6, 'line': 1}
|
||||
\ }],
|
||||
\ ],
|
||||
\ g:sent_message_list
|
||||
AssertEqual 1, b:ale_completion_info.request_id
|
||||
|
||||
let g:received_message = {
|
||||
\ 'id': 1,
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'result': {
|
||||
\ 'isIncomplete': v:false,
|
||||
\ 'items': [
|
||||
\ {
|
||||
\ 'detail': 'Some other word we should ignore',
|
||||
\ 'filterText': 'missingwordIgnoreMe',
|
||||
\ 'insertText': 'missingwordIgnoreMe',
|
||||
\ 'insertTextFormat': 1,
|
||||
\ 'kind': 6,
|
||||
\ 'label': ' missingwordIgnoreMe',
|
||||
\ 'sortText': '3ee19999missingword',
|
||||
\ 'additionalTextEdits': [
|
||||
\ {
|
||||
\ 'range': {
|
||||
\ 'start': {'line': 1, 'character': 1},
|
||||
\ 'end': {'line': 2, 'character': 1},
|
||||
\ },
|
||||
\ 'newText': 'from something import missingwordIgnoreMe',
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ {
|
||||
\ 'detail': 'Some word without text edits',
|
||||
\ 'filterText': 'missingword',
|
||||
\ 'insertText': 'missingword',
|
||||
\ 'insertTextFormat': 1,
|
||||
\ 'kind': 6,
|
||||
\ 'label': ' missingword',
|
||||
\ 'sortText': '3ee19999missingword',
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\}
|
||||
call g:LastHandleCallback(347, g:received_message)
|
||||
|
||||
AssertEqual 'echom ''No possible imports found.''', GetLastMessage()
|
35
test/completion/test_complete_events.vader
Normal file
35
test/completion/test_complete_events.vader
Normal file
|
@ -0,0 +1,35 @@
|
|||
Before:
|
||||
let g:complete_post_triggered = 0
|
||||
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALECompletePost let g:complete_post_triggered = 1
|
||||
augroup END
|
||||
|
||||
After:
|
||||
unlet! b:ale_completion_info
|
||||
unlet! g:complete_post_triggered
|
||||
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
augroup! VaderTest
|
||||
|
||||
Execute(ALECompletePost should not be triggered when completion is cancelled):
|
||||
call ale#completion#HandleUserData({})
|
||||
|
||||
Assert !g:complete_post_triggered
|
||||
|
||||
Execute(ALECompletePost should not be triggered when tools other than ALE insert completions):
|
||||
call ale#completion#HandleUserData({'user_data': ''})
|
||||
call ale#completion#HandleUserData({'user_data': '{}'})
|
||||
|
||||
Assert !g:complete_post_triggered
|
||||
|
||||
Execute(ALECompletePost should be triggered when ALE inserts completions):
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': json_encode({'_ale_completion_item': 1}),
|
||||
\})
|
||||
|
||||
Assert g:complete_post_triggered
|
|
@ -407,41 +407,75 @@ Execute(HandleUserData should call ale#code_action#HandleCodeAction):
|
|||
AssertEqual g:handle_code_action_called, 0
|
||||
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': ''
|
||||
\ 'user_data': ''
|
||||
\})
|
||||
AssertEqual g:handle_code_action_called, 0
|
||||
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': '{}'
|
||||
\ 'user_data': json_encode({}),
|
||||
\})
|
||||
AssertEqual g:handle_code_action_called, 0
|
||||
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': '{"codeActions": []}'
|
||||
\ 'user_data': json_encode({
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [],
|
||||
\ }),
|
||||
\})
|
||||
AssertEqual g:handle_code_action_called, 0
|
||||
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': '{"codeActions": [{"description":"", "changes": []}]}'
|
||||
\ 'user_data': json_encode({
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [
|
||||
\ {'description': '', 'changes': []},
|
||||
\ ],
|
||||
\ }),
|
||||
\})
|
||||
AssertEqual g:handle_code_action_called, 1
|
||||
|
||||
let b:ale_completion_info = {'source': 'ale-automatic'}
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': '{"codeActions": [{"description":"", "changes": []}]}'
|
||||
\ 'user_data': json_encode({
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [
|
||||
\ {'description': '', 'changes': []},
|
||||
\ ],
|
||||
\ }),
|
||||
\})
|
||||
AssertEqual g:handle_code_action_called, 2
|
||||
|
||||
let b:ale_completion_info = {'source': 'ale-callback'}
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': '{"codeActions": [{"description":"", "changes": []}]}'
|
||||
\ 'user_data': json_encode({
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [
|
||||
\ {'description': '', 'changes': []},
|
||||
\ ],
|
||||
\ }),
|
||||
\})
|
||||
AssertEqual g:handle_code_action_called, 3
|
||||
|
||||
let b:ale_completion_info = {'source': 'ale-omnifunc'}
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': json_encode({
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [
|
||||
\ {'description': '', 'changes': []},
|
||||
\ ],
|
||||
\ }),
|
||||
\})
|
||||
AssertEqual g:handle_code_action_called, 4
|
||||
|
||||
Execute(ale#code_action#HandleCodeAction should not be called when when source is not ALE):
|
||||
call MockHandleCodeAction()
|
||||
let b:ale_completion_info = {'source': 'syntastic'}
|
||||
call ale#completion#HandleUserData({
|
||||
\ 'user_data': '{"codeActions": [{"description":"", "changes": []}]}'
|
||||
\ 'user_data': json_encode({
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [
|
||||
\ {'description': '', 'changes': []},
|
||||
\ ],
|
||||
\ }),
|
||||
\})
|
||||
AssertEqual g:handle_code_action_called, 0
|
||||
|
|
|
@ -12,13 +12,24 @@ After:
|
|||
Execute(Prefix filtering should work for Lists of strings):
|
||||
AssertEqual
|
||||
\ ['FooBar', 'foo'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo')
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 0)
|
||||
AssertEqual
|
||||
\ ['FooBar', 'FongBar', 'baz', 'foo'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.')
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 0)
|
||||
AssertEqual
|
||||
\ ['FooBar', 'FongBar', 'baz', 'foo'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '')
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '', 0)
|
||||
|
||||
Execute(Exact filtering should work):
|
||||
AssertEqual
|
||||
\ ['foo'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 1)
|
||||
AssertEqual
|
||||
\ ['FooBar', 'FongBar', 'baz', 'foo'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 1)
|
||||
AssertEqual
|
||||
\ ['Foo'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'Foo', 'foo'], 'Foo', 1)
|
||||
|
||||
Execute(Prefix filtering should work for completion items):
|
||||
AssertEqual
|
||||
|
@ -32,7 +43,8 @@ Execute(Prefix filtering should work for completion items):
|
|||
\ {'word': 'baz'},
|
||||
\ {'word': 'foo'},
|
||||
\ ],
|
||||
\ 'foo'
|
||||
\ 'foo',
|
||||
\ 0,
|
||||
\ )
|
||||
|
||||
AssertEqual
|
||||
|
@ -51,7 +63,8 @@ Execute(Prefix filtering should work for completion items):
|
|||
\ {'word': 'baz'},
|
||||
\ {'word': 'foo'},
|
||||
\ ],
|
||||
\ '.'
|
||||
\ '.',
|
||||
\ 0,
|
||||
\ )
|
||||
|
||||
Execute(Excluding words from completion results should work):
|
||||
|
@ -66,7 +79,8 @@ Execute(Excluding words from completion results should work):
|
|||
\ {'word': 'Italian'},
|
||||
\ {'word': 'it'},
|
||||
\ ],
|
||||
\ 'it'
|
||||
\ 'it',
|
||||
\ 0,
|
||||
\ )
|
||||
|
||||
AssertEqual
|
||||
|
@ -78,7 +92,8 @@ Execute(Excluding words from completion results should work):
|
|||
\ {'word': 'describe'},
|
||||
\ {'word': 'Deutsch'},
|
||||
\ ],
|
||||
\ 'de'
|
||||
\ 'de',
|
||||
\ 0,
|
||||
\ )
|
||||
|
||||
AssertEqual
|
||||
|
@ -90,7 +105,8 @@ Execute(Excluding words from completion results should work):
|
|||
\ {'word': 'describe'},
|
||||
\ {'word': 'Deutsch'},
|
||||
\ ],
|
||||
\ '.'
|
||||
\ '.',
|
||||
\ 0,
|
||||
\ )
|
||||
|
||||
Execute(Excluding words from completion results should work with lists of Strings):
|
||||
|
@ -98,29 +114,29 @@ Execute(Excluding words from completion results should work with lists of String
|
|||
|
||||
AssertEqual
|
||||
\ ['Italian'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it')
|
||||
\ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it', 0)
|
||||
AssertEqual
|
||||
\ ['Deutsch'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de')
|
||||
\ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de', 0)
|
||||
AssertEqual
|
||||
\ ['Deutsch'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.')
|
||||
\ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.', 0)
|
||||
AssertEqual
|
||||
\ ['Deutsch'],
|
||||
\ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '')
|
||||
\ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '', 0)
|
||||
|
||||
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 [], ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0)
|
||||
AssertEqual b:suggestions, [{'word': 'describe'}]
|
||||
AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de')
|
||||
AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de', 0)
|
||||
AssertEqual b:suggestions, [{'word': 'describe'}]
|
||||
|
||||
Execute(Filtering should respect filetype triggers):
|
||||
let b:suggestions = [{'word': 'describe'}]
|
||||
|
||||
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.')
|
||||
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.')
|
||||
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::')
|
||||
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0)
|
||||
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.', 0)
|
||||
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::', 0)
|
||||
|
|
|
@ -12,34 +12,34 @@ After:
|
|||
Execute(Should handle Rust completion results correctly):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'word': 'new', 'menu': 'pub fn new() -> String', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'with_capacity', 'menu': 'pub fn with_capacity(capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'from_utf8', 'menu': 'pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'from_utf8_lossy', 'menu': 'pub fn from_utf8_lossy<''a>(v: &''a [u8]) -> Cow<''a, str>', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'from_utf16', 'menu': 'pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'from_utf16_lossy', 'menu': 'pub fn from_utf16_lossy(v: &[u16]) -> String', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'from_raw_parts', 'menu': 'pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'from_utf8_unchecked', 'menu': 'pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'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': 't', 'icase': 1},
|
||||
\ {'word': 'default', 'menu': 'fn default() -> String', '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},
|
||||
\ {'word': 'from', 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'new', 'menu': 'pub fn new() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'with_capacity', 'menu': 'pub fn with_capacity(capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_utf8', 'menu': 'pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_utf8_lossy', 'menu': 'pub fn from_utf8_lossy<''a>(v: &''a [u8]) -> Cow<''a, str>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_utf16', 'menu': 'pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_utf16_lossy', 'menu': 'pub fn from_utf16_lossy(v: &[u16]) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_raw_parts', 'menu': 'pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_utf8_unchecked', 'menu': 'pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a str>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = Cow<''a, str>>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Searcher', 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'default', 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Output', 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'Err', 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from_str', 'menu': 'fn from_str(s: &str) -> Result<String, ParseError>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from', 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from', 'menu': 'fn from(s: Box<str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'from', 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ "jsonrpc":"2.0",
|
||||
|
@ -195,7 +195,7 @@ Execute(Should handle Python completion results correctly):
|
|||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'word': 'what', 'menu': 'example-python-project.bar.Bar', 'info': "what()\n\n", 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'what', 'menu': 'example-python-project.bar.Bar', 'info': "what()\n\n", 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ ],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ "jsonrpc":"2.0",
|
||||
|
@ -399,7 +399,7 @@ Execute(Should handle Python completion results correctly):
|
|||
\ }
|
||||
\ })
|
||||
|
||||
Execute(Should handle Python completion results correctly):
|
||||
Execute(Should handle extra Python completion results correctly):
|
||||
let b:ale_completion_info = {
|
||||
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
|
||||
\ 'prefix': 'mig',
|
||||
|
@ -407,8 +407,8 @@ Execute(Should handle Python completion results correctly):
|
|||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'word': 'migrations', 'menu': 'xxx', 'info': 'migrations', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'MigEngine', 'menu': 'xxx', 'info': 'mig engine', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'migrations', 'menu': 'xxx', 'info': 'migrations', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ {'word': 'MigEngine', 'menu': 'xxx', 'info': 'mig engine', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ ],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ 'jsonrpc': '2.0',
|
||||
|
@ -441,7 +441,7 @@ Execute(Should handle Python completion results correctly):
|
|||
Execute(Should handle missing keys):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'word': 'x', 'menu': '', 'info': '', 'kind': 'v', 'icase': 1},
|
||||
\ {'word': 'x', 'menu': '', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ ],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ 'jsonrpc': '2.0',
|
||||
|
@ -459,7 +459,7 @@ Execute(Should handle missing keys):
|
|||
Execute(Should handle documentation in the markdown format):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'word': 'migrations', 'menu': 'xxx', 'info': 'Markdown documentation', 'kind': 'f', 'icase': 1},
|
||||
\ {'word': 'migrations', 'menu': 'xxx', 'info': 'Markdown documentation', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ ],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ 'jsonrpc': '2.0',
|
||||
|
@ -483,7 +483,7 @@ Execute(Should handle documentation in the markdown format):
|
|||
Execute(Should handle completion messages with textEdit objects):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1},
|
||||
\ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ ],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ 'id': 226,
|
||||
|
@ -514,7 +514,7 @@ Execute(Should handle completion messages with textEdit objects):
|
|||
Execute(Should handle completion messages with the deprecated insertText attribute):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1},
|
||||
\ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
|
||||
\ ],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ 'id': 226,
|
||||
|
@ -547,7 +547,8 @@ Execute(Should handle completion messages with additionalTextEdits when ale_comp
|
|||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({
|
||||
\ 'codeActions': [
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [
|
||||
\ {
|
||||
\ 'description': 'completion',
|
||||
\ 'changes': [
|
||||
|
@ -658,6 +659,7 @@ Execute(Should still handle completion messages with empty additionalTextEdits w
|
|||
\ 'info': '',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({'_ale_completion_item': 1}),
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
|
|
|
@ -90,6 +90,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
|
|||
\ 'info': '',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({'_ale_completion_item': 1}),
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ {
|
||||
|
@ -98,6 +99,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
|
|||
\ 'info': 'foo bar baz',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({'_ale_completion_item': 1}),
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ {
|
||||
|
@ -106,6 +108,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
|
|||
\ 'info': '',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({'_ale_completion_item': 1}),
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ ],
|
||||
|
@ -179,7 +182,8 @@ Execute(Entries without details should be included in the responses):
|
|||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({
|
||||
\ 'codeActions': [{
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [{
|
||||
\ 'description': 'import { def } from "./Foo";',
|
||||
\ 'changes': [],
|
||||
\ }],
|
||||
|
@ -192,6 +196,7 @@ Execute(Entries without details should be included in the responses):
|
|||
\ 'info': 'foo bar baz',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({'_ale_completion_item': 1}),
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ {
|
||||
|
@ -199,6 +204,7 @@ Execute(Entries without details should be included in the responses):
|
|||
\ 'menu': '',
|
||||
\ 'info': '',
|
||||
\ 'kind': 'v',
|
||||
\ 'user_data': json_encode({'_ale_completion_item': 1}),
|
||||
\ 'icase': 1,
|
||||
\ },
|
||||
\ ],
|
||||
|
@ -260,7 +266,8 @@ Execute(Default imports should be handled correctly):
|
|||
\ 'kind': 't',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({
|
||||
\ 'codeActions': [{
|
||||
\ '_ale_completion_item': 1,
|
||||
\ 'code_actions': [{
|
||||
\ 'description': 'Import default ''abcd'' from module "./foo"',
|
||||
\ 'changes': [],
|
||||
\ }],
|
||||
|
|
|
@ -196,6 +196,10 @@ After:
|
|||
" Clear the messages between tests.
|
||||
echomsg ''
|
||||
|
||||
if !exists('g:ale_command_wrapper')
|
||||
let g:ale_command_wrapper = ''
|
||||
endif
|
||||
|
||||
Given testft (A file with three lines):
|
||||
a
|
||||
b
|
||||
|
@ -206,6 +210,13 @@ Execute(ALEFix should complain when there are no functions to call):
|
|||
call ale#test#FlushJobs()
|
||||
AssertEqual 'No fixers have been defined. Try :ALEFixSuggest', GetLastMessage()
|
||||
|
||||
Execute(ALEFix should not complain when the command is run with a bang):
|
||||
echom 'none'
|
||||
|
||||
ALEFix!
|
||||
call ale#test#FlushJobs()
|
||||
AssertEqual 'none', GetLastMessage()
|
||||
|
||||
Execute(ALEFix should apply simple functions):
|
||||
let g:ale_fixers.testft = ['AddCarets']
|
||||
ALEFix
|
||||
|
@ -715,6 +726,19 @@ Execute(ale#fix#InitBufferData() should set up the correct data):
|
|||
\ 'done': 0,
|
||||
\ 'lines_before': ['a', 'b', 'c'],
|
||||
\ 'should_save': 1,
|
||||
\ 'ignore_file_changed_errors': 0,
|
||||
\ },
|
||||
\}, g:ale_fix_buffer_data
|
||||
|
||||
call ale#fix#InitBufferData(bufnr(''), '!')
|
||||
|
||||
AssertEqual {
|
||||
\ bufnr(''): {
|
||||
\ 'temporary_directory_list': [],
|
||||
\ 'done': 0,
|
||||
\ 'lines_before': ['a', 'b', 'c'],
|
||||
\ 'should_save': 0,
|
||||
\ 'ignore_file_changed_errors': 1,
|
||||
\ },
|
||||
\}, g:ale_fix_buffer_data
|
||||
|
||||
|
|
|
@ -44,9 +44,21 @@ After:
|
|||
Given foobar(An empty file):
|
||||
Execute(tsserver syntax error responses should be handled correctly):
|
||||
runtime ale_linters/typescript/tsserver.vim
|
||||
call ale#test#SetFilename('filename.ts')
|
||||
|
||||
if has('win32')
|
||||
call ale#test#SetFilename('filename,[]^$.ts')
|
||||
else
|
||||
call ale#test#SetFilename('filename*?,{}[]^$.ts')
|
||||
endif
|
||||
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
if has('win32')
|
||||
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
|
||||
else
|
||||
AssertEqual 'filename*?,{}[]^$.ts', expand('%:p:t')
|
||||
endif
|
||||
|
||||
" When we get syntax errors and no semantic errors, we should keep the
|
||||
" syntax errors.
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
|
@ -54,7 +66,7 @@ Execute(tsserver syntax error responses should be handled correctly):
|
|||
\ 'type': 'event',
|
||||
\ 'event': 'syntaxDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir . '/filename.ts',
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ {
|
||||
\ 'start': {
|
||||
|
@ -76,7 +88,7 @@ Execute(tsserver syntax error responses should be handled correctly):
|
|||
\ 'type': 'event',
|
||||
\ 'event': 'semanticDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir . '/filename.ts',
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ ],
|
||||
\ },
|
||||
|
@ -104,7 +116,7 @@ Execute(tsserver syntax error responses should be handled correctly):
|
|||
\ 'type': 'event',
|
||||
\ 'event': 'syntaxDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir . '/filename.ts',
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ ],
|
||||
\ },
|
||||
|
@ -146,9 +158,21 @@ Execute(tsserver syntax error responses should be handled correctly):
|
|||
|
||||
Execute(tsserver semantic error responses should be handled correctly):
|
||||
runtime ale_linters/typescript/tsserver.vim
|
||||
call ale#test#SetFilename('filename.ts')
|
||||
|
||||
if has('win32')
|
||||
call ale#test#SetFilename('filename,[]^$.ts')
|
||||
else
|
||||
call ale#test#SetFilename('filename*?,{}[]^$.ts')
|
||||
endif
|
||||
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
if has('win32')
|
||||
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
|
||||
else
|
||||
AssertEqual 'filename*?,{}[]^$.ts', expand('%:p:t')
|
||||
endif
|
||||
|
||||
" When we get syntax errors and no semantic errors, we should keep the
|
||||
" syntax errors.
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
|
@ -156,7 +180,7 @@ Execute(tsserver semantic error responses should be handled correctly):
|
|||
\ 'type': 'event',
|
||||
\ 'event': 'syntaxDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir . '/filename.ts',
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ ],
|
||||
\ },
|
||||
|
@ -166,7 +190,7 @@ Execute(tsserver semantic error responses should be handled correctly):
|
|||
\ 'type': 'event',
|
||||
\ 'event': 'semanticDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir . '/filename.ts',
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ {
|
||||
\ 'start': {
|
||||
|
@ -206,7 +230,7 @@ Execute(tsserver semantic error responses should be handled correctly):
|
|||
\ 'type': 'event',
|
||||
\ 'event': 'semanticDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir . '/filename.ts',
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ ],
|
||||
\ },
|
||||
|
@ -270,15 +294,27 @@ Execute(tsserver errors should mark tsserver no longer active):
|
|||
Execute(LSP diagnostics responses should be handled correctly):
|
||||
let b:ale_linters = ['eclipselsp']
|
||||
runtime ale_linters/java/eclipselsp.vim
|
||||
call ale#test#SetFilename('filename.java')
|
||||
|
||||
if has('win32')
|
||||
call ale#test#SetFilename('filename,[]^$.ts')
|
||||
else
|
||||
call ale#test#SetFilename('filename*?,{}[]^$.java')
|
||||
endif
|
||||
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
call ale#lsp_linter#SetLSPLinterMap({'1': 'eclipselsp'})
|
||||
|
||||
if has('win32')
|
||||
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
|
||||
else
|
||||
AssertEqual 'filename*?,{}[]^$.java', expand('%:p:t')
|
||||
endif
|
||||
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'jsonrpc':'2.0',
|
||||
\ 'method':'textDocument/publishDiagnostics',
|
||||
\ 'params': {
|
||||
\ 'uri':'file://' . g:dir . '/filename.java',
|
||||
\ 'uri': ale#path#ToURI(expand('%:p')),
|
||||
\ 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Execute(Checks for versions below the current version should succeed):
|
||||
AssertEqual 1, ale#Has('ale-3.0.0')
|
||||
AssertEqual 1, ale#Has('ale-2.7.0')
|
||||
AssertEqual 1, ale#Has('ale-2.6.0')
|
||||
AssertEqual 1, ale#Has('ale-2.5.0')
|
||||
|
|
|
@ -6,6 +6,7 @@ Before:
|
|||
Save g:ale_completion_delay
|
||||
Save g:ale_completion_enabled
|
||||
Save g:ale_completion_max_suggestions
|
||||
Save g:ale_disable_lsp
|
||||
Save g:ale_echo_cursor
|
||||
Save g:ale_echo_msg_error_str
|
||||
Save g:ale_echo_msg_format
|
||||
|
@ -24,6 +25,7 @@ Before:
|
|||
Save g:ale_lint_on_text_changed
|
||||
Save g:ale_linters
|
||||
Save g:ale_linters_explicit
|
||||
Save g:ale_linters_ignore
|
||||
Save g:ale_list_vertical
|
||||
Save g:ale_list_window_size
|
||||
Save g:ale_loclist_msg_format
|
||||
|
@ -64,6 +66,7 @@ Before:
|
|||
let g:ale_completion_delay = 100
|
||||
let g:ale_completion_enabled = 0
|
||||
let g:ale_completion_max_suggestions = 50
|
||||
let g:ale_disable_lsp = 0
|
||||
let g:ale_echo_cursor = 1
|
||||
let g:ale_echo_msg_error_str = 'Error'
|
||||
let g:ale_echo_msg_format = '%code: %%s'
|
||||
|
@ -80,6 +83,7 @@ Before:
|
|||
let g:ale_lint_on_save = 1
|
||||
let g:ale_lint_on_text_changed = 'normal'
|
||||
let g:ale_linters_explicit = 0
|
||||
let g:ale_linters_ignore = {'python': ['pyright']}
|
||||
let g:ale_list_vertical = 0
|
||||
let g:ale_list_window_size = 10
|
||||
let g:ale_loclist_msg_format = '%code: %%s'
|
||||
|
@ -138,6 +142,7 @@ Before:
|
|||
\ 'let g:ale_completion_delay = 100',
|
||||
\ 'let g:ale_completion_enabled = 0',
|
||||
\ 'let g:ale_completion_max_suggestions = 50',
|
||||
\ 'let g:ale_disable_lsp = 0',
|
||||
\ 'let g:ale_echo_cursor = 1',
|
||||
\ 'let g:ale_echo_msg_error_str = ''Error''',
|
||||
\ 'let g:ale_echo_msg_format = ''%code: %%s''',
|
||||
|
@ -158,6 +163,7 @@ Before:
|
|||
\ 'let g:ale_linter_aliases = {}',
|
||||
\ 'let g:ale_linters = {}',
|
||||
\ 'let g:ale_linters_explicit = 0',
|
||||
\ 'let g:ale_linters_ignore = {''python'': [''pyright'']}',
|
||||
\ 'let g:ale_list_vertical = 0',
|
||||
\ 'let g:ale_list_window_size = 10',
|
||||
\ 'let g:ale_loclist_msg_format = ''%code: %%s''',
|
||||
|
@ -243,6 +249,7 @@ Execute (ALEInfo with no linters should return the right output):
|
|||
\ ' Current Filetype: nolintersft',
|
||||
\ 'Available Linters: []',
|
||||
\ ' Enabled Linters: []',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -265,6 +272,7 @@ Execute (ALEInfo should return buffer-local global ALE settings):
|
|||
\ ' Current Filetype: ',
|
||||
\ 'Available Linters: []',
|
||||
\ ' Enabled Linters: []',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -279,6 +287,7 @@ Execute (ALEInfo with no filetype should return the right output):
|
|||
\ ' Current Filetype: ',
|
||||
\ 'Available Linters: []',
|
||||
\ ' Enabled Linters: []',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -295,6 +304,7 @@ Execute (ALEInfo with a single linter should return the right output):
|
|||
\ ' Current Filetype: testft',
|
||||
\ 'Available Linters: [''testlinter1'']',
|
||||
\ ' Enabled Linters: [''testlinter1'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -312,6 +322,7 @@ Execute (ALEInfo with two linters should return the right output):
|
|||
\ ' Current Filetype: testft',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -333,6 +344,7 @@ Execute (ALEInfo should calculate enabled linters correctly):
|
|||
\ ' Current Filetype: testft',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -350,6 +362,7 @@ Execute (ALEInfo should only return linters for current filetype):
|
|||
\ ' Current Filetype: testft',
|
||||
\ 'Available Linters: [''testlinter1'']',
|
||||
\ ' Enabled Linters: [''testlinter1'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -367,6 +380,7 @@ Execute (ALEInfo with compound filetypes should return linters for both of them)
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -389,6 +403,7 @@ Execute (ALEInfo should return appropriately named global variables):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + [
|
||||
|
@ -420,6 +435,7 @@ Execute (ALEInfoToFile should write to a file correctly):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + [
|
||||
|
@ -447,6 +463,7 @@ Execute (ALEInfo should buffer-local linter variables):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + [
|
||||
|
@ -478,6 +495,7 @@ Execute (ALEInfo should output linter aliases):
|
|||
\ '''testlinter1'' -> [''testftalias1'', ''testftalias2'']',
|
||||
\ '''testlinter2'' -> [''testftalias3'', ''testftalias4'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + [
|
||||
|
@ -505,6 +523,7 @@ Execute (ALEInfo should return command history):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -532,6 +551,7 @@ Execute (ALEInfo command history should print exit codes correctly):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -580,6 +600,7 @@ Execute (ALEInfo command history should print command output if logging is on):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -618,6 +639,7 @@ Execute (ALEInfo should include executable checks in the history):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'']',
|
||||
\ ' Enabled Linters: [''testlinter1'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -647,6 +669,7 @@ Execute (The option for caching failing executable checks should work):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'']',
|
||||
\ ' Enabled Linters: [''testlinter1'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -669,6 +692,7 @@ Execute (LSP errors for a linter should be outputted):
|
|||
\ ' Current Filetype: testft',
|
||||
\ 'Available Linters: [''testlinter1'']',
|
||||
\ ' Enabled Linters: [''testlinter1'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -693,6 +717,7 @@ Execute (LSP errors for other linters shouldn't appear):
|
|||
\ ' Current Filetype: testft',
|
||||
\ 'Available Linters: [''testlinter1'']',
|
||||
\ ' Enabled Linters: [''testlinter1'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -715,6 +740,7 @@ Execute (ALEInfo should include linter global options):
|
|||
\ ' Current Filetype: testft.testft2',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
@ -740,6 +766,7 @@ Execute (ALEInfo should include linter global options for enabled linters):
|
|||
\ ' Current Filetype: testft',
|
||||
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
|
||||
\ ' Enabled Linters: [''testlinter1'']',
|
||||
\ ' Ignored Linters: []',
|
||||
\ ]
|
||||
\ + g:fixer_lines
|
||||
\ + g:variables_lines
|
||||
|
|
27
test/test_ale_lint_stop_command.vader
Normal file
27
test/test_ale_lint_stop_command.vader
Normal file
|
@ -0,0 +1,27 @@
|
|||
Before:
|
||||
Save g:ale_buffer_info
|
||||
|
||||
let g:ale_buffer_info = {}
|
||||
|
||||
call ale#linter#PreventLoading('testft')
|
||||
call ale#linter#Define('testft', {
|
||||
\ 'name': 'testlinter',
|
||||
\ 'callback': {-> []},
|
||||
\ 'executable': has('win32') ? 'cmd' : 'true',
|
||||
\ 'command': 'sleep 9001',
|
||||
\})
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
call ale#linter#Reset()
|
||||
|
||||
Given testft (An empty file):
|
||||
Execute(ALELintStop should stop ALE from linting):
|
||||
ALELint
|
||||
|
||||
Assert ale#engine#IsCheckingBuffer(bufnr('')), 'ALE did not start checking the buffer'
|
||||
|
||||
ALELintStop
|
||||
|
||||
Assert !ale#engine#IsCheckingBuffer(bufnr('')), 'ALELintStop didn''t work'
|
|
@ -132,3 +132,19 @@ Execute(Linters where lint_file eventually evaluates to 1 shouldn't be run if we
|
|||
call ale#test#FlushJobs()
|
||||
|
||||
AssertEqual [], ale#test#GetLoclistWithoutModule()
|
||||
|
||||
Execute(Keeping computed lint_file jobs running should work):
|
||||
AssertEqual 'testlinter2', ale#linter#Get('foobar')[1].name
|
||||
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
call ale#engine#MarkLinterActive(
|
||||
\ g:ale_buffer_info[bufnr('')],
|
||||
\ ale#linter#Get('foobar')[1]
|
||||
\)
|
||||
call ale#engine#RunLinters(bufnr(''), ale#linter#Get('foobar'), 0)
|
||||
|
||||
Assert !empty(g:ale_buffer_info[bufnr('')].active_linter_list),
|
||||
\ 'The active linter list was empty'
|
||||
Assert ale#engine#IsCheckingBuffer(bufnr('')),
|
||||
\ 'The IsCheckingBuffer function returned 0'
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
Before:
|
||||
call ale#test#SetDirectory('/testplugin/test')
|
||||
|
||||
runtime ale_linters/handlebars/embertemplatelint.vim
|
||||
|
||||
After:
|
||||
call ale#test#RestoreDirectory()
|
||||
call ale#linter#Reset()
|
||||
|
||||
Execute(ember-template-lint executables runs the right command):
|
||||
call ale#test#SetFilename('ember-template-lint-test-files/app/template.hbs')
|
||||
|
||||
AssertEqual
|
||||
\ ale_linters#handlebars#embertemplatelint#GetCommand(bufnr(''), [2, 0, 0]),
|
||||
\ '%e --json --filename %s'
|
||||
|
||||
Execute(old ember-template-lint executables runs the right command):
|
||||
call ale#test#SetFilename('ember-template-lint-test-files/app/template.hbs')
|
||||
|
||||
AssertEqual
|
||||
\ ale_linters#handlebars#embertemplatelint#GetCommand(bufnr(''), [1, 5, 0]),
|
||||
\ '%e --json %t'
|
Reference in a new issue