Remove features deprecated in previous versions

This commit is contained in:
w0rp 2020-08-18 23:03:43 +01:00
parent 4df352eee5
commit 5eda1df0a9
No known key found for this signature in database
GPG Key ID: 0FC1ECAA8C81CD83
20 changed files with 125 additions and 968 deletions

View File

@ -9,6 +9,6 @@ call ale#linter#Define('ocaml', {
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': function('ale#handlers#ols#GetExecutable'), \ 'executable': function('ale#handlers#ols#GetExecutable'),
\ 'command': function('ale#handlers#ols#GetCommand'), \ 'command': function('ale#handlers#ols#GetCommand'),
\ 'language_callback': 'ale#handlers#ols#GetLanguage', \ 'language': function('ale#handlers#ols#GetLanguage'),
\ 'project_root': function('ale#handlers#ols#GetProjectRoot'), \ 'project_root': function('ale#handlers#ols#GetProjectRoot'),
\}) \})

View File

@ -9,6 +9,6 @@ call ale#linter#Define('reason', {
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': function('ale#handlers#ols#GetExecutable'), \ 'executable': function('ale#handlers#ols#GetExecutable'),
\ 'command': function('ale#handlers#ols#GetCommand'), \ 'command': function('ale#handlers#ols#GetCommand'),
\ 'language_callback': 'ale#handlers#ols#GetLanguage', \ 'language': function('ale#handlers#ols#GetLanguage'),
\ 'project_root': function('ale#handlers#ols#GetProjectRoot'), \ 'project_root': function('ale#handlers#ols#GetProjectRoot'),
\}) \})

View File

@ -130,7 +130,7 @@ endfunction
function! ale#assert#LSPLanguage(expected_language) abort function! ale#assert#LSPLanguage(expected_language) abort
let l:buffer = bufnr('') let l:buffer = bufnr('')
let l:linter = s:GetLinter() let l:linter = s:GetLinter()
let l:language = ale#util#GetFunction(l:linter.language_callback)(l:buffer) let l:language = ale#linter#GetLanguage(l:buffer, l:linter)
AssertEqual a:expected_language, l:language AssertEqual a:expected_language, l:language
endfunction endfunction

View File

@ -135,10 +135,6 @@ function! s:GoToLSPDefinition(linter, options, capability) abort
endfunction endfunction
function! ale#definition#GoTo(options) abort function! ale#definition#GoTo(options) abort
if !get(g:, 'ale_ignore_2_7_warnings') && has_key(a:options, 'deprecated_command')
execute 'echom '':' . a:options.deprecated_command . ' is deprecated. Use `let g:ale_ignore_2_7_warnings = 1` to disable this message.'''
endif
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp) if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'definition') call s:GoToLSPDefinition(l:linter, a:options, 'definition')
@ -147,10 +143,6 @@ function! ale#definition#GoTo(options) abort
endfunction endfunction
function! ale#definition#GoToType(options) abort function! ale#definition#GoToType(options) abort
if !get(g:, 'ale_ignore_2_7_warnings') && has_key(a:options, 'deprecated_command')
execute 'echom '':' . a:options.deprecated_command . ' is deprecated. Use `let g:ale_ignore_2_7_warnings = 1` to disable this message.'''
endif
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp) if !empty(l:linter.lsp)
" TODO: handle typeDefinition for tsserver if supported by the " TODO: handle typeDefinition for tsserver if supported by the

View File

@ -104,42 +104,6 @@ function! ale#engine#IsCheckingBuffer(buffer) abort
\ || !empty(get(l:info, 'active_other_sources_list', [])) \ || !empty(get(l:info, 'active_other_sources_list', []))
endfunction endfunction
" Register a temporary file to be managed with the ALE engine for
" a current job run.
function! ale#engine#ManageFile(buffer, filename) abort
if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''ale#engine#ManageFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
call ale#command#ManageFile(a:buffer, a:filename)
endfunction
" Same as the above, but manage an entire directory.
function! ale#engine#ManageDirectory(buffer, directory) abort
if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''ale#engine#ManageDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
call ale#command#ManageDirectory(a:buffer, a:directory)
endfunction
function! ale#engine#CreateFile(buffer) abort
if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''ale#engine#CreateFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
return ale#command#CreateFile(a:buffer)
endfunction
" Create a new temporary directory and manage it in one go.
function! ale#engine#CreateDirectory(buffer) abort
if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''ale#engine#CreateDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
return ale#command#CreateDirectory(a:buffer)
endfunction
function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort
let l:info = get(g:ale_buffer_info, a:buffer, {}) let l:info = get(g:ale_buffer_info, a:buffer, {})
@ -192,7 +156,6 @@ function! s:HandleExit(job_info, buffer, output, data) abort
let l:linter = a:job_info.linter let l:linter = a:job_info.linter
let l:executable = a:job_info.executable let l:executable = a:job_info.executable
let l:next_chain_index = a:job_info.next_chain_index
" Remove this job from the list. " Remove this job from the list.
call ale#engine#MarkLinterInactive(l:buffer_info, l:linter.name) call ale#engine#MarkLinterInactive(l:buffer_info, l:linter.name)
@ -207,20 +170,6 @@ function! s:HandleExit(job_info, buffer, output, data) abort
call remove(a:output, -1) call remove(a:output, -1)
endif endif
if l:next_chain_index < len(get(l:linter, 'command_chain', []))
let [l:command, l:options] = ale#engine#ProcessChain(
\ a:buffer,
\ l:executable,
\ l:linter,
\ l:next_chain_index,
\ a:output,
\)
call s:RunJob(l:command, l:options)
return
endif
try try
let l:loclist = ale#util#GetFunction(l:linter.callback)(a:buffer, a:output) let l:loclist = ale#util#GetFunction(l:linter.callback)(a:buffer, a:output)
" Handle the function being unknown, or being deleted. " Handle the function being unknown, or being deleted.
@ -454,20 +403,18 @@ function! s:RunJob(command, options) abort
let l:buffer = a:options.buffer let l:buffer = a:options.buffer
let l:linter = a:options.linter let l:linter = a:options.linter
let l:output_stream = a:options.output_stream let l:output_stream = a:options.output_stream
let l:next_chain_index = a:options.next_chain_index
let l:read_buffer = a:options.read_buffer let l:read_buffer = a:options.read_buffer
let l:info = g:ale_buffer_info[l:buffer] let l:info = g:ale_buffer_info[l:buffer]
let l:Callback = function('s:HandleExit', [{ let l:Callback = function('s:HandleExit', [{
\ 'linter': l:linter, \ 'linter': l:linter,
\ 'executable': l:executable, \ 'executable': l:executable,
\ 'next_chain_index': l:next_chain_index,
\}]) \}])
let l:result = ale#command#Run(l:buffer, l:command, l:Callback, { let l:result = ale#command#Run(l:buffer, l:command, l:Callback, {
\ 'output_stream': l:output_stream, \ 'output_stream': l:output_stream,
\ 'executable': l:executable, \ 'executable': l:executable,
\ 'read_buffer': l:read_buffer, \ 'read_buffer': l:read_buffer,
\ 'log_output': l:next_chain_index >= len(get(l:linter, 'command_chain', [])), \ 'log_output': 1,
\}) \})
" Only proceed if the job is being run. " Only proceed if the job is being run.
@ -482,68 +429,6 @@ function! s:RunJob(command, options) abort
return 1 return 1
endfunction endfunction
" Determine which commands to run for a link in a command chain, or
" just a regular command.
function! ale#engine#ProcessChain(buffer, executable, linter, chain_index, input) abort
let l:output_stream = get(a:linter, 'output_stream', 'stdout')
let l:read_buffer = a:linter.read_buffer
let l:chain_index = a:chain_index
let l:input = a:input
while l:chain_index < len(a:linter.command_chain)
" Run a chain of commands, one asynchronous command after the other,
" so that many programs can be run in a sequence.
let l:chain_item = a:linter.command_chain[l:chain_index]
if l:chain_index == 0
" The first callback in the chain takes only a buffer number.
let l:command = ale#util#GetFunction(l:chain_item.callback)(
\ a:buffer
\)
else
" The second callback in the chain takes some input too.
let l:command = ale#util#GetFunction(l:chain_item.callback)(
\ a:buffer,
\ l:input
\)
endif
" If we have a command to run, execute that.
if !empty(l:command)
" The chain item can override the output_stream option.
if has_key(l:chain_item, 'output_stream')
let l:output_stream = l:chain_item.output_stream
endif
" The chain item can override the read_buffer option.
if has_key(l:chain_item, 'read_buffer')
let l:read_buffer = l:chain_item.read_buffer
elseif l:chain_index != len(a:linter.command_chain) - 1
" Don't read the buffer for commands besides the last one
" in the chain by default.
let l:read_buffer = 0
endif
break
endif
" Command chain items can return an empty string to indicate that
" a command should be skipped, so we should try the next item
" with no input.
let l:input = []
let l:chain_index += 1
endwhile
return [l:command, {
\ 'executable': a:executable,
\ 'buffer': a:buffer,
\ 'linter': a:linter,
\ 'output_stream': l:output_stream,
\ 'next_chain_index': l:chain_index + 1,
\ 'read_buffer': l:read_buffer,
\}]
endfunction
function! s:StopCurrentJobs(buffer, clear_lint_file_jobs) abort function! s:StopCurrentJobs(buffer, clear_lint_file_jobs) abort
let l:info = get(g:ale_buffer_info, a:buffer, {}) let l:info = get(g:ale_buffer_info, a:buffer, {})
call ale#command#StopJobs(a:buffer, 'linter') call ale#command#StopJobs(a:buffer, 'linter')
@ -622,25 +507,12 @@ function! s:RunIfExecutable(buffer, linter, executable) abort
let l:job_type = a:linter.lint_file ? 'file_linter' : 'linter' let l:job_type = a:linter.lint_file ? 'file_linter' : 'linter'
call setbufvar(a:buffer, 'ale_job_type', l:job_type) call setbufvar(a:buffer, 'ale_job_type', l:job_type)
if has_key(a:linter, 'command_chain')
let [l:command, l:options] = ale#engine#ProcessChain(
\ a:buffer,
\ a:executable,
\ a:linter,
\ 0,
\ []
\)
return s:RunJob(l:command, l:options)
endif
let l:command = ale#linter#GetCommand(a:buffer, a:linter) let l:command = ale#linter#GetCommand(a:buffer, a:linter)
let l:options = { let l:options = {
\ 'executable': a:executable, \ 'executable': a:executable,
\ 'buffer': a:buffer, \ 'buffer': a:buffer,
\ 'linter': a:linter, \ 'linter': a:linter,
\ 'output_stream': get(a:linter, 'output_stream', 'stdout'), \ 'output_stream': get(a:linter, 'output_stream', 'stdout'),
\ 'next_chain_index': 1,
\ 'read_buffer': a:linter.read_buffer, \ 'read_buffer': a:linter.read_buffer,
\} \}

View File

@ -90,7 +90,6 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort
let l:output = a:job_output let l:output = a:job_output
endif endif
let l:ChainCallback = get(a:job_info, 'chain_with', v:null)
let l:ProcessWith = get(a:job_info, 'process_with', v:null) let l:ProcessWith = get(a:job_info, 'process_with', v:null)
" Post-process the output with a function if we have one. " Post-process the output with a function if we have one.
@ -102,27 +101,18 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort
" otherwise skip this job and use the input from before. " otherwise skip this job and use the input from before.
" "
" We'll use the input from before for chained commands. " We'll use the input from before for chained commands.
if l:ChainCallback is v:null && !empty(split(join(l:output))) if !empty(split(join(l:output)))
let l:input = l:output let l:input = l:output
else else
let l:input = a:job_info.input let l:input = a:job_info.input
endif endif
if l:ChainCallback isnot v:null && !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''chain_with is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
let l:next_index = l:ChainCallback is v:null
\ ? a:job_info.callback_index + 1
\ : a:job_info.callback_index
call s:RunFixer({ call s:RunFixer({
\ 'buffer': a:buffer, \ 'buffer': a:buffer,
\ 'input': l:input, \ 'input': l:input,
\ 'output': l:output, \ 'output': l:output,
\ 'callback_list': a:job_info.callback_list, \ 'callback_list': a:job_info.callback_list,
\ 'callback_index': l:next_index, \ 'callback_index': a:job_info.callback_index + 1,
\ 'chain_callback': l:ChainCallback,
\}) \})
endfunction endfunction
@ -152,17 +142,14 @@ function! s:RunJob(result, options) abort
endif endif
let l:command = get(a:result, 'command', '') let l:command = get(a:result, 'command', '')
let l:ChainWith = get(a:result, 'chain_with', v:null)
if empty(l:command) if empty(l:command)
" If the command is empty, skip to the next item, or call the " If the command is empty, skip to the next item.
" chain_with function.
call s:RunFixer({ call s:RunFixer({
\ 'buffer': l:buffer, \ 'buffer': l:buffer,
\ 'input': l:input, \ 'input': l:input,
\ 'callback_index': a:options.callback_index + (l:ChainWith is v:null), \ 'callback_index': a:options.callback_index,
\ 'callback_list': a:options.callback_list, \ 'callback_list': a:options.callback_list,
\ 'chain_callback': l:ChainWith,
\ 'output': [], \ 'output': [],
\}) \})
@ -170,8 +157,7 @@ function! s:RunJob(result, options) abort
endif endif
let l:read_temporary_file = get(a:result, 'read_temporary_file', 0) let l:read_temporary_file = get(a:result, 'read_temporary_file', 0)
" Default to piping the buffer for the last fixer in the chain. let l:read_buffer = get(a:result, 'read_buffer', 1)
let l:read_buffer = get(a:result, 'read_buffer', l:ChainWith is v:null)
let l:output_stream = get(a:result, 'output_stream', 'stdout') let l:output_stream = get(a:result, 'output_stream', 'stdout')
if l:read_temporary_file if l:read_temporary_file
@ -180,7 +166,6 @@ function! s:RunJob(result, options) abort
let l:Callback = function('s:HandleExit', [{ let l:Callback = function('s:HandleExit', [{
\ 'input': l:input, \ 'input': l:input,
\ 'chain_with': l:ChainWith,
\ 'callback_index': a:options.callback_index, \ 'callback_index': a:options.callback_index,
\ 'callback_list': a:options.callback_list, \ 'callback_list': a:options.callback_list,
\ 'process_with': get(a:result, 'process_with', v:null), \ 'process_with': get(a:result, 'process_with', v:null),

View File

@ -77,10 +77,6 @@ function! s:IsBoolean(value) abort
return type(a:value) is v:t_number && (a:value == 0 || a:value == 1) return type(a:value) is v:t_number && (a:value == 0 || a:value == 1)
endfunction endfunction
function! s:LanguageGetter(buffer) dict abort
return l:self.language
endfunction
function! ale#linter#PreProcess(filetype, linter) abort function! ale#linter#PreProcess(filetype, linter) abort
if type(a:linter) isnot v:t_dict if type(a:linter) isnot v:t_dict
throw 'The linter object must be a Dictionary' throw 'The linter object must be a Dictionary'
@ -114,14 +110,7 @@ function! ale#linter#PreProcess(filetype, linter) abort
if !l:needs_executable if !l:needs_executable
if has_key(a:linter, 'executable') if has_key(a:linter, 'executable')
\|| has_key(a:linter, 'executable_callback') throw '`executable` cannot be used when lsp == ''socket'''
throw '`executable` and `executable_callback` cannot be used when lsp == ''socket'''
endif
elseif has_key(a:linter, 'executable_callback')
let l:obj.executable_callback = a:linter.executable_callback
if !s:IsCallback(l:obj.executable_callback)
throw '`executable_callback` must be a callback if defined'
endif endif
elseif has_key(a:linter, 'executable') elseif has_key(a:linter, 'executable')
let l:obj.executable = a:linter.executable let l:obj.executable = a:linter.executable
@ -131,54 +120,12 @@ function! ale#linter#PreProcess(filetype, linter) abort
throw '`executable` must be a String or Function if defined' throw '`executable` must be a String or Function if defined'
endif endif
else else
throw 'Either `executable` or `executable_callback` must be defined' throw '`executable` must be defined'
endif endif
if !l:needs_command if !l:needs_command
if has_key(a:linter, 'command') if has_key(a:linter, 'command')
\|| has_key(a:linter, 'command_callback') throw '`command` cannot be used when lsp == ''socket'''
\|| has_key(a:linter, 'command_chain')
throw '`command` and `command_callback` and `command_chain` cannot be used when lsp == ''socket'''
endif
elseif has_key(a:linter, 'command_chain')
let l:obj.command_chain = a:linter.command_chain
if type(l:obj.command_chain) isnot v:t_list
throw '`command_chain` must be a List'
endif
if empty(l:obj.command_chain)
throw '`command_chain` must contain at least one item'
endif
let l:link_index = 0
for l:link in l:obj.command_chain
let l:err_prefix = 'The `command_chain` item ' . l:link_index . ' '
if !s:IsCallback(get(l:link, 'callback'))
throw l:err_prefix . 'must define a `callback` function'
endif
if has_key(l:link, 'output_stream')
if type(l:link.output_stream) isnot v:t_string
\|| index(['stdout', 'stderr', 'both'], l:link.output_stream) < 0
throw l:err_prefix . '`output_stream` flag must be '
\ . "'stdout', 'stderr', or 'both'"
endif
endif
if has_key(l:link, 'read_buffer') && !s:IsBoolean(l:link.read_buffer)
throw l:err_prefix . 'value for `read_buffer` must be `0` or `1`'
endif
let l:link_index += 1
endfor
elseif has_key(a:linter, 'command_callback')
let l:obj.command_callback = a:linter.command_callback
if !s:IsCallback(l:obj.command_callback)
throw '`command_callback` must be a callback if defined'
endif endif
elseif has_key(a:linter, 'command') elseif has_key(a:linter, 'command')
let l:obj.command = a:linter.command let l:obj.command = a:linter.command
@ -188,22 +135,12 @@ function! ale#linter#PreProcess(filetype, linter) abort
throw '`command` must be a String or Function if defined' throw '`command` must be a String or Function if defined'
endif endif
else else
throw 'Either `command`, `executable_callback`, `command_chain` ' throw '`command` must be defined'
\ . 'must be defined'
endif
if (
\ has_key(a:linter, 'command')
\ + has_key(a:linter, 'command_chain')
\ + has_key(a:linter, 'command_callback')
\) > 1
throw 'Only one of `command`, `command_callback`, or `command_chain` '
\ . 'should be set'
endif endif
if !l:needs_address if !l:needs_address
if has_key(a:linter, 'address') || has_key(a:linter, 'address_callback') if has_key(a:linter, 'address')
throw '`address` or `address_callback` cannot be used when lsp != ''socket''' throw '`address` cannot be used when lsp != ''socket'''
endif endif
elseif has_key(a:linter, 'address') elseif has_key(a:linter, 'address')
if type(a:linter.address) isnot v:t_string if type(a:linter.address) isnot v:t_string
@ -212,41 +149,17 @@ function! ale#linter#PreProcess(filetype, linter) abort
endif endif
let l:obj.address = a:linter.address let l:obj.address = a:linter.address
elseif has_key(a:linter, 'address_callback')
let l:obj.address_callback = a:linter.address_callback
if !s:IsCallback(l:obj.address_callback)
throw '`address_callback` must be a callback if defined'
endif
else else
throw '`address` or `address_callback` must be defined for getting the LSP address' throw '`address` must be defined for getting the LSP address'
endif endif
if l:needs_lsp_details if l:needs_lsp_details
if has_key(a:linter, 'language_callback') " Default to using the filetype as the language.
if has_key(a:linter, 'language') let l:obj.language = get(a:linter, 'language', a:filetype)
throw 'Only one of `language` or `language_callback` '
\ . 'should be set'
endif
let l:obj.language_callback = get(a:linter, 'language_callback') if type(l:obj.language) isnot v:t_string
\&& type(l:obj.language) isnot v:t_func
if !s:IsCallback(l:obj.language_callback) throw '`language` must be a String or Funcref if defined'
throw '`language_callback` must be a callback for LSP linters'
endif
else
" Default to using the filetype as the language.
let l:Language = get(a:linter, 'language', a:filetype)
if type(l:Language) is v:t_string
" Make 'language_callback' return the 'language' value.
let l:obj.language = l:Language
let l:obj.language_callback = function('s:LanguageGetter')
elseif type(l:Language) is v:t_func
let l:obj.language_callback = l:Language
else
throw '`language` must be a String or Funcref'
endif
endif endif
if has_key(a:linter, 'project_root') if has_key(a:linter, 'project_root')
@ -254,16 +167,10 @@ function! ale#linter#PreProcess(filetype, linter) abort
if type(l:obj.project_root) isnot v:t_string if type(l:obj.project_root) isnot v:t_string
\&& type(l:obj.project_root) isnot v:t_func \&& type(l:obj.project_root) isnot v:t_func
throw '`project_root` must be a String or Function if defined' throw '`project_root` must be a String or Function'
endif
elseif has_key(a:linter, 'project_root_callback')
let l:obj.project_root_callback = a:linter.project_root_callback
if !s:IsCallback(l:obj.project_root_callback)
throw '`project_root_callback` must be a callback if defined'
endif endif
else else
throw '`project_root` or `project_root_callback` must be defined for LSP linters' throw '`project_root` must be defined for LSP linters'
endif endif
if has_key(a:linter, 'completion_filter') if has_key(a:linter, 'completion_filter')
@ -274,37 +181,16 @@ function! ale#linter#PreProcess(filetype, linter) abort
endif endif
endif endif
if has_key(a:linter, 'initialization_options_callback') if has_key(a:linter, 'initialization_options')
if has_key(a:linter, 'initialization_options')
throw 'Only one of `initialization_options` or '
\ . '`initialization_options_callback` should be set'
endif
let l:obj.initialization_options_callback = a:linter.initialization_options_callback
if !s:IsCallback(l:obj.initialization_options_callback)
throw '`initialization_options_callback` must be a callback if defined'
endif
elseif has_key(a:linter, 'initialization_options')
let l:obj.initialization_options = a:linter.initialization_options let l:obj.initialization_options = a:linter.initialization_options
if type(l:obj.initialization_options) isnot v:t_dict if type(l:obj.initialization_options) isnot v:t_dict
\&& type(l:obj.initialization_options) isnot v:t_func \&& type(l:obj.initialization_options) isnot v:t_func
throw '`initialization_options` must be a String or Function if defined' throw '`initialization_options` must be a Dictionary or Function if defined'
endif endif
endif endif
if has_key(a:linter, 'lsp_config_callback') if has_key(a:linter, 'lsp_config')
if has_key(a:linter, 'lsp_config')
throw 'Only one of `lsp_config` or `lsp_config_callback` should be set'
endif
let l:obj.lsp_config_callback = a:linter.lsp_config_callback
if !s:IsCallback(l:obj.lsp_config_callback)
throw '`lsp_config_callback` must be a callback if defined'
endif
elseif has_key(a:linter, 'lsp_config')
if type(a:linter.lsp_config) isnot v:t_dict if type(a:linter.lsp_config) isnot v:t_dict
\&& type(a:linter.lsp_config) isnot v:t_func \&& type(a:linter.lsp_config) isnot v:t_func
throw '`lsp_config` must be a Dictionary or Function if defined' throw '`lsp_config` must be a Dictionary or Function if defined'
@ -347,14 +233,6 @@ function! ale#linter#PreProcess(filetype, linter) abort
throw '`aliases` must be a List of String values' throw '`aliases` must be a List of String values'
endif endif
for l:key in filter(keys(a:linter), 'v:val[-9:] is# ''_callback'' || v:val is# ''command_chain''')
if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom l:key . '' is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
break
endfor
return l:obj return l:obj
endfunction endfunction
@ -522,9 +400,7 @@ endfunction
" Given a buffer and linter, get the executable String for the linter. " Given a buffer and linter, get the executable String for the linter.
function! ale#linter#GetExecutable(buffer, linter) abort function! ale#linter#GetExecutable(buffer, linter) abort
let l:Executable = has_key(a:linter, 'executable_callback') let l:Executable = a:linter.executable
\ ? function(a:linter.executable_callback)
\ : a:linter.executable
return type(l:Executable) is v:t_func return type(l:Executable) is v:t_func
\ ? l:Executable(a:buffer) \ ? l:Executable(a:buffer)
@ -532,24 +408,21 @@ function! ale#linter#GetExecutable(buffer, linter) abort
endfunction endfunction
" Given a buffer and linter, get the command String for the linter. " Given a buffer and linter, get the command String for the linter.
" The command_chain key is not supported.
function! ale#linter#GetCommand(buffer, linter) abort function! ale#linter#GetCommand(buffer, linter) abort
let l:Command = has_key(a:linter, 'command_callback') let l:Command = a:linter.command
\ ? function(a:linter.command_callback)
\ : a:linter.command
return type(l:Command) is v:t_func return type(l:Command) is v:t_func ? l:Command(a:buffer) : l:Command
\ ? l:Command(a:buffer)
\ : l:Command
endfunction endfunction
" Given a buffer and linter, get the address for connecting to the server. " Given a buffer and linter, get the address for connecting to the server.
function! ale#linter#GetAddress(buffer, linter) abort function! ale#linter#GetAddress(buffer, linter) abort
let l:Address = has_key(a:linter, 'address_callback') let l:Address = a:linter.address
\ ? function(a:linter.address_callback)
\ : a:linter.address
return type(l:Address) is v:t_func return type(l:Address) is v:t_func ? l:Address(a:buffer) : l:Address
\ ? l:Address(a:buffer) endfunction
\ : l:Address
function! ale#linter#GetLanguage(buffer, linter) abort
let l:Language = a:linter.language
return type(l:Language) is v:t_func ? l:Language(a:buffer) : l:Language
endfunction endfunction

View File

@ -227,7 +227,7 @@ function! ale#lsp_linter#OnInit(linter, details, Callback) abort
let l:command = a:details.command let l:command = a:details.command
let l:config = ale#lsp_linter#GetConfig(l:buffer, a:linter) let l:config = ale#lsp_linter#GetConfig(l:buffer, a:linter)
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(l:buffer) let l:language_id = ale#linter#GetLanguage(l:buffer, a:linter)
call ale#lsp#UpdateConfig(l:conn_id, l:buffer, l:config) call ale#lsp#UpdateConfig(l:conn_id, l:buffer, l:config)

View File

@ -145,8 +145,8 @@ function! ale#test#WaitForJobs(deadline) abort
" end, but before handlers are run. " end, but before handlers are run.
sleep 10ms sleep 10ms
" We must check the buffer data again to see if new jobs started " We must check the buffer data again to see if new jobs started for
" for command_chain linters. " linters with chained commands.
let l:has_new_jobs = 0 let l:has_new_jobs = 0
" Check again to see if any jobs are running. " Check again to see if any jobs are running.

View File

@ -684,7 +684,9 @@ g:ale_completion_enabled *g:ale_completion_enabled*
See |ale-completion| See |ale-completion|
g:ale_completion_tsserver_remove_warnings *g:ale_completion_tsserver_remove_warnings*
*g:ale_completion_tsserver_remove_warnings*
g:ale_completion_tsserver_remove_warnings
Type: Number Type: Number
Default: `0` Default: `0`
@ -693,6 +695,7 @@ g:ale_completion_tsserver_remove_warnings *g:ale_completion_tsserver_remove_warn
including those that are a warning. Warnings can be excluded from completed including those that are a warning. Warnings can be excluded from completed
items by setting it to `1`. items by setting it to `1`.
g:ale_completion_autoimport *g:ale_completion_autoimport* g:ale_completion_autoimport *g:ale_completion_autoimport*
Type: Number Type: Number
@ -2809,7 +2812,13 @@ ALEGoToDefinition `<options>` *ALEGoToDefinition*
command. Otherwise, Vim will refuse to leave the buffer you're jumping from command. Otherwise, Vim will refuse to leave the buffer you're jumping from
unless you have saved your edits. unless you have saved your edits.
A plug mapping `<Plug>(ale_go_to_definition)` is defined for this command. The following Plug mappings are defined for this command, which correspond
to the following commands.
`<Plug>(ale_go_to_definition)` - `:ALEGoToDefinition`
`<Plug>(ale_go_to_definition_in_tab)` - `:ALEGoToDefinition -tab`
`<Plug>(ale_go_to_definition_in_split)` - `:ALEGoToDefinition -split`
`<Plug>(ale_go_to_definition_in_vsplit)` - `:ALEGoToDefinition -vsplit`
ALEGoToTypeDefinition *ALEGoToTypeDefinition* ALEGoToTypeDefinition *ALEGoToTypeDefinition*
@ -2831,8 +2840,13 @@ ALEGoToTypeDefinition *ALEGoToTypeDefinition*
You can jump back to the position you were at before going to the definition You can jump back to the position you were at before going to the definition
of something with jump motions like CTRL-O. See |jump-motions|. of something with jump motions like CTRL-O. See |jump-motions|.
A plug mapping `<Plug>(ale_go_to_type_definition)` is defined for this The following Plug mappings are defined for this command, which correspond
command. to the following commands.
`<Plug>(ale_go_to_type_definition)` - `:ALEGoToTypeDefinition`
`<Plug>(ale_go_to_type_definition_in_tab)` - `:ALEGoToTypeDefinition -tab`
`<Plug>(ale_go_to_type_definition_in_split)` - `:ALEGoToTypeDefinition -split`
`<Plug>(ale_go_to_type_definition_in_vsplit)` - `:ALEGoToTypeDefinition -vsplit`
ALEHover *ALEHover* ALEHover *ALEHover*

View File

@ -207,19 +207,9 @@ command! -bar ALEFixSuggest :call ale#fix#registry#Suggest(&filetype)
" Go to definition for tsserver and LSP " Go to definition for tsserver and LSP
command! -bar -nargs=* ALEGoToDefinition :call ale#definition#GoToCommandHandler('', <f-args>) command! -bar -nargs=* ALEGoToDefinition :call ale#definition#GoToCommandHandler('', <f-args>)
" Deprecated commands we have to keep for now.
command! -bar ALEGoToDefinitionInTab :call ale#definition#GoTo({'open_in': 'tab', 'deprecated_command': 'ALEGoToDefinitionInTab'})
command! -bar ALEGoToDefinitionInSplit :call ale#definition#GoTo({'open_in': 'split', 'deprecated_command': 'ALEGoToDefinitionInSplit'})
command! -bar ALEGoToDefinitionInVSplit :call ale#definition#GoTo({'open_in': 'vsplit', 'deprecated_command': 'ALEGoToDefinitionInVSplit'})
" Go to type definition for tsserver and LSP " Go to type definition for tsserver and LSP
command! -bar -nargs=* ALEGoToTypeDefinition :call ale#definition#GoToCommandHandler('type', <f-args>) command! -bar -nargs=* ALEGoToTypeDefinition :call ale#definition#GoToCommandHandler('type', <f-args>)
" Deprecated commands we have to keep for now.
command! -bar ALEGoToTypeDefinitionInTab :call ale#definition#GoToType({'open_in': 'tab', 'deprecated_command': 'ALEGoToTypeDefinitionInTab'})
command! -bar ALEGoToTypeDefinitionInSplit :call ale#definition#GoToType({'open_in': 'split', 'deprecated_command': 'ALEGoToTypeDefinitionInSplit'})
command! -bar ALEGoToTypeDefinitionInVSplit :call ale#definition#GoToType({'open_in': 'vsplit', 'deprecated_command': 'ALEGoToTypeDefinitionInVSplit'})
" Repeat a previous selection in the preview window " Repeat a previous selection in the preview window
command! -bar ALERepeatSelection :call ale#preview#RepeatSelection() command! -bar ALERepeatSelection :call ale#preview#RepeatSelection()
@ -270,7 +260,13 @@ nnoremap <silent> <Plug>(ale_lint) :ALELint<Return>
nnoremap <silent> <Plug>(ale_detail) :ALEDetail<Return> nnoremap <silent> <Plug>(ale_detail) :ALEDetail<Return>
nnoremap <silent> <Plug>(ale_fix) :ALEFix<Return> nnoremap <silent> <Plug>(ale_fix) :ALEFix<Return>
nnoremap <silent> <Plug>(ale_go_to_definition) :ALEGoToDefinition<Return> nnoremap <silent> <Plug>(ale_go_to_definition) :ALEGoToDefinition<Return>
nnoremap <silent> <Plug>(ale_go_to_definition_in_tab) :ALEGoToDefinition -tab<Return>
nnoremap <silent> <Plug>(ale_go_to_definition_in_split) :ALEGoToDefinition -split<Return>
nnoremap <silent> <Plug>(ale_go_to_definition_in_vsplit) :ALEGoToDefinition -vsplit<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition) :ALEGoToTypeDefinition<Return> nnoremap <silent> <Plug>(ale_go_to_type_definition) :ALEGoToTypeDefinition<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinition -tab<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition_in_split) :ALEGoToTypeDefinition -split<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionIn -vsplit<Return>
nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return> nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return>
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return> nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
nnoremap <silent> <Plug>(ale_documentation) :ALEDocumentation<Return> nnoremap <silent> <Plug>(ale_documentation) :ALEDocumentation<Return>
@ -278,14 +274,6 @@ inoremap <silent> <Plug>(ale_complete) <C-\><C-O>:ALEComplete<Return>
nnoremap <silent> <Plug>(ale_rename) :ALERename<Return> nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
nnoremap <silent> <Plug>(ale_repeat_selection) :ALERepeatSelection<Return> nnoremap <silent> <Plug>(ale_repeat_selection) :ALERepeatSelection<Return>
" Deprecated <Plug> mappings
nnoremap <silent> <Plug>(ale_go_to_definition_in_tab) :ALEGoToDefinitionInTab<Return>
nnoremap <silent> <Plug>(ale_go_to_definition_in_split) :ALEGoToDefinitionInSplit<Return>
nnoremap <silent> <Plug>(ale_go_to_definition_in_vsplit) :ALEGoToDefinitionInVSplit<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinitionInTab<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition_in_split) :ALEGoToTypeDefinitionInSplit<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionInVSplit<Return>
" Set up autocmd groups now. " Set up autocmd groups now.
call ale#events#Init() call ale#events#Init()

View File

@ -84,56 +84,6 @@ Before:
return [{'lnum': 1, 'col': 1, 'text': 'xxx'}] return [{'lnum': 1, 'col': 1, 'text': 'xxx'}]
endfunction endfunction
function! FirstChainCallback(buffer)
return {'command': 'echo echoline', 'chain_with': 'SecondChainCallback'}
endfunction
function! FirstChainCallbackSkipped(buffer)
let l:ChainWith = 'SecondChainCallback'
" Test with lambdas where support is available.
if has('lambda')
let l:ChainWith = {buffer, output -> SecondChainCallback(buffer, output)}
endif
return {'command': '', 'chain_with': l:ChainWith}
endfunction
function! FirstChainCallbackSecondSkipped(buffer)
return {'command': 'echo skipit', 'chain_with': 'SecondChainCallback'}
endfunction
function! SecondChainCallback(buffer, output)
let l:previous_line = empty(a:output)
\ ? 'emptydefault'
\ : join(split(a:output[0]))
if l:previous_line is# 'skipit'
return {'command': '', 'chain_with': 'ThirdChainCallback'}
endif
return {
\ 'command': 'echo ' . l:previous_line,
\ 'chain_with': 'ThirdChainCallback',
\}
endfunction
function! ThirdChainCallback(buffer, output, input)
let l:previous_line = empty(a:output)
\ ? 'thirddefault'
\ : join(split(a:output[0]))
return a:input + [l:previous_line]
endfunction
function! ChainWhereLastIsSkipped(buffer)
return {'command': 'echo echoline', 'chain_with': 'ChainEndSkipped'}
endfunction
function! ChainEndSkipped(buffer, output)
return {'command': ''}
endfunction
" echo will output a single blank line, and we should ingore it. " echo will output a single blank line, and we should ingore it.
function! IgnoredEmptyOutput(buffer, output) function! IgnoredEmptyOutput(buffer, output)
return {'command': has('win32') ? 'echo(' : 'echo'} return {'command': has('win32') ? 'echo(' : 'echo'}
@ -208,13 +158,6 @@ After:
delfunction RemoveLastLine delfunction RemoveLastLine
delfunction RemoveLastLineOneArg delfunction RemoveLastLineOneArg
delfunction TestCallback delfunction TestCallback
delfunction FirstChainCallback
delfunction FirstChainCallbackSkipped
delfunction FirstChainCallbackSecondSkipped
delfunction SecondChainCallback
delfunction ThirdChainCallback
delfunction ChainWhereLastIsSkipped
delfunction ChainEndSkipped
delfunction SetUpLinters delfunction SetUpLinters
delfunction GetLastMessage delfunction GetLastMessage
delfunction IgnoredEmptyOutput delfunction IgnoredEmptyOutput
@ -816,57 +759,6 @@ Execute(ALE should tolerate valid fixers with minuses in the name):
ALEFix ALEFix
call ale#test#FlushJobs() call ale#test#FlushJobs()
Execute(Test fixing with chained callbacks):
let g:ale_fixers.testft = ['FirstChainCallback']
ALEFix
call ale#test#FlushJobs()
" The buffer shouldn't be piped in for earlier commands in the chain.
AssertEqual
\ [
\ string(ale#job#PrepareCommand(bufnr(''), 'echo echoline')),
\ string(ale#job#PrepareCommand(bufnr(''), 'echo echoline')),
\ ],
\ map(ale#history#Get(bufnr(''))[-2:-1], 'string(v:val.command)')
Expect(The echoed line should be added):
a
b
c
echoline
Execute(Test fixing with chained callback where the first command is skipped):
let g:ale_fixers.testft = ['FirstChainCallbackSkipped']
ALEFix
call ale#test#FlushJobs()
Expect(The default line should be added):
a
b
c
emptydefault
Execute(Test fixing with chained callback where the second command is skipped):
let g:ale_fixers.testft = ['FirstChainCallbackSecondSkipped']
ALEFix
call ale#test#FlushJobs()
Expect(The default line should be added):
a
b
c
thirddefault
Execute(Test fixing with chained callback where the final callback is skipped):
let g:ale_fixers.testft = ['ChainWhereLastIsSkipped']
ALEFix
call ale#test#FlushJobs()
Expect(The lines should be the same):
a
b
c
Execute(Empty output should be ignored): Execute(Empty output should be ignored):
let g:ale_fixers.testft = ['IgnoredEmptyOutput'] let g:ale_fixers.testft = ['IgnoredEmptyOutput']
ALEFix ALEFix

View File

@ -33,8 +33,8 @@ Before:
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'command': 'cat - > /dev/null', \ 'command': 'cat - > /dev/null',
\ 'executable': has('win32') ? 'cmd' : 'echo', \ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'language_callback': 'LanguageCallback', \ 'language': function('LanguageCallback'),
\ 'project_root_callback': 'ProjectRootCallback', \ 'project_root': function('ProjectRootCallback'),
\ }) \ })
let g:ale_linters = {'foobar': ['dummy_linter']} let g:ale_linters = {'foobar': ['dummy_linter']}

View File

@ -24,8 +24,8 @@ Execute(Command formatting should be applied correctly for LSP linters):
\ bufnr(''), \ bufnr(''),
\ { \ {
\ 'name': 'linter', \ 'name': 'linter',
\ 'language_callback': {-> 'x'}, \ 'language': {-> 'x'},
\ 'project_root_callback': {-> '/foo/bar'}, \ 'project_root': {-> '/foo/bar'},
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': has('win32') ? 'cmd': 'true', \ 'executable': has('win32') ? 'cmd': 'true',
\ 'command': '%e --foo', \ 'command': '%e --foo',

View File

@ -25,7 +25,6 @@ Before:
\ 'name': g:linter_name, \ 'name': g:linter_name,
\ 'project_root': {b -> g:project_root}, \ 'project_root': {b -> g:project_root},
\ 'aliases': [], \ 'aliases': [],
\ 'language_callback': {b -> 'cpp'},
\ 'read_buffer': 1, \ 'read_buffer': 1,
\ 'command': '%e' \ 'command': '%e'
\ }] \ }]

View File

@ -1,73 +0,0 @@
Before:
Save &shell, g:ale_run_synchronously
let g:ale_run_synchronously = 1
unlet! g:ale_run_synchronously_callbacks
if !has('win32')
set shell=/bin/sh
endif
let g:linter_output = []
let g:first_echo_called = 0
let g:second_echo_called = 0
let g:final_callback_called = 0
function! CollectResults(buffer, output)
let g:final_callback_called = 1
let g:linter_output = map(copy(a:output), 'join(split(v:val))')
return []
endfunction
function! RunFirstEcho(buffer)
let g:first_echo_called = 1
return 'echo foo'
endfunction
function! RunSecondEcho(buffer, output)
let g:second_echo_called = 1
return 'echo bar'
endfunction
call ale#linter#Define('foobar', {
\ 'name': 'testlinter',
\ 'callback': 'CollectResults',
\ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'command_chain': [
\ {
\ 'callback': 'RunFirstEcho',
\ 'output_stream': 'stdout',
\ 'read_buffer': 0,
\ },
\ {
\ 'callback': 'RunSecondEcho',
\ 'output_stream': 'stdout',
\ 'read_buffer': 0,
\ },
\ ],
\})
After:
Restore
unlet! g:ale_run_synchronously_callbacks
unlet! g:first_echo_called
unlet! g:second_echo_called
unlet! g:final_callback_called
unlet! g:linter_output
let g:ale_buffer_info = {}
call ale#linter#Reset()
delfunction CollectResults
delfunction RunFirstEcho
delfunction RunSecondEcho
Given foobar (Some imaginary filetype):
anything
Execute(Check the results of running the chain):
AssertEqual 'foobar', &filetype
call ale#Queue(0)
call ale#test#FlushJobs()
Assert g:first_echo_called, 'The first chain item was not called'
Assert g:second_echo_called, 'The second chain item was not called'
Assert g:final_callback_called, 'The final callback was not called'
AssertEqual ['bar'], g:linter_output

View File

@ -1,108 +0,0 @@
Before:
function! CollectResults(buffer, output)
return []
endfunction
function! FirstChainFunction(buffer)
return 'first'
endfunction
function! SecondChainFunction(buffer, output)
" We'll skip this command
return ''
endfunction
function! ThirdChainFunction(buffer, output)
return 'third'
endfunction
function! FourthChainFunction(buffer, output)
return 'fourth'
endfunction
let g:linter = {
\ 'name': 'testlinter',
\ 'callback': 'CollectResults',
\ 'executable': 'echo',
\ 'command_chain': [
\ {'callback': 'FirstChainFunction'},
\ {'callback': 'SecondChainFunction'},
\ {'callback': 'ThirdChainFunction'},
\ {'callback': 'FourthChainFunction'},
\ ],
\ 'read_buffer': 1,
\}
function! ProcessIndex(chain_index)
let [l:command, l:options] = ale#engine#ProcessChain(347, '', g:linter, a:chain_index, [])
let l:options.command = l:command
return l:options
endfunction
After:
delfunction CollectResults
delfunction FirstChainFunction
delfunction SecondChainFunction
delfunction ThirdChainFunction
delfunction ProcessIndex
unlet! g:linter
unlet! g:result
Execute(Engine invocation should return the command for the first item correctly):
let g:result = ProcessIndex(0)
AssertEqual 'first', g:result.command
AssertEqual 1, g:result.next_chain_index
Execute(Engine invocation should return the command for the second item correctly):
let g:result = ProcessIndex(1)
AssertEqual 'third', g:result.command
AssertEqual 3, g:result.next_chain_index
Execute(Engine invocation should return the command for the fourth item correctly):
let g:result = ProcessIndex(3)
AssertEqual 'fourth', g:result.command
AssertEqual 4, g:result.next_chain_index
Execute(Engine invocation should allow read_buffer to be enabled for a command in the middle of a chain):
let g:linter.command_chain[2].read_buffer = 1
let g:result = ProcessIndex(2)
AssertEqual g:result.command, 'third'
AssertEqual g:result.read_buffer, 1
Execute(Engine invocation should allow read_buffer to be disabled for the end of a chain):
let g:linter.command_chain[3].read_buffer = 0
let g:result = ProcessIndex(3)
AssertEqual g:result.command, 'fourth'
AssertEqual g:result.read_buffer, 0
Execute(Engine invocation should not use read_buffer from earlier items in a chain):
let g:linter.command_chain[1].read_buffer = 1
let g:result = ProcessIndex(1)
AssertEqual g:result.command, 'third'
AssertEqual g:result.read_buffer, 0
Execute(Engine invocation should allow the output_stream setting to be changed in the middle of a chain):
let g:linter.command_chain[2].output_stream = 'both'
let g:result = ProcessIndex(2)
AssertEqual g:result.command, 'third'
AssertEqual g:result.output_stream, 'both'
Execute(Engine invocation should not use output_stream from earlier items in a chain):
let g:linter.command_chain[1].output_stream = 'both'
let g:result = ProcessIndex(1)
AssertEqual g:result.command, 'third'
AssertEqual g:result.output_stream, 'stdout'

View File

@ -514,7 +514,7 @@ Execute(LSP tab type definition requests should be sent):
let b:ale_linters = ['pyls'] let b:ale_linters = ['pyls']
call setpos('.', [bufnr(''), 1, 5, 0]) call setpos('.', [bufnr(''), 1, 5, 0])
ALEGoToTypeDefinitionInTab ALEGoToTypeDefinition -tab
" We shouldn't register the callback yet. " We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback) AssertEqual '''''', string(g:Callback)

View File

@ -39,13 +39,13 @@ Execute (PreProcess should throw when then callback is not a function):
\}) \})
AssertEqual '`callback` must be defined with a callback to accept output', g:vader_exception AssertEqual '`callback` must be defined with a callback to accept output', g:vader_exception
Execute (PreProcess should throw when there is no executable or executable_callback): Execute (PreProcess should throw when there is no executable):
AssertThrows call ale#linter#PreProcess('testft', { AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo', \ 'name': 'foo',
\ 'callback': 'SomeFunction', \ 'callback': 'SomeFunction',
\ 'command': 'echo', \ 'command': 'echo',
\}) \})
AssertEqual 'Either `executable` or `executable_callback` must be defined', g:vader_exception AssertEqual '`executable` must be defined', g:vader_exception
Execute (PreProcess should throw when executable is not a string): Execute (PreProcess should throw when executable is not a string):
AssertThrows call ale#linter#PreProcess('testft', { AssertThrows call ale#linter#PreProcess('testft', {
@ -56,15 +56,6 @@ Execute (PreProcess should throw when executable is not a string):
\}) \})
AssertEqual '`executable` must be a String or Function if defined', g:vader_exception AssertEqual '`executable` must be a String or Function if defined', g:vader_exception
Execute (PreProcess should throw when executable_callback is not a callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'callback': 'SomeFunction',
\ 'executable_callback': 123,
\ 'command': 'echo',
\})
AssertEqual '`executable_callback` must be a callback if defined', g:vader_exception
Execute (PreProcess should allow executable to be a callback): Execute (PreProcess should allow executable to be a callback):
call ale#linter#PreProcess('testft', { call ale#linter#PreProcess('testft', {
\ 'name': 'foo', \ 'name': 'foo',
@ -79,7 +70,7 @@ Execute (PreProcess should throw when there is no command):
\ 'callback': 'SomeFunction', \ 'callback': 'SomeFunction',
\ 'executable': 'echo', \ 'executable': 'echo',
\}) \})
AssertEqual 'Either `command`, `executable_callback`, `command_chain` must be defined', g:vader_exception AssertEqual '`command` must be defined', g:vader_exception
Execute (PreProcess should throw when command is not a string): Execute (PreProcess should throw when command is not a string):
AssertThrows call ale#linter#PreProcess('testft', { AssertThrows call ale#linter#PreProcess('testft', {
@ -98,15 +89,6 @@ Execute (PreProcess should allow command to be a callback):
\ 'command': function('type'), \ 'command': function('type'),
\}) \})
Execute (PreProcess should throw when command_callback is not a callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'callback': 'SomeFunction',
\ 'executable': 'echo',
\ 'command_callback': 123,
\})
AssertEqual '`command_callback` must be a callback if defined', g:vader_exception
Execute (PreProcess should when the output stream isn't a valid string): Execute (PreProcess should when the output stream isn't a valid string):
AssertThrows call ale#linter#PreProcess('testft', { AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo', \ 'name': 'foo',
@ -152,117 +134,12 @@ Execute (PreProcess should accept a 'both' output_stream):
\ 'output_stream': 'both', \ 'output_stream': 'both',
\}) \})
Execute(PreProcess should complain if the command_chain is not a List):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`command_chain` must be a List', g:vader_exception
Execute(PreProcess should complain if the command_chain is empty):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`command_chain` must contain at least one item', g:vader_exception
Execute(PreProcess should complain if the command_chain has no callback):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 0 must define a `callback` function', g:vader_exception
Execute(PreProcess should complain if the command_chain callback is not a function):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 2}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 0 must define a `callback` function', g:vader_exception
Execute(PreProcess should accept a chain with one callback):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo'}],
\}
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should complain about invalid output_stream values in the chain):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo', 'output_stream': ''}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual "The `command_chain` item 0 `output_stream` flag must be 'stdout', 'stderr', or 'both'", g:vader_exception
Execute(PreProcess should complain about valid output_stream values in the chain):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo', 'output_stream': 'stdout'}],
\}
call ale#linter#PreProcess('testft', g:linter)
let g:linter.command_chain[0].output_stream = 'stderr'
call ale#linter#PreProcess('testft', g:linter)
let g:linter.command_chain[0].output_stream = 'both'
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should complain about invalid chain items at higher indices):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo'}, {'callback': 123}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 1 must define a `callback` function', g:vader_exception
Execute(PreProcess should complain when conflicting command options are used):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command': 'foo',
\ 'command_chain': [{'callback': 'foo'}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception
unlet g:linter.command
let g:linter.command_callback = 'foo'
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception
let g:linter.command = 'foo'
unlet g:linter.command_chain
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception
Execute(PreProcess should process the read_buffer option correctly): Execute(PreProcess should process the read_buffer option correctly):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'callback': 'x', \ 'callback': 'x',
\ 'executable': 'x', \ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo'}, {'callback': 'bar'}], \ 'command': 'x',
\ 'read_buffer': '0', \ 'read_buffer': '0',
\} \}
@ -277,25 +154,6 @@ Execute(PreProcess should process the read_buffer option correctly):
call ale#linter#PreProcess('testft', g:linter) call ale#linter#PreProcess('testft', g:linter)
unlet g:linter.read_buffer
let g:linter.command_chain[0].read_buffer = '0'
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 0 value for `read_buffer` must be `0` or `1`', g:vader_exception
let g:linter.command_chain[0].read_buffer = 0
call ale#linter#PreProcess('testft', g:linter)
let g:linter.command_chain[1].read_buffer = '0'
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 1 value for `read_buffer` must be `0` or `1`', g:vader_exception
let g:linter.command_chain[1].read_buffer = 1
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should set a default value for read_buffer): Execute(PreProcess should set a default value for read_buffer):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
@ -394,151 +252,96 @@ Execute(PreProcess should accept tsserver LSP configuration):
\ 'executable': 'x', \ 'executable': 'x',
\ 'command': 'x', \ 'command': 'x',
\ 'lsp': 'tsserver', \ 'lsp': 'tsserver',
\ 'language_callback': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\} \}
AssertEqual 'tsserver', ale#linter#PreProcess('testft', g:linter).lsp AssertEqual 'tsserver', ale#linter#PreProcess('testft', g:linter).lsp
call remove(g:linter, 'executable')
let g:linter.executable_callback = 'X'
call ale#linter#PreProcess('testft', g:linter)
call remove(g:linter, 'command')
let g:linter.command_callback = 'X'
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should accept stdio LSP configuration): Execute(PreProcess should accept stdio LSP configuration):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'executable': 'x', \ 'executable': 'x',
\ 'command': 'x', \ 'command': 'x',
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'language_callback': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\} \}
AssertEqual 'stdio', ale#linter#PreProcess('testft', g:linter).lsp AssertEqual 'stdio', ale#linter#PreProcess('testft', g:linter).lsp
call remove(g:linter, 'executable')
let g:linter.executable_callback = 'X'
call ale#linter#PreProcess('testft', g:linter)
call remove(g:linter, 'command')
let g:linter.command_callback = 'X'
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should accept LSP server configurations): Execute(PreProcess should accept LSP server configurations):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language_callback': 'x', \ 'language': 'foobar',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\} \}
AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp
Execute(PreProcess should accept let you specify the language as just a string): Execute(PreProcess should accept let you specify the `language` as a Function):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language': 'foobar', \ 'language': {-> 'foobar'},
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\} \}
AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language_callback(0) AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language(bufnr(''))
Execute(PreProcess should complain about using language and language_callback together):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `language` or `language_callback` should be set', g:vader_exception
Execute(PreProcess should complain about invalid language values): Execute(PreProcess should complain about invalid language values):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language': 0, \ 'language': 0,
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\} \}
AssertThrows call ale#linter#PreProcess('testft', g:linter) AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`language` must be a String or Funcref', g:vader_exception AssertEqual '`language` must be a String or Funcref if defined', g:vader_exception
Execute(PreProcess should use the filetype as the language string by default): Execute(PreProcess should use the filetype as the language string by default):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\} \}
AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language_callback(0) AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language
Execute(PreProcess should allow language to be set to a callback): Execute(PreProcess should require an `address` for LSP socket configurations):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': {-> 'foo'},
\ 'project_root_callback': 'x',
\}
AssertEqual 'foo', ale#linter#PreProcess('testft', g:linter).language_callback(0)
Execute(PreProcess should require an address_callback for LSP socket configurations):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\} \}
AssertThrows call ale#linter#PreProcess('testft', g:linter) AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`address` or `address_callback` must be defined for getting the LSP address', g:vader_exception AssertEqual '`address` must be defined for getting the LSP address', g:vader_exception
Execute(PreProcess should complain about address_callback for non-LSP linters): Execute(PreProcess should complain about `address` for non-LSP linters):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'callback': 'SomeFunction', \ 'callback': 'SomeFunction',
\ 'executable': 'echo', \ 'executable': 'echo',
\ 'command': 'echo', \ 'command': 'echo',
\ 'address_callback': 'X', \ 'address': 'X',
\} \}
AssertThrows call ale#linter#PreProcess('testft', g:linter) AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`address` or `address_callback` cannot be used when lsp != ''socket''', g:vader_exception AssertEqual '`address` cannot be used when lsp != ''socket''', g:vader_exception
Execute(PreProcess accept valid address_callback values): Execute(PreProcess accept `address` as a String):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': {-> 'foo:123'},
\ 'language': 'x',
\ 'project_root_callback': 'x',
\})
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
Execute(PreProcess accept address as a String):
let g:linter = ale#linter#PreProcess('testft', { let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address': 'foo:123', \ 'address': 'foo:123',
\ 'language': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\}) \})
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
@ -549,7 +352,7 @@ Execute(PreProcess accept address as a Function):
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address': {-> 'foo:123'}, \ 'address': {-> 'foo:123'},
\ 'language': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\}) \})
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
@ -560,11 +363,11 @@ Execute(PreProcess should complain about invalid address values):
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address': 0, \ 'address': 0,
\ 'language': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\}) \})
AssertEqual '`address` must be a String or Function if defined', g:vader_exception AssertEqual '`address` must be a String or Function if defined', g:vader_exception
Execute(PreProcess should accept allow the project root be set as a String): Execute(PreProcess should allow the `project_root` to be set as a String):
let g:linter = ale#linter#PreProcess('testft', { let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
@ -575,7 +378,7 @@ Execute(PreProcess should accept allow the project root be set as a String):
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter) AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
Execute(PreProcess should accept allow the project root be set as a Function): Execute(PreProcess should `project_root` be set as a Function):
let g:linter = ale#linter#PreProcess('testft', { let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
@ -586,7 +389,7 @@ Execute(PreProcess should accept allow the project root be set as a Function):
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter) AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
Execute(PreProcess should complain when the project_root valid is invalid): Execute(PreProcess should complain when `project_root` is invalid):
AssertThrows call ale#linter#PreProcess('testft', { AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
@ -594,154 +397,74 @@ Execute(PreProcess should complain when the project_root valid is invalid):
\ 'language': 'x', \ 'language': 'x',
\ 'project_root': 0, \ 'project_root': 0,
\}) \})
AssertEqual '`project_root` must be a String or Function if defined', g:vader_exception AssertEqual '`project_root` must be a String or Function', g:vader_exception
Execute(PreProcess should accept project_root_callback as a String): Execute(PreProcess should throw when `initialization_options` is not a Dictionary or callback):
call ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address': 'foo:123',
\ 'language': 'x',
\ 'project_root_callback': 'Foobar',
\})
Execute(PreProcess should accept project_root_callback as a Function):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address': 'foo:123',
\ 'language': 'x',
\ 'project_root_callback': {-> '/foo/bar'},
\})
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
Execute(PreProcess should complain when the project_root_callback valid is invalid):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address': 'foo:123',
\ 'language': 'x',
\ 'project_root_callback': 0,
\})
AssertEqual '`project_root_callback` must be a callback if defined', g:vader_exception
Execute(PreProcess should complain about using initialization_options and initialization_options_callback together):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'initialization_options': 'x',
\ 'initialization_options_callback': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `initialization_options` or `initialization_options_callback` should be set', g:vader_exception
Execute(PreProcess should throw when initialization_options_callback is not a callback):
AssertThrows call ale#linter#PreProcess('testft', { AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo', \ 'name': 'foo',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\ 'initialization_options_callback': {},
\})
AssertEqual '`initialization_options_callback` must be a callback if defined', g:vader_exception
Execute(PreProcess should throw when initialization_options is not a Dictionary or callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'initialization_options': 0, \ 'initialization_options': 0,
\}) \})
AssertEqual '`initialization_options` must be a String or Function if defined', g:vader_exception AssertEqual '`initialization_options` must be a Dictionary or Function if defined', g:vader_exception
Execute(PreProcess should accept initialization_options as a Dictionary): Execute(PreProcess should accept `initialization_options` as a Dictionary):
let g:linter = ale#linter#PreProcess('testft', { let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'foo', \ 'name': 'foo',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\ 'initialization_options': {'foo': v:true}, \ 'initialization_options': {'foo': v:true},
\}) \})
AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter) AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter)
Execute(PreProcess should accept initialization_options as a Funcref): Execute(PreProcess should accept `initialization_options` as a Function):
let g:linter = ale#linter#PreProcess('testft', { let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'foo', \ 'name': 'foo',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\ 'initialization_options': {-> {'foo': v:true}}, \ 'initialization_options': {-> {'foo': v:true}},
\}) \})
AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter) AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter)
Execute(PreProcess should complain about using lsp_config and lsp_config_callback together): Execute(PreProcess should accept `lsp_config` as a Dictionary):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\ 'lsp_config': 'x',
\ 'lsp_config_callback': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `lsp_config` or `lsp_config_callback` should be set', g:vader_exception
Execute(PreProcess should throw when lsp_config_callback is not a callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'lsp_config_callback': {},
\})
AssertEqual '`lsp_config_callback` must be a callback if defined', g:vader_exception
Execute(PreProcess should accept LSP configuration options via lsp_config):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\ 'lsp_config': {'foo': 'bar'}, \ 'lsp_config': {'foo': 'bar'},
\} \}
AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter) AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter)
Execute(PreProcess should accept LSP configuration options via lsp_config as a function): Execute(PreProcess should accept `lsp_config` as a Function):
let g:linter = { let g:linter = {
\ 'name': 'x', \ 'name': 'x',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language_callback': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\ 'lsp_config': {-> {'foo': 'bar'}}, \ 'lsp_config': {-> {'foo': 'bar'}},
\} \}
AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter) AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter)
Execute(PreProcess should throw when lsp_config is not a Dictionary or Function): Execute(PreProcess should throw when `lsp_config` is not a Dictionary or Function):
AssertThrows call ale#linter#PreProcess('testft', { AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo', \ 'name': 'foo',
\ 'lsp': 'socket', \ 'lsp': 'socket',
\ 'address_callback': 'X', \ 'address': 'X',
\ 'language': 'x', \ 'language': 'x',
\ 'project_root_callback': 'x', \ 'project_root': 'x',
\ 'lsp_config': 'x', \ 'lsp_config': 'x',
\}) \})
AssertEqual '`lsp_config` must be a Dictionary or Function if defined', g:vader_exception AssertEqual '`lsp_config` must be a Dictionary or Function if defined', g:vader_exception

View File

@ -40,7 +40,7 @@ Before:
\ 'name': 'testlinter', \ 'name': 'testlinter',
\ 'executable': has('win32') ? 'cmd' : 'echo', \ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'callback': 'TestCallback', \ 'callback': 'TestCallback',
\ 'command_callback': 'TestCommandCallback', \ 'command': function('TestCommandCallback'),
\}) \})
call ale#command#ClearData() call ale#command#ClearData()