diff options
-rw-r--r-- | ale_linters/ocaml/ols.vim | 2 | ||||
-rw-r--r-- | ale_linters/reason/ols.vim | 2 | ||||
-rw-r--r-- | autoload/ale/assert.vim | 2 | ||||
-rw-r--r-- | autoload/ale/definition.vim | 8 | ||||
-rw-r--r-- | autoload/ale/engine.vim | 130 | ||||
-rw-r--r-- | autoload/ale/fix.vim | 25 | ||||
-rw-r--r-- | autoload/ale/linter.vim | 183 | ||||
-rw-r--r-- | autoload/ale/lsp_linter.vim | 2 | ||||
-rw-r--r-- | autoload/ale/test.vim | 4 | ||||
-rw-r--r-- | doc/ale.txt | 22 | ||||
-rw-r--r-- | plugin/ale.vim | 24 | ||||
-rw-r--r-- | test/fix/test_ale_fix.vader | 108 | ||||
-rw-r--r-- | test/lsp/test_did_save_event.vader | 4 | ||||
-rw-r--r-- | test/lsp/test_lsp_command_formatting.vader | 4 | ||||
-rw-r--r-- | test/lsp/test_lsp_custom_request.vader | 1 | ||||
-rw-r--r-- | test/test_command_chain.vader | 73 | ||||
-rw-r--r-- | test/test_engine_invocation.vader | 108 | ||||
-rw-r--r-- | test/test_go_to_definition.vader | 2 | ||||
-rw-r--r-- | test/test_linter_defintion_processing.vader | 387 | ||||
-rw-r--r-- | test/test_temporary_file_management.vader | 2 |
20 files changed, 125 insertions, 968 deletions
diff --git a/ale_linters/ocaml/ols.vim b/ale_linters/ocaml/ols.vim index d8208c52..ec71bdb4 100644 --- a/ale_linters/ocaml/ols.vim +++ b/ale_linters/ocaml/ols.vim @@ -9,6 +9,6 @@ call ale#linter#Define('ocaml', { \ 'lsp': 'stdio', \ 'executable': function('ale#handlers#ols#GetExecutable'), \ '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'), \}) diff --git a/ale_linters/reason/ols.vim b/ale_linters/reason/ols.vim index 66137e1b..9fbd9b4f 100644 --- a/ale_linters/reason/ols.vim +++ b/ale_linters/reason/ols.vim @@ -9,6 +9,6 @@ call ale#linter#Define('reason', { \ 'lsp': 'stdio', \ 'executable': function('ale#handlers#ols#GetExecutable'), \ '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'), \}) diff --git a/autoload/ale/assert.vim b/autoload/ale/assert.vim index 291edcee..934fcaa8 100644 --- a/autoload/ale/assert.vim +++ b/autoload/ale/assert.vim @@ -130,7 +130,7 @@ endfunction function! ale#assert#LSPLanguage(expected_language) abort let l:buffer = bufnr('') 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 endfunction diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim index ffcd9d10..0c1fb7cf 100644 --- a/autoload/ale/definition.vim +++ b/autoload/ale/definition.vim @@ -135,10 +135,6 @@ function! s:GoToLSPDefinition(linter, options, capability) abort endfunction 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) if !empty(l:linter.lsp) call s:GoToLSPDefinition(l:linter, a:options, 'definition') @@ -147,10 +143,6 @@ function! ale#definition#GoTo(options) abort endfunction 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) if !empty(l:linter.lsp) " TODO: handle typeDefinition for tsserver if supported by the diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 491d3c2e..cfc1e5d7 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -104,42 +104,6 @@ function! ale#engine#IsCheckingBuffer(buffer) abort \ || !empty(get(l:info, 'active_other_sources_list', [])) 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 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:executable = a:job_info.executable - let l:next_chain_index = a:job_info.next_chain_index " Remove this job from the list. 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) 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 let l:loclist = ale#util#GetFunction(l:linter.callback)(a:buffer, a:output) " 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:linter = a:options.linter 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:info = g:ale_buffer_info[l:buffer] let l:Callback = function('s:HandleExit', [{ \ 'linter': l:linter, \ 'executable': l:executable, - \ 'next_chain_index': l:next_chain_index, \}]) let l:result = ale#command#Run(l:buffer, l:command, l:Callback, { \ 'output_stream': l:output_stream, \ 'executable': l:executable, \ '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. @@ -482,68 +429,6 @@ function! s:RunJob(command, options) abort return 1 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 let l:info = get(g:ale_buffer_info, a:buffer, {}) 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' 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:options = { \ 'executable': a:executable, \ 'buffer': a:buffer, \ 'linter': a:linter, \ 'output_stream': get(a:linter, 'output_stream', 'stdout'), - \ 'next_chain_index': 1, \ 'read_buffer': a:linter.read_buffer, \} diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim index 69817b36..b2a39444 100644 --- a/autoload/ale/fix.vim +++ b/autoload/ale/fix.vim @@ -90,7 +90,6 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort let l:output = a:job_output endif - let l:ChainCallback = get(a:job_info, 'chain_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. @@ -102,27 +101,18 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort " otherwise skip this job and use the input from before. " " 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 else let l:input = a:job_info.input 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({ \ 'buffer': a:buffer, \ 'input': l:input, \ 'output': l:output, \ 'callback_list': a:job_info.callback_list, - \ 'callback_index': l:next_index, - \ 'chain_callback': l:ChainCallback, + \ 'callback_index': a:job_info.callback_index + 1, \}) endfunction @@ -152,17 +142,14 @@ function! s:RunJob(result, options) abort endif let l:command = get(a:result, 'command', '') - let l:ChainWith = get(a:result, 'chain_with', v:null) if empty(l:command) - " If the command is empty, skip to the next item, or call the - " chain_with function. + " If the command is empty, skip to the next item. call s:RunFixer({ \ 'buffer': l:buffer, \ '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, - \ 'chain_callback': l:ChainWith, \ 'output': [], \}) @@ -170,8 +157,7 @@ function! s:RunJob(result, options) abort endif 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', l:ChainWith is v:null) + let l:read_buffer = get(a:result, 'read_buffer', 1) let l:output_stream = get(a:result, 'output_stream', 'stdout') if l:read_temporary_file @@ -180,7 +166,6 @@ function! s:RunJob(result, options) abort let l:Callback = function('s:HandleExit', [{ \ 'input': l:input, - \ 'chain_with': l:ChainWith, \ 'callback_index': a:options.callback_index, \ 'callback_list': a:options.callback_list, \ 'process_with': get(a:result, 'process_with', v:null), diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index 0e935149..fecfeed6 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -77,10 +77,6 @@ function! s:IsBoolean(value) abort return type(a:value) is v:t_number && (a:value == 0 || a:value == 1) endfunction -function! s:LanguageGetter(buffer) dict abort - return l:self.language -endfunction - function! ale#linter#PreProcess(filetype, linter) abort if type(a:linter) isnot v:t_dict throw 'The linter object must be a Dictionary' @@ -114,14 +110,7 @@ function! ale#linter#PreProcess(filetype, linter) abort if !l:needs_executable if has_key(a:linter, 'executable') - \|| has_key(a:linter, 'executable_callback') - 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' + throw '`executable` cannot be used when lsp == ''socket''' endif elseif has_key(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' endif else - throw 'Either `executable` or `executable_callback` must be defined' + throw '`executable` must be defined' endif if !l:needs_command if has_key(a:linter, 'command') - \|| has_key(a:linter, 'command_callback') - \|| 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' + throw '`command` cannot be used when lsp == ''socket''' endif elseif has_key(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' endif else - throw 'Either `command`, `executable_callback`, `command_chain` ' - \ . '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' + throw '`command` must be defined' endif if !l:needs_address - if has_key(a:linter, 'address') || has_key(a:linter, 'address_callback') - throw '`address` or `address_callback` cannot be used when lsp != ''socket''' + if has_key(a:linter, 'address') + throw '`address` cannot be used when lsp != ''socket''' endif elseif has_key(a:linter, 'address') if type(a:linter.address) isnot v:t_string @@ -212,41 +149,17 @@ function! ale#linter#PreProcess(filetype, linter) abort endif 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 - throw '`address` or `address_callback` must be defined for getting the LSP address' + throw '`address` must be defined for getting the LSP address' endif if l:needs_lsp_details - if has_key(a:linter, 'language_callback') - if has_key(a:linter, 'language') - throw 'Only one of `language` or `language_callback` ' - \ . 'should be set' - endif - - let l:obj.language_callback = get(a:linter, 'language_callback') + " Default to using the filetype as the language. + let l:obj.language = get(a:linter, 'language', a:filetype) - if !s:IsCallback(l:obj.language_callback) - 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 + if type(l:obj.language) isnot v:t_string + \&& type(l:obj.language) isnot v:t_func + throw '`language` must be a String or Funcref if defined' endif 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 \&& type(l:obj.project_root) isnot v:t_func - throw '`project_root` must be a String or Function if defined' - 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' + throw '`project_root` must be a String or Function' endif else - throw '`project_root` or `project_root_callback` must be defined for LSP linters' + throw '`project_root` must be defined for LSP linters' endif if has_key(a:linter, 'completion_filter') @@ -274,37 +181,16 @@ function! ale#linter#PreProcess(filetype, linter) abort endif endif - if has_key(a:linter, 'initialization_options_callback') - 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') + if has_key(a:linter, 'initialization_options') let l:obj.initialization_options = a:linter.initialization_options if type(l:obj.initialization_options) isnot v:t_dict \&& 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 - if has_key(a:linter, 'lsp_config_callback') - 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 has_key(a:linter, 'lsp_config') if type(a:linter.lsp_config) isnot v:t_dict \&& type(a:linter.lsp_config) isnot v:t_func 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' 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 endfunction @@ -522,9 +400,7 @@ endfunction " Given a buffer and linter, get the executable String for the linter. function! ale#linter#GetExecutable(buffer, linter) abort - let l:Executable = has_key(a:linter, 'executable_callback') - \ ? function(a:linter.executable_callback) - \ : a:linter.executable + let l:Executable = a:linter.executable return type(l:Executable) is v:t_func \ ? l:Executable(a:buffer) @@ -532,24 +408,21 @@ function! ale#linter#GetExecutable(buffer, linter) abort endfunction " 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 - let l:Command = has_key(a:linter, 'command_callback') - \ ? function(a:linter.command_callback) - \ : a:linter.command + let l:Command = a:linter.command - return type(l:Command) is v:t_func - \ ? l:Command(a:buffer) - \ : l:Command + return type(l:Command) is v:t_func ? l:Command(a:buffer) : l:Command endfunction " Given a buffer and linter, get the address for connecting to the server. function! ale#linter#GetAddress(buffer, linter) abort - let l:Address = has_key(a:linter, 'address_callback') - \ ? function(a:linter.address_callback) - \ : a:linter.address + let l:Address = a:linter.address + + return type(l:Address) is v:t_func ? l:Address(a:buffer) : l:Address +endfunction + +function! ale#linter#GetLanguage(buffer, linter) abort + let l:Language = a:linter.language - return type(l:Address) is v:t_func - \ ? l:Address(a:buffer) - \ : l:Address + return type(l:Language) is v:t_func ? l:Language(a:buffer) : l:Language endfunction diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim index e4148ceb..f4a42bf4 100644 --- a/autoload/ale/lsp_linter.vim +++ b/autoload/ale/lsp_linter.vim @@ -227,7 +227,7 @@ function! ale#lsp_linter#OnInit(linter, details, Callback) abort let l:command = a:details.command 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) diff --git a/autoload/ale/test.vim b/autoload/ale/test.vim index 082d91ff..6fcbf35e 100644 --- a/autoload/ale/test.vim +++ b/autoload/ale/test.vim @@ -145,8 +145,8 @@ function! ale#test#WaitForJobs(deadline) abort " end, but before handlers are run. sleep 10ms - " We must check the buffer data again to see if new jobs started - " for command_chain linters. + " We must check the buffer data again to see if new jobs started for + " linters with chained commands. let l:has_new_jobs = 0 " Check again to see if any jobs are running. diff --git a/doc/ale.txt b/doc/ale.txt index 50c0b8a0..606fe72c 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -684,7 +684,9 @@ g:ale_completion_enabled *g:ale_completion_enabled* 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 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 items by setting it to `1`. + g:ale_completion_autoimport *g:ale_completion_autoimport* Type: Number @@ -2809,7 +2812,13 @@ ALEGoToDefinition `<options>` *ALEGoToDefinition* command. Otherwise, Vim will refuse to leave the buffer you're jumping from 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* @@ -2831,8 +2840,13 @@ ALEGoToTypeDefinition *ALEGoToTypeDefinition* 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|. - A plug mapping `<Plug>(ale_go_to_type_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_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* diff --git a/plugin/ale.vim b/plugin/ale.vim index 65c5a77c..0651dd4b 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -207,19 +207,9 @@ command! -bar ALEFixSuggest :call ale#fix#registry#Suggest(&filetype) " Go to definition for tsserver and LSP 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 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 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_fix) :ALEFix<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_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_hover) :ALEHover<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_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. call ale#events#Init() diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader index 6081f4e2..53079d16 100644 --- a/test/fix/test_ale_fix.vader +++ b/test/fix/test_ale_fix.vader @@ -84,56 +84,6 @@ Before: return [{'lnum': 1, 'col': 1, 'text': 'xxx'}] 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. function! IgnoredEmptyOutput(buffer, output) return {'command': has('win32') ? 'echo(' : 'echo'} @@ -208,13 +158,6 @@ After: delfunction RemoveLastLine delfunction RemoveLastLineOneArg delfunction TestCallback - delfunction FirstChainCallback - delfunction FirstChainCallbackSkipped - delfunction FirstChainCallbackSecondSkipped - delfunction SecondChainCallback - delfunction ThirdChainCallback - delfunction ChainWhereLastIsSkipped - delfunction ChainEndSkipped delfunction SetUpLinters delfunction GetLastMessage delfunction IgnoredEmptyOutput @@ -816,57 +759,6 @@ Execute(ALE should tolerate valid fixers with minuses in the name): ALEFix 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): let g:ale_fixers.testft = ['IgnoredEmptyOutput'] ALEFix diff --git a/test/lsp/test_did_save_event.vader b/test/lsp/test_did_save_event.vader index bdea6d98..1d811363 100644 --- a/test/lsp/test_did_save_event.vader +++ b/test/lsp/test_did_save_event.vader @@ -33,8 +33,8 @@ Before: \ 'lsp': 'stdio', \ 'command': 'cat - > /dev/null', \ 'executable': has('win32') ? 'cmd' : 'echo', - \ 'language_callback': 'LanguageCallback', - \ 'project_root_callback': 'ProjectRootCallback', + \ 'language': function('LanguageCallback'), + \ 'project_root': function('ProjectRootCallback'), \ }) let g:ale_linters = {'foobar': ['dummy_linter']} diff --git a/test/lsp/test_lsp_command_formatting.vader b/test/lsp/test_lsp_command_formatting.vader index 2c1e8788..e99e1dad 100644 --- a/test/lsp/test_lsp_command_formatting.vader +++ b/test/lsp/test_lsp_command_formatting.vader @@ -24,8 +24,8 @@ Execute(Command formatting should be applied correctly for LSP linters): \ bufnr(''), \ { \ 'name': 'linter', - \ 'language_callback': {-> 'x'}, - \ 'project_root_callback': {-> '/foo/bar'}, + \ 'language': {-> 'x'}, + \ 'project_root': {-> '/foo/bar'}, \ 'lsp': 'stdio', \ 'executable': has('win32') ? 'cmd': 'true', \ 'command': '%e --foo', diff --git a/test/lsp/test_lsp_custom_request.vader b/test/lsp/test_lsp_custom_request.vader index 04f044af..c8767e59 100644 --- a/test/lsp/test_lsp_custom_request.vader +++ b/test/lsp/test_lsp_custom_request.vader @@ -25,7 +25,6 @@ Before: \ 'name': g:linter_name, \ 'project_root': {b -> g:project_root}, \ 'aliases': [], - \ 'language_callback': {b -> 'cpp'}, \ 'read_buffer': 1, \ 'command': '%e' \ }] diff --git a/test/test_command_chain.vader b/test/test_command_chain.vader deleted file mode 100644 index 329ebc97..00000000 --- a/test/test_command_chain.vader +++ /dev/null @@ -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 diff --git a/test/test_engine_invocation.vader b/test/test_engine_invocation.vader deleted file mode 100644 index af713953..00000000 --- a/test/test_engine_invocation.vader +++ /dev/null @@ -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' diff --git a/test/test_go_to_definition.vader b/test/test_go_to_definition.vader index a517bd54..f2f34280 100644 --- a/test/test_go_to_definition.vader +++ b/test/test_go_to_definition.vader @@ -514,7 +514,7 @@ Execute(LSP tab type definition requests should be sent): let b:ale_linters = ['pyls'] call setpos('.', [bufnr(''), 1, 5, 0]) - ALEGoToTypeDefinitionInTab + ALEGoToTypeDefinition -tab " We shouldn't register the callback yet. AssertEqual '''''', string(g:Callback) diff --git a/test/test_linter_defintion_processing.vader b/test/test_linter_defintion_processing.vader index cd32ebc8..2c85299b 100644 --- a/test/test_linter_defintion_processing.vader +++ b/test/test_linter_defintion_processing.vader @@ -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 -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', { \ 'name': 'foo', \ 'callback': 'SomeFunction', \ '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): 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 -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): call ale#linter#PreProcess('testft', { \ 'name': 'foo', @@ -79,7 +70,7 @@ Execute (PreProcess should throw when there is no command): \ 'callback': 'SomeFunction', \ '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): AssertThrows call ale#linter#PreProcess('testft', { @@ -98,15 +89,6 @@ Execute (PreProcess should allow command to be a callback): \ '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): AssertThrows call ale#linter#PreProcess('testft', { \ 'name': 'foo', @@ -152,117 +134,12 @@ Execute (PreProcess should accept a 'both' output_stream): \ '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): let g:linter = { \ 'name': 'x', \ 'callback': 'x', \ 'executable': 'x', - \ 'command_chain': [{'callback': 'foo'}, {'callback': 'bar'}], + \ 'command': 'x', \ 'read_buffer': '0', \} @@ -277,25 +154,6 @@ Execute(PreProcess should process the read_buffer option correctly): 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): let g:linter = { \ 'name': 'x', @@ -394,151 +252,96 @@ Execute(PreProcess should accept tsserver LSP configuration): \ 'executable': 'x', \ 'command': 'x', \ 'lsp': 'tsserver', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'language': 'x', + \ 'project_root': 'x', \} 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): let g:linter = { \ 'name': 'x', \ 'executable': 'x', \ 'command': 'x', \ 'lsp': 'stdio', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'language': 'x', + \ 'project_root': 'x', \} 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): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', - \} - - AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp - -Execute(PreProcess should accept let you specify the language as just a string): - let g:linter = { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'foobar', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \} - AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language_callback(0) + AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp -Execute(PreProcess should complain about using language and language_callback together): +Execute(PreProcess should accept let you specify the `language` as a Function): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': 'x', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'address': 'X', + \ 'language': {-> 'foobar'}, + \ 'project_root': 'x', \} - AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual 'Only one of `language` or `language_callback` should be set', g:vader_exception + AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language(bufnr('')) Execute(PreProcess should complain about invalid language values): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 0, - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \} 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): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'project_root_callback': 'x', - \} - - AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language_callback(0) - -Execute(PreProcess should allow language to be set to a callback): - let g:linter = { - \ 'name': 'x', - \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': {-> 'foo'}, - \ 'project_root_callback': 'x', + \ 'address': 'X', + \ 'project_root': 'x', \} - AssertEqual 'foo', ale#linter#PreProcess('testft', g:linter).language_callback(0) + AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language -Execute(PreProcess should require an address_callback for LSP socket configurations): +Execute(PreProcess should require an `address` for LSP socket configurations): let g:linter = { \ 'name': 'x', \ 'lsp': 'socket', \} 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 = { \ 'name': 'x', \ 'callback': 'SomeFunction', \ 'executable': 'echo', \ 'command': 'echo', - \ 'address_callback': 'X', + \ 'address': 'X', \} 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): - 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): +Execute(PreProcess accept `address` as a String): let g:linter = ale#linter#PreProcess('testft', { \ 'name': 'x', \ 'lsp': 'socket', \ 'address': 'foo:123', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \}) AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) @@ -549,7 +352,7 @@ Execute(PreProcess accept address as a Function): \ 'lsp': 'socket', \ 'address': {-> 'foo:123'}, \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \}) AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter) @@ -560,11 +363,11 @@ Execute(PreProcess should complain about invalid address values): \ 'lsp': 'socket', \ 'address': 0, \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \}) 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', { \ 'name': 'x', \ '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) -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', { \ 'name': 'x', \ '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) -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', { \ 'name': 'x', \ 'lsp': 'socket', @@ -594,154 +397,74 @@ Execute(PreProcess should complain when the project_root valid is invalid): \ 'language': 'x', \ '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): - 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', { - \ 'name': 'foo', - \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language': 'x', - \ 'project_root_callback': '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): +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', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ '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', { \ 'name': 'foo', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ 'initialization_options': {'foo': v:true}, \}) 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', { \ 'name': 'foo', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ 'initialization_options': {-> {'foo': v:true}}, \}) 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 = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': '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', + \ 'project_root': 'x', \ 'lsp_config': {'foo': 'bar'}, \} 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 = { \ 'name': 'x', \ 'lsp': 'socket', - \ 'address_callback': 'X', - \ 'language_callback': 'x', - \ 'project_root_callback': 'x', + \ 'address': 'X', + \ 'language': 'x', + \ 'project_root': 'x', \ 'lsp_config': {-> {'foo': 'bar'}}, \} 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', { \ 'name': 'foo', \ 'lsp': 'socket', - \ 'address_callback': 'X', + \ 'address': 'X', \ 'language': 'x', - \ 'project_root_callback': 'x', + \ 'project_root': 'x', \ 'lsp_config': 'x', \}) AssertEqual '`lsp_config` must be a Dictionary or Function if defined', g:vader_exception diff --git a/test/test_temporary_file_management.vader b/test/test_temporary_file_management.vader index 9fff1ace..bb735886 100644 --- a/test/test_temporary_file_management.vader +++ b/test/test_temporary_file_management.vader @@ -40,7 +40,7 @@ Before: \ 'name': 'testlinter', \ 'executable': has('win32') ? 'cmd' : 'echo', \ 'callback': 'TestCallback', - \ 'command_callback': 'TestCommandCallback', + \ 'command': function('TestCommandCallback'), \}) call ale#command#ClearData() |