Close #2281 - Separate cwd commands from commands

Working directories are now set seperately from the commands so they
can later be swapped out when running linters over projects is
supported, and also better support filename mapping for running linters
on other machines in future.
This commit is contained in:
w0rp 2021-03-01 20:11:10 +00:00
parent 48fab99a0a
commit 9fe7b1fe6a
No known key found for this signature in database
GPG Key ID: 0FC1ECAA8C81CD83
117 changed files with 1142 additions and 1111 deletions

View File

@ -5,15 +5,13 @@ call ale#Set('c_cppcheck_executable', 'cppcheck')
call ale#Set('c_cppcheck_options', '--enable=style') call ale#Set('c_cppcheck_options', '--enable=style')
function! ale_linters#c#cppcheck#GetCommand(buffer) abort function! ale_linters#c#cppcheck#GetCommand(buffer) abort
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
let l:buffer_path_include = empty(l:compile_commands_option) let l:buffer_path_include = empty(l:compile_commands_option)
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : '' \ : ''
let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
return l:cd_command return '%e -q --language=c'
\ . '%e -q --language=c'
\ . l:template \ . l:template
\ . ale#Pad(l:compile_commands_option) \ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options')) \ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options'))
@ -25,6 +23,7 @@ call ale#linter#Define('c', {
\ 'name': 'cppcheck', \ 'name': 'cppcheck',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'executable': {b -> ale#Var(b, 'c_cppcheck_executable')}, \ 'executable': {b -> ale#Var(b, 'c_cppcheck_executable')},
\ 'cwd': function('ale#handlers#cppcheck#GetCwd'),
\ 'command': function('ale_linters#c#cppcheck#GetCommand'), \ 'command': function('ale_linters#c#cppcheck#GetCommand'),
\ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat', \ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat',
\}) \})

View File

@ -5,15 +5,13 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck')
call ale#Set('cpp_cppcheck_options', '--enable=style') call ale#Set('cpp_cppcheck_options', '--enable=style')
function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
let l:buffer_path_include = empty(l:compile_commands_option) let l:buffer_path_include = empty(l:compile_commands_option)
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : '' \ : ''
let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
return l:cd_command return '%e -q --language=c++'
\ . '%e -q --language=c++'
\ . l:template \ . l:template
\ . ale#Pad(l:compile_commands_option) \ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options')) \ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options'))
@ -25,6 +23,7 @@ call ale#linter#Define('cpp', {
\ 'name': 'cppcheck', \ 'name': 'cppcheck',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'executable': {b -> ale#Var(b, 'cpp_cppcheck_executable')}, \ 'executable': {b -> ale#Var(b, 'cpp_cppcheck_executable')},
\ 'cwd': function('ale#handlers#cppcheck#GetCwd'),
\ 'command': function('ale_linters#cpp#cppcheck#GetCommand'), \ 'command': function('ale_linters#cpp#cppcheck#GetCommand'),
\ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat', \ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat',
\}) \})

View File

@ -3,14 +3,10 @@ call ale#Set('cs_csc_source', '')
call ale#Set('cs_csc_assembly_path', []) call ale#Set('cs_csc_assembly_path', [])
call ale#Set('cs_csc_assemblies', []) call ale#Set('cs_csc_assemblies', [])
function! s:GetWorkingDirectory(buffer) abort function! ale_linters#cs#csc#GetCwd(buffer) abort
let l:working_directory = ale#Var(a:buffer, 'cs_csc_source') let l:cwd = ale#Var(a:buffer, 'cs_csc_source')
if !empty(l:working_directory) return !empty(l:cwd) ? l:cwd : expand('#' . a:buffer . ':p:h')
return l:working_directory
endif
return expand('#' . a:buffer . ':p:h')
endfunction endfunction
function! ale_linters#cs#csc#GetCommand(buffer) abort function! ale_linters#cs#csc#GetCommand(buffer) abort
@ -34,8 +30,7 @@ function! ale_linters#cs#csc#GetCommand(buffer) abort
" The code is compiled as a module and the output is redirected to a " The code is compiled as a module and the output is redirected to a
" temporary file. " temporary file.
return ale#path#CdString(s:GetWorkingDirectory(a:buffer)) return 'csc /unsafe'
\ . 'csc /unsafe'
\ . ale#Pad(ale#Var(a:buffer, 'cs_csc_options')) \ . ale#Pad(ale#Var(a:buffer, 'cs_csc_options'))
\ . ale#Pad(l:lib_option) \ . ale#Pad(l:lib_option)
\ . ale#Pad(l:r_option) \ . ale#Pad(l:r_option)
@ -57,8 +52,7 @@ function! ale_linters#cs#csc#Handle(buffer, lines) abort
\ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$', \ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
\] \]
let l:output = [] let l:output = []
let l:dir = ale_linters#cs#csc#GetCwd(a:buffer)
let l:dir = s:GetWorkingDirectory(a:buffer)
for l:match in ale#util#GetMatches(a:lines, l:patterns) for l:match in ale#util#GetMatches(a:lines, l:patterns)
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS' if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
@ -89,6 +83,7 @@ call ale#linter#Define('cs',{
\ 'name': 'csc', \ 'name': 'csc',
\ 'output_stream': 'stdout', \ 'output_stream': 'stdout',
\ 'executable': 'csc', \ 'executable': 'csc',
\ 'cwd': function('ale_linters#cs#csc#GetCwd'),
\ 'command': function('ale_linters#cs#csc#GetCommand'), \ 'command': function('ale_linters#cs#csc#GetCommand'),
\ 'callback': 'ale_linters#cs#csc#Handle', \ 'callback': 'ale_linters#cs#csc#Handle',
\ 'lint_file': 1 \ 'lint_file': 1

View File

@ -3,14 +3,10 @@ call ale#Set('cs_mcsc_source', '')
call ale#Set('cs_mcsc_assembly_path', []) call ale#Set('cs_mcsc_assembly_path', [])
call ale#Set('cs_mcsc_assemblies', []) call ale#Set('cs_mcsc_assemblies', [])
function! s:GetWorkingDirectory(buffer) abort function! ale_linters#cs#mcsc#GetCwd(buffer) abort
let l:working_directory = ale#Var(a:buffer, 'cs_mcsc_source') let l:cwd = ale#Var(a:buffer, 'cs_mcsc_source')
if !empty(l:working_directory) return !empty(l:cwd) ? l:cwd : expand('#' . a:buffer . ':p:h')
return l:working_directory
endif
return expand('#' . a:buffer . ':p:h')
endfunction endfunction
function! ale_linters#cs#mcsc#GetCommand(buffer) abort function! ale_linters#cs#mcsc#GetCommand(buffer) abort
@ -34,8 +30,7 @@ function! ale_linters#cs#mcsc#GetCommand(buffer) abort
" The code is compiled as a module and the output is redirected to a " The code is compiled as a module and the output is redirected to a
" temporary file. " temporary file.
return ale#path#CdString(s:GetWorkingDirectory(a:buffer)) return 'mcs -unsafe'
\ . 'mcs -unsafe'
\ . ale#Pad(ale#Var(a:buffer, 'cs_mcsc_options')) \ . ale#Pad(ale#Var(a:buffer, 'cs_mcsc_options'))
\ . ale#Pad(l:lib_option) \ . ale#Pad(l:lib_option)
\ . ale#Pad(l:r_option) \ . ale#Pad(l:r_option)
@ -58,7 +53,7 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
\] \]
let l:output = [] let l:output = []
let l:dir = s:GetWorkingDirectory(a:buffer) let l:dir = ale_linters#cs#mcsc#GetCwd(a:buffer)
for l:match in ale#util#GetMatches(a:lines, l:patterns) for l:match in ale#util#GetMatches(a:lines, l:patterns)
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS' if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
@ -89,6 +84,7 @@ call ale#linter#Define('cs',{
\ 'name': 'mcsc', \ 'name': 'mcsc',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': 'mcs', \ 'executable': 'mcs',
\ 'cwd': function('ale_linters#cs#mcsc#GetCwd'),
\ 'command': function('ale_linters#cs#mcsc#GetCommand'), \ 'command': function('ale_linters#cs#mcsc#GetCommand'),
\ 'callback': 'ale_linters#cs#mcsc#Handle', \ 'callback': 'ale_linters#cs#mcsc#Handle',
\ 'lint_file': 1 \ 'lint_file': 1

View File

@ -1,35 +1,37 @@
" Author: w0rp <devw0rp@gmail.com> " Author: w0rp <devw0rp@gmail.com>
" Description: "dmd for D files" " Description: "dmd for D files"
function! ale_linters#d#dmd#GetDUBCommand(buffer) abort function! s:GetDUBCommand(buffer) abort
" If we can't run dub, then skip this command. " If we can't run dub, then skip this command.
if !executable('dub') if !executable('dub')
" Returning an empty string skips to the DMD command. " Returning an empty string skips to the DMD command.
return '' let l:config = ale#d#FindDUBConfig(a:buffer)
" To support older dub versions, we just change the directory to the
" directory where we found the dub config, and then run `dub describe`
" from that directory.
if !empty(l:config)
return [fnamemodify(l:config, ':h'), 'dub describe --import-paths']
endif
endif endif
let l:dub_file = ale#d#FindDUBConfig(a:buffer) return ['', '']
if empty(l:dub_file)
return ''
endif
" To support older dub versions, we just change the directory to
" the directory where we found the dub config, and then run `dub describe`
" from that directory.
return 'cd ' . ale#Escape(fnamemodify(l:dub_file, ':h'))
\ . ' && dub describe --import-paths'
endfunction endfunction
function! ale_linters#d#dmd#RunDUBCommand(buffer) abort function! ale_linters#d#dmd#RunDUBCommand(buffer) abort
let l:command = ale_linters#d#dmd#GetDUBCommand(a:buffer) let [l:cwd, l:command] = s:GetDUBCommand(a:buffer)
if empty(l:command) if empty(l:command)
" If we can't run DUB, just run DMD. " If we can't run DUB, just run DMD.
return ale_linters#d#dmd#DMDCommand(a:buffer, [], {}) return ale_linters#d#dmd#DMDCommand(a:buffer, [], {})
endif endif
return ale#command#Run(a:buffer, l:command, function('ale_linters#d#dmd#DMDCommand')) return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#d#dmd#DMDCommand'),
\ {'cwd': l:cwd},
\)
endfunction endfunction
function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) abort function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) abort

View File

@ -56,11 +56,7 @@ function! ale_linters#elixir#credo#GetConfigFile() abort
endfunction endfunction
function! ale_linters#elixir#credo#GetCommand(buffer) abort function! ale_linters#elixir#credo#GetCommand(buffer) abort
let l:project_root = ale#handlers#elixir#FindMixUmbrellaRoot(a:buffer) return 'mix help credo && '
let l:mode = ale_linters#elixir#credo#GetMode()
return ale#path#CdString(l:project_root)
\ . 'mix help credo && '
\ . 'mix credo ' . ale_linters#elixir#credo#GetMode() \ . 'mix credo ' . ale_linters#elixir#credo#GetMode()
\ . ale_linters#elixir#credo#GetConfigFile() \ . ale_linters#elixir#credo#GetConfigFile()
\ . ' --format=flycheck --read-from-stdin %s' \ . ' --format=flycheck --read-from-stdin %s'
@ -69,6 +65,7 @@ endfunction
call ale#linter#Define('elixir', { call ale#linter#Define('elixir', {
\ 'name': 'credo', \ 'name': 'credo',
\ 'executable': 'mix', \ 'executable': 'mix',
\ 'cwd': function('ale#handlers#elixir#FindMixUmbrellaRoot'),
\ 'command': function('ale_linters#elixir#credo#GetCommand'), \ 'command': function('ale_linters#elixir#credo#GetCommand'),
\ 'callback': 'ale_linters#elixir#credo#Handle', \ 'callback': 'ale_linters#elixir#credo#Handle',
\}) \})

View File

@ -25,17 +25,10 @@ function! ale_linters#elixir#dialyxir#Handle(buffer, lines) abort
return l:output return l:output
endfunction endfunction
function! ale_linters#elixir#dialyxir#GetCommand(buffer) abort
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
return ale#path#CdString(l:project_root)
\ . ' mix help dialyzer && mix dialyzer'
endfunction
call ale#linter#Define('elixir', { call ale#linter#Define('elixir', {
\ 'name': 'dialyxir', \ 'name': 'dialyxir',
\ 'executable': 'mix', \ 'executable': 'mix',
\ 'command': function('ale_linters#elixir#dialyxir#GetCommand'), \ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'),
\ 'command': 'mix help dialyzer && mix dialyzer',
\ 'callback': 'ale_linters#elixir#dialyxir#Handle', \ 'callback': 'ale_linters#elixir#dialyxir#Handle',
\}) \})

View File

@ -29,17 +29,11 @@ function! ale_linters#elixir#dogma#Handle(buffer, lines) abort
return l:output return l:output
endfunction endfunction
function! ale_linters#elixir#dogma#GetCommand(buffer) abort
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
return ale#path#CdString(l:project_root)
\ . ' mix help dogma && mix dogma %s --format=flycheck'
endfunction
call ale#linter#Define('elixir', { call ale#linter#Define('elixir', {
\ 'name': 'dogma', \ 'name': 'dogma',
\ 'executable': 'mix', \ 'executable': 'mix',
\ 'command': function('ale_linters#elixir#dogma#GetCommand'), \ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'),
\ 'command': 'mix help dogma && mix dogma %s --format=flycheck',
\ 'lint_file': 1, \ 'lint_file': 1,
\ 'callback': 'ale_linters#elixir#dogma#Handle', \ 'callback': 'ale_linters#elixir#dogma#Handle',
\}) \})

View File

@ -30,22 +30,15 @@ function! ale_linters#elixir#mix#Handle(buffer, lines) abort
endfunction endfunction
function! ale_linters#elixir#mix#GetCommand(buffer) abort function! ale_linters#elixir#mix#GetCommand(buffer) abort
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
let l:temp_dir = ale#command#CreateDirectory(a:buffer) let l:temp_dir = ale#command#CreateDirectory(a:buffer)
let l:mix_build_path = has('win32') return ale#Env('MIX_BUILD_PATH', l:temp_dir) . 'mix compile %s'
\ ? 'set MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) . ' &&'
\ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir)
return ale#path#CdString(l:project_root)
\ . l:mix_build_path
\ . ' mix compile %s'
endfunction endfunction
call ale#linter#Define('elixir', { call ale#linter#Define('elixir', {
\ 'name': 'mix', \ 'name': 'mix',
\ 'executable': 'mix', \ 'executable': 'mix',
\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'),
\ 'command': function('ale_linters#elixir#mix#GetCommand'), \ 'command': function('ale_linters#elixir#mix#GetCommand'),
\ 'callback': 'ale_linters#elixir#mix#Handle', \ 'callback': 'ale_linters#elixir#mix#Handle',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -186,20 +186,19 @@ function! ale_linters#elm#make#IsTest(buffer) abort
endif endif
endfunction endfunction
function! ale_linters#elm#make#GetCwd(buffer) abort
let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer)
return !empty(l:root_dir) ? l:root_dir : ''
endfunction
" Return the command to execute the linter in the projects directory. " Return the command to execute the linter in the projects directory.
" If it doesn't, then this will fail when imports are needed. " If it doesn't, then this will fail when imports are needed.
function! ale_linters#elm#make#GetCommand(buffer) abort function! ale_linters#elm#make#GetCommand(buffer) abort
let l:executable = ale_linters#elm#make#GetExecutable(a:buffer) let l:executable = ale_linters#elm#make#GetExecutable(a:buffer)
let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer)
let l:is_v19 = ale_linters#elm#make#IsVersionGte19(a:buffer) let l:is_v19 = ale_linters#elm#make#IsVersionGte19(a:buffer)
let l:is_using_elm_test = l:executable =~# 'elm-test$' let l:is_using_elm_test = l:executable =~# 'elm-test$'
if empty(l:root_dir)
let l:dir_set_cmd = ''
else
let l:dir_set_cmd = 'cd ' . ale#Escape(l:root_dir) . ' && '
endif
" elm-test needs to know the path of elm-make if elm isn't installed globally. " elm-test needs to know the path of elm-make if elm isn't installed globally.
" https://github.com/rtfeldman/node-test-runner/blob/57728f10668f2d2ab3179e7e3208bcfa9a1f19aa/README.md#--compiler " https://github.com/rtfeldman/node-test-runner/blob/57728f10668f2d2ab3179e7e3208bcfa9a1f19aa/README.md#--compiler
if l:is_v19 && l:is_using_elm_test if l:is_v19 && l:is_using_elm_test
@ -213,7 +212,9 @@ function! ale_linters#elm#make#GetCommand(buffer) abort
" a sort of flag to tell the compiler not to generate an output file, " a sort of flag to tell the compiler not to generate an output file,
" which is why this is hard coded here. " which is why this is hard coded here.
" Source: https://github.com/elm-lang/elm-compiler/blob/19d5a769b30ec0b2fc4475985abb4cd94cd1d6c3/builder/src/Generate/Output.hs#L253 " Source: https://github.com/elm-lang/elm-compiler/blob/19d5a769b30ec0b2fc4475985abb4cd94cd1d6c3/builder/src/Generate/Output.hs#L253
return l:dir_set_cmd . '%e make --report=json --output=/dev/null' . l:elm_test_compiler_flag . '%t' return '%e make --report=json --output=/dev/null'
\ . l:elm_test_compiler_flag
\ . '%t'
endfunction endfunction
function! ale_linters#elm#make#GetExecutable(buffer) abort function! ale_linters#elm#make#GetExecutable(buffer) abort
@ -235,6 +236,7 @@ call ale#linter#Define('elm', {
\ 'name': 'make', \ 'name': 'make',
\ 'executable': function('ale_linters#elm#make#GetExecutable'), \ 'executable': function('ale_linters#elm#make#GetExecutable'),
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'cwd': function('ale_linters#elm#make#GetCwd'),
\ 'command': function('ale_linters#elm#make#GetCommand'), \ 'command': function('ale_linters#elm#make#GetCommand'),
\ 'callback': 'ale_linters#elm#make#Handle' \ 'callback': 'ale_linters#elm#make#Handle'
\}) \})

View File

@ -10,8 +10,7 @@ function! ale_linters#go#gobuild#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_gobuild_options') let l:options = ale#Var(a:buffer, 'go_gobuild_options')
" Run go test in local directory with relative path " Run go test in local directory with relative path
return ale#path#BufferCdString(a:buffer) return ale#go#EnvString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . ale#Var(a:buffer, 'go_go_executable') . ' test' \ . ale#Var(a:buffer, 'go_go_executable') . ' test'
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -c -o /dev/null ./' \ . ' -c -o /dev/null ./'
@ -50,6 +49,7 @@ call ale#linter#Define('go', {
\ 'name': 'gobuild', \ 'name': 'gobuild',
\ 'aliases': ['go build'], \ 'aliases': ['go build'],
\ 'executable': {b -> ale#Var(b, 'go_go_executable')}, \ 'executable': {b -> ale#Var(b, 'go_go_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#gobuild#GetCommand'), \ 'command': function('ale_linters#go#gobuild#GetCommand'),
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'callback': 'ale_linters#go#gobuild#Handler', \ 'callback': 'ale_linters#go#gobuild#Handler',

View File

@ -12,14 +12,12 @@ function! ale_linters#go#golangci_lint#GetCommand(buffer) abort
if l:lint_package if l:lint_package
return ale#path#BufferCdString(a:buffer) return ale#go#EnvString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . '%e run ' \ . '%e run '
\ . l:options \ . l:options
endif endif
return ale#path#BufferCdString(a:buffer) return ale#go#EnvString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . '%e run ' \ . '%e run '
\ . ale#Escape(l:filename) \ . ale#Escape(l:filename)
\ . ' ' . l:options \ . ' ' . l:options
@ -53,6 +51,7 @@ endfunction
call ale#linter#Define('go', { call ale#linter#Define('go', {
\ 'name': 'golangci-lint', \ 'name': 'golangci-lint',
\ 'executable': {b -> ale#Var(b, 'go_golangci_lint_executable')}, \ 'executable': {b -> ale#Var(b, 'go_golangci_lint_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#golangci_lint#GetCommand'), \ 'command': function('ale_linters#go#golangci_lint#GetCommand'),
\ 'callback': 'ale_linters#go#golangci_lint#Handler', \ 'callback': 'ale_linters#go#golangci_lint#Handler',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -13,14 +13,12 @@ function! ale_linters#go#gometalinter#GetCommand(buffer) abort
" BufferCdString is used so that we can be sure the paths output from gometalinter can " BufferCdString is used so that we can be sure the paths output from gometalinter can
" be calculated to absolute paths in the Handler " be calculated to absolute paths in the Handler
if l:lint_package if l:lint_package
return ale#path#BufferCdString(a:buffer) return ale#go#EnvString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . '%e' \ . '%e'
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .' \ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif endif
return ale#path#BufferCdString(a:buffer) return ale#go#EnvString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . '%e' \ . '%e'
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename)) \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename))
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .' \ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
@ -53,6 +51,7 @@ endfunction
call ale#linter#Define('go', { call ale#linter#Define('go', {
\ 'name': 'gometalinter', \ 'name': 'gometalinter',
\ 'executable': {b -> ale#Var(b, 'go_gometalinter_executable')}, \ 'executable': {b -> ale#Var(b, 'go_gometalinter_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#gometalinter#GetCommand'), \ 'command': function('ale_linters#go#gometalinter#GetCommand'),
\ 'callback': 'ale_linters#go#gometalinter#Handler', \ 'callback': 'ale_linters#go#gometalinter#Handler',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -1,15 +1,11 @@
" Author: Ben Reedy <https://github.com/breed808> " Author: Ben Reedy <https://github.com/breed808>
" Description: gosimple for Go files " Description: gosimple for Go files
function! ale_linters#go#gosimple#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer) . ' '
\ . ale#go#EnvString(a:buffer) . 'gosimple .'
endfunction
call ale#linter#Define('go', { call ale#linter#Define('go', {
\ 'name': 'gosimple', \ 'name': 'gosimple',
\ 'executable': 'gosimple', \ 'executable': 'gosimple',
\ 'command': function('ale_linters#go#gosimple#GetCommand'), \ 'cwd': '%s:h',
\ 'command': {b -> ale#go#EnvString(b) . 'gosimple .'},
\ 'callback': 'ale#handlers#go#Handler', \ 'callback': 'ale#handlers#go#Handler',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -1,19 +1,23 @@
" Author: Jelte Fennema <github-public@jeltef.nl> " Author: Jelte Fennema <github-public@jeltef.nl>
" Description: gotype for Go files " Description: gotype for Go files
function! ale_linters#go#gotype#GetCommand(buffer) abort function! ale_linters#go#gotype#GetExecutable(buffer) abort
if expand('#' . a:buffer . ':p') =~# '_test\.go$' if expand('#' . a:buffer . ':p') =~# '_test\.go$'
return '' return ''
endif endif
return ale#path#BufferCdString(a:buffer) . ' ' return 'gotype'
\ . ale#go#EnvString(a:buffer) . 'gotype -e .' endfunction
function! ale_linters#go#gotype#GetCommand(buffer) abort
return ale#go#EnvString(a:buffer) . 'gotype -e .'
endfunction endfunction
call ale#linter#Define('go', { call ale#linter#Define('go', {
\ 'name': 'gotype', \ 'name': 'gotype',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': 'gotype', \ 'executable': function('ale_linters#go#gotype#GetExecutable'),
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#gotype#GetCommand'), \ 'command': function('ale_linters#go#gotype#GetCommand'),
\ 'callback': 'ale#handlers#go#Handler', \ 'callback': 'ale#handlers#go#Handler',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -10,8 +10,7 @@ call ale#Set('go_govet_options', '')
function! ale_linters#go#govet#GetCommand(buffer) abort function! ale_linters#go#govet#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_govet_options') let l:options = ale#Var(a:buffer, 'go_govet_options')
return ale#path#BufferCdString(a:buffer) . ' ' return ale#go#EnvString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . ale#Var(a:buffer, 'go_go_executable') . ' vet ' \ . ale#Var(a:buffer, 'go_go_executable') . ' vet '
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' .' \ . ' .'
@ -22,6 +21,7 @@ call ale#linter#Define('go', {
\ 'aliases': ['go vet'], \ 'aliases': ['go vet'],
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'go_go_executable')}, \ 'executable': {b -> ale#Var(b, 'go_go_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#govet#GetCommand'), \ 'command': function('ale_linters#go#govet#GetCommand'),
\ 'callback': 'ale#handlers#go#Handler', \ 'callback': 'ale#handlers#go#Handler',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -5,28 +5,24 @@ call ale#Set('go_staticcheck_options', '')
call ale#Set('go_staticcheck_lint_package', 0) call ale#Set('go_staticcheck_lint_package', 0)
function! ale_linters#go#staticcheck#GetCommand(buffer) abort function! ale_linters#go#staticcheck#GetCommand(buffer) abort
let l:filename = expand('#' . a:buffer . ':t')
let l:options = ale#Var(a:buffer, 'go_staticcheck_options') let l:options = ale#Var(a:buffer, 'go_staticcheck_options')
let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package') let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package')
let l:env = ale#go#EnvString(a:buffer) let l:env = ale#go#EnvString(a:buffer)
" BufferCdString is used so that we can be sure the paths output from
" staticcheck can be calculated to absolute paths in the Handler
if l:lint_package if l:lint_package
return ale#path#BufferCdString(a:buffer) return l:env . 'staticcheck'
\ . l:env . 'staticcheck'
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .' \ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif endif
return ale#path#BufferCdString(a:buffer) return l:env . 'staticcheck'
\ . l:env . 'staticcheck'
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' ' . ale#Escape(l:filename) \ . ' %s:t'
endfunction endfunction
call ale#linter#Define('go', { call ale#linter#Define('go', {
\ 'name': 'staticcheck', \ 'name': 'staticcheck',
\ 'executable': 'staticcheck', \ 'executable': 'staticcheck',
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#staticcheck#GetCommand'), \ 'command': function('ale_linters#go#staticcheck#GetCommand'),
\ 'callback': 'ale#handlers#go#Handler', \ 'callback': 'ale#handlers#go#Handler',
\ 'output_stream': 'both', \ 'output_stream': 'both',

View File

@ -4,6 +4,7 @@
call ale#linter#Define('graphql', { call ale#linter#Define('graphql', {
\ 'name': 'eslint', \ 'name': 'eslint',
\ 'executable': function('ale#handlers#eslint#GetExecutable'), \ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'cwd': function('ale#handlers#eslint#GetCwd'),
\ 'command': function('ale#handlers#eslint#GetCommand'), \ 'command': function('ale#handlers#eslint#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON', \ 'callback': 'ale#handlers#eslint#HandleJSON',
\}) \})

View File

@ -1,15 +1,10 @@
" Author: Michiel Westerbeek <happylinks@gmail.com> " Author: Michiel Westerbeek <happylinks@gmail.com>
" Description: Linter for GraphQL Schemas " Description: Linter for GraphQL Schemas
function! ale_linters#graphql#gqlint#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer)
\ . 'gqlint'
\ . ' --reporter=simple %t'
endfunction
call ale#linter#Define('graphql', { call ale#linter#Define('graphql', {
\ 'name': 'gqlint', \ 'name': 'gqlint',
\ 'executable': 'gqlint', \ 'executable': 'gqlint',
\ 'command': function('ale_linters#graphql#gqlint#GetCommand'), \ 'cwd': '%s:h',
\ 'command': 'gqlint --reporter=simple %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@ -4,8 +4,7 @@
call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0') call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0')
function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer) return 'cabal exec -- ghc '
\ . 'cabal exec -- ghc '
\ . ale#Var(a:buffer, 'haskell_cabal_ghc_options') \ . ale#Var(a:buffer, 'haskell_cabal_ghc_options')
\ . ' %t' \ . ' %t'
endfunction endfunction
@ -15,6 +14,7 @@ call ale#linter#Define('haskell', {
\ 'aliases': ['cabal-ghc'], \ 'aliases': ['cabal-ghc'],
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': 'cabal', \ 'executable': 'cabal',
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#haskell#cabal_ghc#GetCommand'), \ 'command': function('ale_linters#haskell#cabal_ghc#GetCommand'),
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\}) \})

View File

@ -4,8 +4,7 @@
call ale#Set('haskell_stack_ghc_options', '-fno-code -v0') call ale#Set('haskell_stack_ghc_options', '-fno-code -v0')
function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer) return ale#handlers#haskell#GetStackExecutable(a:buffer)
\ . ale#handlers#haskell#GetStackExecutable(a:buffer)
\ . ' ghc -- ' \ . ' ghc -- '
\ . ale#Var(a:buffer, 'haskell_stack_ghc_options') \ . ale#Var(a:buffer, 'haskell_stack_ghc_options')
\ . ' %t' \ . ' %t'
@ -16,6 +15,7 @@ call ale#linter#Define('haskell', {
\ 'aliases': ['stack-ghc'], \ 'aliases': ['stack-ghc'],
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': function('ale#handlers#haskell#GetStackExecutable'), \ 'executable': function('ale#handlers#haskell#GetStackExecutable'),
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#haskell#stack_ghc#GetCommand'), \ 'command': function('ale_linters#haskell#stack_ghc#GetCommand'),
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\}) \})

View File

@ -9,16 +9,16 @@ call ale#Set('java_javac_classpath', '')
call ale#Set('java_javac_sourcepath', '') call ale#Set('java_javac_sourcepath', '')
function! ale_linters#java#javac#RunWithImportPaths(buffer) abort function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
let l:command = ale#maven#BuildClasspathCommand(a:buffer) let [l:cwd, l:command] = ale#maven#BuildClasspathCommand(a:buffer)
" Try to use Gradle if Maven isn't available. " Try to use Gradle if Maven isn't available.
if empty(l:command) if empty(l:command)
let l:command = ale#gradle#BuildClasspathCommand(a:buffer) let [l:cwd, l:command] = ale#gradle#BuildClasspathCommand(a:buffer)
endif endif
" Try to use Ant if Gradle and Maven aren't available " Try to use Ant if Gradle and Maven aren't available
if empty(l:command) if empty(l:command)
let l:command = ale#ant#BuildClasspathCommand(a:buffer) let [l:cwd, l:command] = ale#ant#BuildClasspathCommand(a:buffer)
endif endif
if empty(l:command) if empty(l:command)
@ -28,7 +28,8 @@ function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
return ale#command#Run( return ale#command#Run(
\ a:buffer, \ a:buffer,
\ l:command, \ l:command,
\ function('ale_linters#java#javac#GetCommand') \ function('ale_linters#java#javac#GetCommand'),
\ {'cwd': l:cwd},
\) \)
endfunction endfunction
@ -110,8 +111,7 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths, meta) abort
" Always run javac from the directory the file is in, so we can resolve " Always run javac from the directory the file is in, so we can resolve
" relative paths correctly. " relative paths correctly.
return ale#path#BufferCdString(a:buffer) return '%e -Xlint'
\ . '%e -Xlint'
\ . ale#Pad(l:cp_option) \ . ale#Pad(l:cp_option)
\ . ale#Pad(l:sp_option) \ . ale#Pad(l:sp_option)
\ . ' -d ' . ale#Escape(l:class_file_directory) \ . ' -d ' . ale#Escape(l:class_file_directory)
@ -154,6 +154,7 @@ endfunction
call ale#linter#Define('java', { call ale#linter#Define('java', {
\ 'name': 'javac', \ 'name': 'javac',
\ 'executable': {b -> ale#Var(b, 'java_javac_executable')}, \ 'executable': {b -> ale#Var(b, 'java_javac_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#java#javac#RunWithImportPaths'), \ 'command': function('ale_linters#java#javac#RunWithImportPaths'),
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'callback': 'ale_linters#java#javac#Handle', \ 'callback': 'ale_linters#java#javac#Handle',

View File

@ -5,6 +5,7 @@ call ale#linter#Define('javascript', {
\ 'name': 'eslint', \ 'name': 'eslint',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'executable': function('ale#handlers#eslint#GetExecutable'), \ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'cwd': function('ale#handlers#eslint#GetCwd'),
\ 'command': function('ale#handlers#eslint#GetCommand'), \ 'command': function('ale#handlers#eslint#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON', \ 'callback': 'ale#handlers#eslint#HandleJSON',
\}) \})

View File

@ -15,20 +15,15 @@ function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort
let l:command = '' let l:command = ''
" exec maven/gradle only if classpath is not set " exec maven/gradle only if classpath is not set
if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# '' if !empty(ale#Var(a:buffer, 'kotlin_kotlinc_classpath'))
return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {}) return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {})
endif endif
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') let [l:cwd, l:command] = ale#maven#BuildClasspathCommand(a:buffer)
if !empty(l:pom_path) && executable('mvn')
let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath'
endif
" Try to use Gradle if Maven isn't available. " Try to use Gradle if Maven isn't available.
if empty(l:command) if empty(l:command)
let l:command = ale#gradle#BuildClasspathCommand(a:buffer) let [l:cwd, l:command] = ale#gradle#BuildClasspathCommand(a:buffer)
endif endif
if empty(l:command) if empty(l:command)
@ -38,7 +33,8 @@ function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort
return ale#command#Run( return ale#command#Run(
\ a:buffer, \ a:buffer,
\ l:command, \ l:command,
\ function('ale_linters#kotlin#kotlinc#GetCommand') \ function('ale_linters#kotlin#kotlinc#GetCommand'),
\ {'cwd': l:cwd},
\) \)
endfunction endfunction

View File

@ -5,12 +5,9 @@ call ale#Set('mercury_mmc_executable', 'mmc')
call ale#Set('mercury_mmc_options', '--make --output-compile-error-lines 100') call ale#Set('mercury_mmc_options', '--make --output-compile-error-lines 100')
function! ale_linters#mercury#mmc#GetCommand(buffer) abort function! ale_linters#mercury#mmc#GetCommand(buffer) abort
let l:module_name = expand('#' . a:buffer . ':t:r') return '%e --errorcheck-only '
return ale#path#BufferCdString(a:buffer)
\ . '%e --errorcheck-only '
\ . ale#Var(a:buffer, 'mercury_mmc_options') \ . ale#Var(a:buffer, 'mercury_mmc_options')
\ . ' ' . l:module_name \ . ' %s:t:r'
endfunction endfunction
function! ale_linters#mercury#mmc#Handle(buffer, lines) abort function! ale_linters#mercury#mmc#Handle(buffer, lines) abort
@ -34,6 +31,7 @@ call ale#linter#Define('mercury', {
\ 'name': 'mmc', \ 'name': 'mmc',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'mercury_mmc_executable')}, \ 'executable': {b -> ale#Var(b, 'mercury_mmc_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#mercury#mmc#GetCommand'), \ 'command': function('ale_linters#mercury#mmc#GetCommand'),
\ 'callback': 'ale_linters#mercury#mmc#Handle', \ 'callback': 'ale_linters#mercury#mmc#Handle',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -13,8 +13,7 @@ function! ale_linters#php#phpcs#GetCommand(buffer) abort
\ ? '--standard=' . ale#Escape(l:standard) \ ? '--standard=' . ale#Escape(l:standard)
\ : '' \ : ''
return ale#path#BufferCdString(a:buffer) return '%e -s --report=emacs --stdin-path=%s'
\ . '%e -s --report=emacs --stdin-path=%s'
\ . ale#Pad(l:standard_option) \ . ale#Pad(l:standard_option)
\ . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options')) \ . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options'))
endfunction endfunction
@ -49,6 +48,7 @@ call ale#linter#Define('php', {
\ 'vendor/bin/phpcs', \ 'vendor/bin/phpcs',
\ 'phpcs' \ 'phpcs'
\ ])}, \ ])},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#php#phpcs#GetCommand'), \ 'command': function('ale_linters#php#phpcs#GetCommand'),
\ 'callback': 'ale_linters#php#phpcs#Handle', \ 'callback': 'ale_linters#php#phpcs#Handle',
\}) \})

View File

@ -38,30 +38,28 @@ function! ale_linters#python#flake8#RunWithVersionCheck(buffer) abort
\) \)
endfunction endfunction
function! ale_linters#python#flake8#GetCdString(buffer) abort function! ale_linters#python#flake8#GetCwd(buffer) abort
let l:change_directory = ale#Var(a:buffer, 'python_flake8_change_directory') let l:change_directory = ale#Var(a:buffer, 'python_flake8_change_directory')
let l:cd_string = '' let l:cwd = ''
if l:change_directory is# 'project' if l:change_directory is# 'project'
let l:project_root = ale#python#FindProjectRootIni(a:buffer) let l:project_root = ale#python#FindProjectRootIni(a:buffer)
if !empty(l:project_root) if !empty(l:project_root)
let l:cd_string = ale#path#CdString(l:project_root) let l:cwd = l:project_root
endif endif
endif endif
if (l:change_directory is# 'project' && empty(l:cd_string)) if (l:change_directory is# 'project' && empty(l:cwd))
\|| l:change_directory is# 1 \|| l:change_directory is# 1
\|| l:change_directory is# 'file' \|| l:change_directory is# 'file'
let l:cd_string = ale#path#BufferCdString(a:buffer) let l:cwd = '%s:h'
endif endif
return l:cd_string return l:cwd
endfunction endfunction
function! ale_linters#python#flake8#GetCommand(buffer, version) abort function! ale_linters#python#flake8#GetCommand(buffer, version) abort
let l:cd_string = ale_linters#python#flake8#GetCdString(a:buffer)
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
@ -76,8 +74,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version) abort
let l:options = ale#Var(a:buffer, 'python_flake8_options') let l:options = ale#Var(a:buffer, 'python_flake8_options')
return l:cd_string return ale#Escape(l:executable) . l:exec_args
\ . ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --format=default' \ . ' --format=default'
\ . l:display_name_args . ' -' \ . l:display_name_args . ' -'
@ -161,6 +158,7 @@ endfunction
call ale#linter#Define('python', { call ale#linter#Define('python', {
\ 'name': 'flake8', \ 'name': 'flake8',
\ 'executable': function('ale_linters#python#flake8#GetExecutable'), \ 'executable': function('ale_linters#python#flake8#GetExecutable'),
\ 'cwd': function('ale_linters#python#flake8#GetCwd'),
\ 'command': function('ale_linters#python#flake8#RunWithVersionCheck'), \ 'command': function('ale_linters#python#flake8#RunWithVersionCheck'),
\ 'callback': 'ale_linters#python#flake8#Handle', \ 'callback': 'ale_linters#python#flake8#Handle',
\}) \})

View File

@ -18,7 +18,7 @@ function! ale_linters#python#mypy#GetExecutable(buffer) abort
endfunction endfunction
" The directory to change to before running mypy " The directory to change to before running mypy
function! s:GetDir(buffer) abort function! ale_linters#python#mypy#GetCwd(buffer) abort
" If we find a directory with "mypy.ini" in it use that, " If we find a directory with "mypy.ini" in it use that,
" else try and find the "python project" root, or failing " else try and find the "python project" root, or failing
" that, run from the same folder as the current file " that, run from the same folder as the current file
@ -36,26 +36,19 @@ function! s:GetDir(buffer) abort
endfunction endfunction
function! ale_linters#python#mypy#GetCommand(buffer) abort function! ale_linters#python#mypy#GetCommand(buffer) abort
let l:dir = s:GetDir(a:buffer)
let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer) let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run mypy' \ ? ' run mypy'
\ : '' \ : ''
let l:options = ale#Var(a:buffer, 'python_mypy_options') return '%e' . l:exec_args
\ . ale#Pad(ale#Var(a:buffer, 'python_mypy_options'))
" We have to always switch to an explicit directory for a command so
" we can know with certainty the base path for the 'filename' keys below.
return ale#path#CdString(l:dir)
\ . ale#Escape(l:executable) . l:exec_args
\ . (len(l:options) ? (' ' . l:options) : '')
\ . ' --show-column-numbers' \ . ' --show-column-numbers'
\ . ' --shadow-file %s %t %s' \ . ' --shadow-file %s %t %s'
endfunction endfunction
function! ale_linters#python#mypy#Handle(buffer, lines) abort function! ale_linters#python#mypy#Handle(buffer, lines) abort
let l:dir = s:GetDir(a:buffer) let l:dir = ale_linters#python#mypy#GetCwd(a:buffer)
" Look for lines like the following: " Look for lines like the following:
" "
" file.py:4: error: No library stub file for module 'django.db' " file.py:4: error: No library stub file for module 'django.db'
@ -97,6 +90,7 @@ endfunction
call ale#linter#Define('python', { call ale#linter#Define('python', {
\ 'name': 'mypy', \ 'name': 'mypy',
\ 'executable': function('ale_linters#python#mypy#GetExecutable'), \ 'executable': function('ale_linters#python#mypy#GetExecutable'),
\ 'cwd': function('ale_linters#python#mypy#GetCwd'),
\ 'command': function('ale_linters#python#mypy#GetCommand'), \ 'command': function('ale_linters#python#mypy#GetCommand'),
\ 'callback': 'ale_linters#python#mypy#Handle', \ 'callback': 'ale_linters#python#mypy#Handle',
\ 'output_stream': 'both' \ 'output_stream': 'both'

View File

@ -21,8 +21,7 @@ function! ale_linters#python#pydocstyle#GetCommand(buffer) abort
\ ? ' run pydocstyle' \ ? ' run pydocstyle'
\ : '' \ : ''
return ale#path#BufferCdString(a:buffer) return ale#Escape(l:executable) . l:exec_args
\ . ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(ale#Var(a:buffer, 'python_pydocstyle_options')) \ . ale#Pad(ale#Var(a:buffer, 'python_pydocstyle_options'))
\ . ' %s:t' \ . ' %s:t'
endfunction endfunction
@ -66,6 +65,7 @@ endfunction
call ale#linter#Define('python', { call ale#linter#Define('python', {
\ 'name': 'pydocstyle', \ 'name': 'pydocstyle',
\ 'executable': function('ale_linters#python#pydocstyle#GetExecutable'), \ 'executable': function('ale_linters#python#pydocstyle#GetExecutable'),
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#python#pydocstyle#GetCommand'), \ 'command': function('ale_linters#python#pydocstyle#GetCommand'),
\ 'callback': 'ale_linters#python#pydocstyle#Handle', \ 'callback': 'ale_linters#python#pydocstyle#Handle',
\}) \})

View File

@ -16,19 +16,20 @@ function! ale_linters#python#pylama#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama']) return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama'])
endfunction endfunction
function! ale_linters#python#pylama#GetCommand(buffer) abort function! ale_linters#python#pylama#GetCwd(buffer) abort
let l:cd_string = ''
if ale#Var(a:buffer, 'python_pylama_change_directory') if ale#Var(a:buffer, 'python_pylama_change_directory')
" Pylama loads its configuration from the current directory only, and " Pylama loads its configuration from the current directory only, and
" applies file masks using paths relative to the current directory. " applies file masks using paths relative to the current directory.
" Run from project root, if found, otherwise buffer dir. " Run from project root, if found, otherwise buffer dir.
let l:project_root = ale#python#FindProjectRoot(a:buffer) let l:project_root = ale#python#FindProjectRoot(a:buffer)
let l:cd_string = l:project_root isnot# ''
\ ? ale#path#CdString(l:project_root) return !empty(l:project_root) ? l:project_root : '%s:h'
\ : ale#path#BufferCdString(a:buffer)
endif endif
return ''
endfunction
function! ale_linters#python#pylama#GetCommand(buffer) abort
let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer) let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run pylama' \ ? ' run pylama'
@ -37,8 +38,7 @@ function! ale_linters#python#pylama#GetCommand(buffer) abort
" Note: Using %t to lint changes would be preferable, but many pylama " Note: Using %t to lint changes would be preferable, but many pylama
" checks use surrounding paths (e.g. C0103 module name, E0402 relative " checks use surrounding paths (e.g. C0103 module name, E0402 relative
" import beyond top, etc.). Neither is ideal. " import beyond top, etc.). Neither is ideal.
return l:cd_string return ale#Escape(l:executable) . l:exec_args
\ . ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(ale#Var(a:buffer, 'python_pylama_options')) \ . ale#Pad(ale#Var(a:buffer, 'python_pylama_options'))
\ . ' %s' \ . ' %s'
endfunction endfunction
@ -86,6 +86,7 @@ endfunction
call ale#linter#Define('python', { call ale#linter#Define('python', {
\ 'name': 'pylama', \ 'name': 'pylama',
\ 'executable': function('ale_linters#python#pylama#GetExecutable'), \ 'executable': function('ale_linters#python#pylama#GetExecutable'),
\ 'cwd': function('ale_linters#python#pylama#GetCwd'),
\ 'command': function('ale_linters#python#pylama#GetCommand'), \ 'command': function('ale_linters#python#pylama#GetCommand'),
\ 'callback': 'ale_linters#python#pylama#Handle', \ 'callback': 'ale_linters#python#pylama#Handle',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -17,27 +17,26 @@ function! ale_linters#python#pylint#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint']) return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint'])
endfunction endfunction
function! ale_linters#python#pylint#GetCommand(buffer, version) abort function! ale_linters#python#pylint#GetCwd(buffer) abort
let l:cd_string = ''
if ale#Var(a:buffer, 'python_pylint_change_directory') if ale#Var(a:buffer, 'python_pylint_change_directory')
" pylint only checks for pylintrc in the packages above its current " pylint only checks for pylintrc in the packages above its current
" directory before falling back to user and global pylintrc. " directory before falling back to user and global pylintrc.
" Run from project root, if found, otherwise buffer dir. " Run from project root, if found, otherwise buffer dir.
let l:project_root = ale#python#FindProjectRoot(a:buffer) let l:project_root = ale#python#FindProjectRoot(a:buffer)
let l:cd_string = l:project_root isnot# ''
\ ? ale#path#CdString(l:project_root) return !empty(l:project_root) ? l:project_root : '%s:h'
\ : ale#path#BufferCdString(a:buffer)
endif endif
let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer) return ''
endfunction
function! ale_linters#python#pylint#GetCommand(buffer, version) abort
let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run pylint' \ ? ' run pylint'
\ : '' \ : ''
return l:cd_string return ale#Escape(l:executable) . l:exec_args
\ . ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(ale#Var(a:buffer, 'python_pylint_options')) \ . ale#Pad(ale#Var(a:buffer, 'python_pylint_options'))
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n' \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n'
\ . (ale#semver#GTE(a:version, [2, 4, 0]) ? ' --from-stdin' : '') \ . (ale#semver#GTE(a:version, [2, 4, 0]) ? ' --from-stdin' : '')
@ -104,6 +103,7 @@ call ale#linter#Define('python', {
\ '%e --version', \ '%e --version',
\ {buffer, version -> !ale#semver#GTE(version, [2, 4, 0])}, \ {buffer, version -> !ale#semver#GTE(version, [2, 4, 0])},
\ )}, \ )},
\ 'cwd': function('ale_linters#python#pylint#GetCwd'),
\ 'command': {buffer -> ale#semver#RunWithVersionCheck( \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ buffer, \ buffer,
\ ale#Var(buffer, 'python_pylint_executable'), \ ale#Var(buffer, 'python_pylint_executable'),

View File

@ -6,7 +6,6 @@ call ale#Set('python_vulture_options', '')
call ale#Set('python_vulture_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_vulture_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_vulture_change_directory', 1) call ale#Set('python_vulture_change_directory', 1)
" The directory to change to before running vulture " The directory to change to before running vulture
function! s:GetDir(buffer) abort function! s:GetDir(buffer) abort
let l:project_root = ale#python#FindProjectRoot(a:buffer) let l:project_root = ale#python#FindProjectRoot(a:buffer)
@ -16,29 +15,28 @@ function! s:GetDir(buffer) abort
\ : expand('#' . a:buffer . ':p:h') \ : expand('#' . a:buffer . ':p:h')
endfunction endfunction
function! ale_linters#python#vulture#GetExecutable(buffer) abort function! ale_linters#python#vulture#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_vulture', ['vulture']) return ale#python#FindExecutable(a:buffer, 'python_vulture', ['vulture'])
endfunction endfunction
function! ale_linters#python#vulture#GetCwd(buffer) abort
if !ale#Var(a:buffer, 'python_vulture_change_directory')
return ''
endif
return s:GetDir(a:buffer)
endfunction
function! ale_linters#python#vulture#GetCommand(buffer) abort function! ale_linters#python#vulture#GetCommand(buffer) abort
let l:change_dir = ale#Var(a:buffer, 'python_vulture_change_directory')
\ ? ale#path#CdString(s:GetDir(a:buffer))
\ : ''
let l:executable = ale_linters#python#vulture#GetExecutable(a:buffer) let l:executable = ale_linters#python#vulture#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run vulture' \ ? ' run vulture'
\ : '' \ : ''
let l:lint_dest = ale#Var(a:buffer, 'python_vulture_change_directory') let l:lint_dest = ale#Var(a:buffer, 'python_vulture_change_directory')
\ ? ' .' \ ? ' .'
\ : ' %s' \ : ' %s'
return l:change_dir return ale#Escape(l:executable) . l:exec_args
\ . ale#Escape(l:executable) . l:exec_args
\ . ' ' \ . ' '
\ . ale#Var(a:buffer, 'python_vulture_options') \ . ale#Var(a:buffer, 'python_vulture_options')
\ . l:lint_dest \ . l:lint_dest
@ -74,6 +72,7 @@ endfunction
call ale#linter#Define('python', { call ale#linter#Define('python', {
\ 'name': 'vulture', \ 'name': 'vulture',
\ 'executable': function('ale_linters#python#vulture#GetExecutable'), \ 'executable': function('ale_linters#python#vulture#GetExecutable'),
\ 'cwd': function('ale_linters#python#vulture#GetCwd'),
\ 'command': function('ale_linters#python#vulture#GetCommand'), \ 'command': function('ale_linters#python#vulture#GetCommand'),
\ 'callback': 'ale_linters#python#vulture#Handle', \ 'callback': 'ale_linters#python#vulture#Handle',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -21,14 +21,13 @@ function! ale_linters#r#lintr#GetCommand(buffer) abort
let l:cmd_string = 'suppressPackageStartupMessages(library(lintr));' let l:cmd_string = 'suppressPackageStartupMessages(library(lintr));'
\ . l:lint_cmd \ . l:lint_cmd
return ale#path#BufferCdString(a:buffer) return 'Rscript --vanilla -e ' . ale#Escape(l:cmd_string) . ' %t'
\ . 'Rscript --vanilla -e '
\ . ale#Escape(l:cmd_string) . ' %t'
endfunction endfunction
call ale#linter#Define('r', { call ale#linter#Define('r', {
\ 'name': 'lintr', \ 'name': 'lintr',
\ 'executable': 'Rscript', \ 'executable': 'Rscript',
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#r#lintr#GetCommand'), \ 'command': function('ale_linters#r#lintr#GetCommand'),
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'output_stream': 'both', \ 'output_stream': 'both',

View File

@ -1,6 +1,5 @@
" Author: John Nduli https://github.com/jnduli " Author: John Nduli https://github.com/jnduli
" Description: Rstcheck for reStructuredText files " Description: Rstcheck for reStructuredText files
"
function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort
" matches: 'bad_rst.rst:1: (SEVERE/4) Title overline & underline " matches: 'bad_rst.rst:1: (SEVERE/4) Title overline & underline
@ -22,17 +21,11 @@ function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort
return l:output return l:output
endfunction endfunction
function! ale_linters#rst#rstcheck#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer)
\ . 'rstcheck'
\ . ' %t'
endfunction
call ale#linter#Define('rst', { call ale#linter#Define('rst', {
\ 'name': 'rstcheck', \ 'name': 'rstcheck',
\ 'executable': 'rstcheck', \ 'executable': 'rstcheck',
\ 'command': function('ale_linters#rst#rstcheck#GetCommand'), \ 'cwd': '%s:h',
\ 'command': 'rstcheck %t',
\ 'callback': 'ale_linters#rst#rstcheck#Handle', \ 'callback': 'ale_linters#rst#rstcheck#Handle',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\}) \})

View File

@ -6,7 +6,7 @@ call ale#Set('ruby_ruby_executable', 'ruby')
call ale#linter#Define('ruby', { call ale#linter#Define('ruby', {
\ 'name': 'ruby', \ 'name': 'ruby',
\ 'executable': {b -> ale#Var(b, 'ruby_ruby_executable')}, \ 'executable': {b -> ale#Var(b, 'ruby_ruby_executable')},
\ 'command': '%e -w -c %t', \ 'command': '%e -w -c -T1 %t',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', \ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
\}) \})

View File

@ -23,6 +23,19 @@ function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
endif endif
endfunction endfunction
function! ale_linters#rust#cargo#GetCwd(buffer) abort
if ale#Var(a:buffer, 'rust_cargo_avoid_whole_workspace')
let l:nearest_cargo = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
let l:nearest_cargo_dir = fnamemodify(l:nearest_cargo, ':h')
if l:nearest_cargo_dir isnot# '.'
return l:nearest_cargo_dir
endif
endif
return ''
endfunction
function! ale_linters#rust#cargo#GetCommand(buffer, version) abort function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check') let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
\ && ale#semver#GTE(a:version, [0, 17, 0]) \ && ale#semver#GTE(a:version, [0, 17, 0])
@ -42,18 +55,6 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
let l:include_features = ' --features ' . ale#Escape(l:include_features) let l:include_features = ' --features ' . ale#Escape(l:include_features)
endif endif
let l:avoid_whole_workspace = ale#Var(a:buffer, 'rust_cargo_avoid_whole_workspace')
let l:nearest_cargo_prefix = ''
if l:avoid_whole_workspace
let l:nearest_cargo = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
let l:nearest_cargo_dir = fnamemodify(l:nearest_cargo, ':h')
if l:nearest_cargo_dir isnot# '.'
let l:nearest_cargo_prefix = 'cd '. ale#Escape(l:nearest_cargo_dir) .' && '
endif
endif
let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior') let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior')
if l:default_feature_behavior is# 'all' if l:default_feature_behavior is# 'all'
@ -81,7 +82,7 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
endif endif
endif endif
return l:nearest_cargo_prefix . 'cargo ' return 'cargo '
\ . l:subcommand \ . l:subcommand
\ . (l:use_all_targets ? ' --all-targets' : '') \ . (l:use_all_targets ? ' --all-targets' : '')
\ . (l:use_examples ? ' --examples' : '') \ . (l:use_examples ? ' --examples' : '')
@ -96,6 +97,7 @@ endfunction
call ale#linter#Define('rust', { call ale#linter#Define('rust', {
\ 'name': 'cargo', \ 'name': 'cargo',
\ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'), \ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'),
\ 'cwd': function('ale_linters#rust#cargo#GetCwd'),
\ 'command': {buffer -> ale#semver#RunWithVersionCheck( \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ buffer, \ buffer,
\ ale_linters#rust#cargo#GetCargoExecutable(buffer), \ ale_linters#rust#cargo#GetCargoExecutable(buffer),

View File

@ -4,6 +4,7 @@
call ale#linter#Define('typescript', { call ale#linter#Define('typescript', {
\ 'name': 'eslint', \ 'name': 'eslint',
\ 'executable': function('ale#handlers#eslint#GetExecutable'), \ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'cwd': function('ale#handlers#eslint#GetCwd'),
\ 'command': function('ale#handlers#eslint#GetCommand'), \ 'command': function('ale#handlers#eslint#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON', \ 'callback': 'ale#handlers#eslint#HandleJSON',
\}) \})

View File

@ -59,8 +59,7 @@ function! ale_linters#typescript#tslint#GetCommand(buffer) abort
\ ? ' -r ' . ale#Escape(l:tslint_rules_dir) \ ? ' -r ' . ale#Escape(l:tslint_rules_dir)
\ : '' \ : ''
return ale#path#BufferCdString(a:buffer) return ale#Escape(ale#handlers#tslint#GetExecutable(a:buffer))
\ . ale#Escape(ale#handlers#tslint#GetExecutable(a:buffer))
\ . ' --format json' \ . ' --format json'
\ . l:tslint_config_option \ . l:tslint_config_option
\ . l:tslint_rules_option \ . l:tslint_rules_option
@ -70,6 +69,7 @@ endfunction
call ale#linter#Define('typescript', { call ale#linter#Define('typescript', {
\ 'name': 'tslint', \ 'name': 'tslint',
\ 'executable': function('ale#handlers#tslint#GetExecutable'), \ 'executable': function('ale#handlers#tslint#GetExecutable'),
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#typescript#tslint#GetCommand'), \ 'command': function('ale_linters#typescript#tslint#GetCommand'),
\ 'callback': 'ale_linters#typescript#tslint#Handle', \ 'callback': 'ale_linters#typescript#tslint#Handle',
\}) \})

View File

@ -22,16 +22,20 @@ function! s:GetALEProjectDir(buffer) abort
return ale#path#Dirname(ale#path#Dirname(ale#path#Dirname(l:executable))) return ale#path#Dirname(ale#path#Dirname(ale#path#Dirname(l:executable)))
endfunction endfunction
function! ale_linters#vim#ale_custom_linting_rules#GetCommand(buffer) abort function! ale_linters#vim#ale_custom_linting_rules#GetCwd(buffer) abort
let l:dir = s:GetALEProjectDir(a:buffer) let l:executable = ale_linters#vim#ale_custom_linting_rules#GetExecutable(a:buffer)
return ale#path#Dirname(ale#path#Dirname(ale#path#Dirname(l:executable)))
endfunction
function! ale_linters#vim#ale_custom_linting_rules#GetCommand(buffer) abort
let l:temp_dir = ale#command#CreateDirectory(a:buffer) let l:temp_dir = ale#command#CreateDirectory(a:buffer)
let l:temp_file = l:temp_dir . '/example.vim' let l:temp_file = l:temp_dir . '/example.vim'
let l:lines = getbufline(a:buffer, 1, '$') let l:lines = getbufline(a:buffer, 1, '$')
call ale#util#Writefile(a:buffer, l:lines, l:temp_file) call ale#util#Writefile(a:buffer, l:lines, l:temp_file)
return ale#path#CdString(l:dir) . '%e ' . ale#Escape(l:temp_dir) return '%e ' . ale#Escape(l:temp_dir)
endfunction endfunction
function! ale_linters#vim#ale_custom_linting_rules#Handle(buffer, lines) abort function! ale_linters#vim#ale_custom_linting_rules#Handle(buffer, lines) abort
@ -59,6 +63,7 @@ endfunction
call ale#linter#Define('vim', { call ale#linter#Define('vim', {
\ 'name': 'ale_custom_linting_rules', \ 'name': 'ale_custom_linting_rules',
\ 'executable': function('ale_linters#vim#ale_custom_linting_rules#GetExecutable'), \ 'executable': function('ale_linters#vim#ale_custom_linting_rules#GetExecutable'),
\ 'cwd': function('ale_linters#vim#ale_custom_linting_rules#GetCwd'),
\ 'command': function('ale_linters#vim#ale_custom_linting_rules#GetCommand'), \ 'command': function('ale_linters#vim#ale_custom_linting_rules#GetCommand'),
\ 'callback': 'ale_linters#vim#ale_custom_linting_rules#Handle', \ 'callback': 'ale_linters#vim#ale_custom_linting_rules#Handle',
\ 'read_buffer': 0, \ 'read_buffer': 0,

View File

@ -23,19 +23,23 @@ function! ale#ant#FindExecutable(buffer) abort
return '' return ''
endfunction endfunction
" Given a buffer number, build a command to print the classpath of the root " Given a buffer number, get a working directory and command to print the
" project. Returns an empty string if cannot build the command. " classpath of the root project.
"
" Returns an empty string for the command if Ant is not detected.
function! ale#ant#BuildClasspathCommand(buffer) abort function! ale#ant#BuildClasspathCommand(buffer) abort
let l:executable = ale#ant#FindExecutable(a:buffer) let l:executable = ale#ant#FindExecutable(a:buffer)
let l:project_root = ale#ant#FindProjectRoot(a:buffer)
if !empty(l:executable) && !empty(l:project_root) if !empty(l:executable)
return ale#path#CdString(l:project_root) let l:project_root = ale#ant#FindProjectRoot(a:buffer)
\ . ale#Escape(l:executable)
\ . ' classpath' if !empty(l:project_root)
\ . ' -S' return [
\ . ' -q' \ l:project_root,
\ ale#Escape(l:executable) .' classpath -S -q'
\]
endif
endif endif
return '' return ['', '']
endfunction endfunction

View File

@ -52,6 +52,36 @@ function! s:ProcessDeferredCommands(initial_result) abort
return l:command return l:command
endfunction endfunction
function! s:ProcessDeferredCwds(initial_command, initial_cwd) abort
let l:result = a:initial_command
let l:last_cwd = v:null
let l:command_index = 0
let l:cwd_list = []
while ale#command#IsDeferred(l:result)
call add(l:cwd_list, l:result.cwd)
if get(g:, 'ale_run_synchronously_emulate_commands')
" Don't run commands, but simulate the results.
let l:Callback = g:ale_run_synchronously_callbacks[0]
let l:output = get(s:command_output, l:command_index, [])
call l:Callback(0, l:output)
unlet g:ale_run_synchronously_callbacks
let l:command_index += 1
else
" Run the commands in the shell, synchronously.
call ale#test#FlushJobs()
endif
let l:result = l:result.value
endwhile
call add(l:cwd_list, a:initial_cwd is v:null ? l:last_cwd : a:initial_cwd)
return l:cwd_list
endfunction
" Load the currently loaded linter for a test case, and check that the command " Load the currently loaded linter for a test case, and check that the command
" matches the given string. " matches the given string.
function! ale#assert#Linter(expected_executable, expected_command) abort function! ale#assert#Linter(expected_executable, expected_command) abort
@ -85,6 +115,38 @@ function! ale#assert#Linter(expected_executable, expected_command) abort
\ [l:executable, l:command] \ [l:executable, l:command]
endfunction endfunction
function! ale#assert#LinterCwd(expected_cwd) abort
let l:buffer = bufnr('')
let l:linter = s:GetLinter()
let l:initial_cwd = ale#linter#GetCwd(l:buffer, l:linter)
call ale#command#SetCwd(l:buffer, l:initial_cwd)
let l:cwd = s:ProcessDeferredCwds(
\ ale#linter#GetCommand(l:buffer, l:linter),
\ l:initial_cwd,
\)
call ale#command#ResetCwd(l:buffer)
if type(a:expected_cwd) isnot v:t_list
let l:cwd = l:cwd[-1]
endif
AssertEqual a:expected_cwd, l:cwd
endfunction
function! ale#assert#FixerCwd(expected_cwd) abort
let l:buffer = bufnr('')
let l:cwd = s:ProcessDeferredCwds(s:FixerFunction(l:buffer), v:null)
if type(a:expected_cwd) isnot v:t_list
let l:cwd = l:cwd[-1]
endif
AssertEqual a:expected_cwd, l:cwd
endfunction
function! ale#assert#Fixer(expected_result) abort function! ale#assert#Fixer(expected_result) abort
let l:buffer = bufnr('') let l:buffer = bufnr('')
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer)) let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))
@ -153,6 +215,7 @@ endfunction
function! ale#assert#SetUpLinterTestCommands() abort function! ale#assert#SetUpLinterTestCommands() abort
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>) command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
command! -nargs=+ AssertLinterCwd :call ale#assert#LinterCwd(<args>)
command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>) command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>)
command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted() command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted()
command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>) command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>)
@ -164,10 +227,35 @@ endfunction
function! ale#assert#SetUpFixerTestCommands() abort function! ale#assert#SetUpFixerTestCommands() abort
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>) command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
command! -nargs=+ AssertFixerCwd :call ale#assert#FixerCwd(<args>)
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>) command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted() command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted()
endfunction endfunction
function! ale#assert#ResetVariables(filetype, name, ...) abort
" If the suffix of the option names format is different, an additional
" argument can be used for that instead.
if a:0 > 1
throw 'Too many arguments'
endif
let l:option_suffix = get(a:000, 0, a:name)
let l:prefix = 'ale_' . a:filetype . '_'
\ . substitute(l:option_suffix, '-', '_', 'g')
let l:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
" Save and clear linter variables.
" We'll load the runtime file to reset them to defaults.
for l:key in filter(keys(g:), l:filter_expr)
execute 'Save g:' . l:key
unlet g:[l:key]
endfor
for l:key in filter(keys(b:), l:filter_expr)
unlet b:[l:key]
endfor
endfunction
" A dummy function for making sure this module is loaded. " A dummy function for making sure this module is loaded.
function! ale#assert#SetUpLinterTest(filetype, name) abort function! ale#assert#SetUpLinterTest(filetype, name) abort
" Set up a marker so ALE doesn't create real random temporary filenames. " Set up a marker so ALE doesn't create real random temporary filenames.
@ -177,31 +265,18 @@ function! ale#assert#SetUpLinterTest(filetype, name) abort
call ale#linter#Reset() call ale#linter#Reset()
call ale#linter#PreventLoading(a:filetype) call ale#linter#PreventLoading(a:filetype)
let l:prefix = 'ale_' . a:filetype . '_' . a:name
let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
Save g:ale_lsp_root Save g:ale_lsp_root
let g:ale_lsp_root = {} let g:ale_lsp_root = {}
Save b:ale_lsp_root Save b:ale_lsp_root
unlet! b:ale_lsp_root unlet! b:ale_lsp_root
call ale#assert#ResetVariables(a:filetype, a:name)
Save g:ale_c_build_dir Save g:ale_c_build_dir
unlet! g:ale_c_build_dir unlet! g:ale_c_build_dir
" Save and clear linter variables.
" We'll load the runtime file to reset them to defaults.
for l:key in filter(keys(g:), b:filter_expr)
execute 'Save g:' . l:key
unlet g:[l:key]
endfor
unlet! b:ale_c_build_dir unlet! b:ale_c_build_dir
for l:key in filter(keys(b:), b:filter_expr)
unlet b:[l:key]
endfor
execute 'runtime ale_linters/' . a:filetype . '/' . a:name . '.vim' execute 'runtime ale_linters/' . a:filetype . '/' . a:name . '.vim'
if !exists('g:dir') if !exists('g:dir')
@ -226,6 +301,10 @@ function! ale#assert#TearDownLinterTest() abort
delcommand GivenCommandOutput delcommand GivenCommandOutput
endif endif
if exists(':AssertLinterCwd')
delcommand AssertLinterCwd
endif
if exists(':AssertLinter') if exists(':AssertLinter')
delcommand AssertLinter delcommand AssertLinter
endif endif
@ -281,18 +360,7 @@ function! ale#assert#SetUpFixerTest(filetype, name, ...) abort
let s:FixerFunction = function(l:function_name) let s:FixerFunction = function(l:function_name)
let l:option_suffix = get(a:000, 0, a:name) let l:option_suffix = get(a:000, 0, a:name)
let l:prefix = 'ale_' . a:filetype . '_' call ale#assert#ResetVariables(a:filetype, a:name, l:option_suffix)
\ . substitute(l:option_suffix, '-', '_', 'g')
let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
for l:key in filter(keys(g:), b:filter_expr)
execute 'Save g:' . l:key
unlet g:[l:key]
endfor
for l:key in filter(keys(b:), b:filter_expr)
unlet b:[l:key]
endfor
execute 'runtime autoload/ale/fixers/' . substitute(a:name, '-', '_', 'g') . '.vim' execute 'runtime autoload/ale/fixers/' . substitute(a:name, '-', '_', 'g') . '.vim'
@ -329,6 +397,10 @@ function! ale#assert#TearDownFixerTest() abort
delcommand GivenCommandOutput delcommand GivenCommandOutput
endif endif
if exists(':AssertFixerCwd')
delcommand AssertFixerCwd
endif
if exists(':AssertFixer') if exists(':AssertFixer')
delcommand AssertFixer delcommand AssertFixer
endif endif

View File

@ -513,16 +513,18 @@ function! ale#c#GetMakeCommand(buffer) abort
if !empty(l:path) if !empty(l:path)
let l:always_make = ale#Var(a:buffer, 'c_always_make') let l:always_make = ale#Var(a:buffer, 'c_always_make')
return ale#path#CdString(fnamemodify(l:path, ':h')) return [
\ . 'make -n' . (l:always_make ? ' --always-make' : '') \ fnamemodify(l:path, ':h'),
\ 'make -n' . (l:always_make ? ' --always-make' : ''),
\]
endif endif
endif endif
return '' return ['', '']
endfunction endfunction
function! ale#c#RunMakeCommand(buffer, Callback) abort function! ale#c#RunMakeCommand(buffer, Callback) abort
let l:command = ale#c#GetMakeCommand(a:buffer) let [l:cwd, l:command] = ale#c#GetMakeCommand(a:buffer)
if empty(l:command) if empty(l:command)
return a:Callback(a:buffer, []) return a:Callback(a:buffer, [])
@ -532,6 +534,7 @@ function! ale#c#RunMakeCommand(buffer, Callback) abort
\ a:buffer, \ a:buffer,
\ l:command, \ l:command,
\ {b, output -> a:Callback(a:buffer, output)}, \ {b, output -> a:Callback(a:buffer, output)},
\ {'cwd': l:cwd},
\) \)
endfunction endfunction

View File

@ -7,6 +7,9 @@ if !exists('s:buffer_data')
let s:buffer_data = {} let s:buffer_data = {}
endif endif
" The regular expression used for formatting filenames with modifiers.
let s:path_format_regex = '\v\%s(%(:h|:t|:r|:e)*)'
" Used to get the data in tests. " Used to get the data in tests.
function! ale#command#GetData() abort function! ale#command#GetData() abort
return deepcopy(s:buffer_data) return deepcopy(s:buffer_data)
@ -26,6 +29,19 @@ function! ale#command#InitData(buffer) abort
endif endif
endfunction endfunction
" Set the cwd for commands that are about to run.
" Used internally.
function! ale#command#SetCwd(buffer, cwd) abort
call ale#command#InitData(a:buffer)
let s:buffer_data[a:buffer].cwd = a:cwd
endfunction
function! ale#command#ResetCwd(buffer) abort
if has_key(s:buffer_data, a:buffer)
let s:buffer_data[a:buffer].cwd = v:null
endif
endfunction
function! ale#command#ManageFile(buffer, file) abort function! ale#command#ManageFile(buffer, file) abort
call ale#command#InitData(a:buffer) call ale#command#InitData(a:buffer)
call add(s:buffer_data[a:buffer].file_list, a:file) call add(s:buffer_data[a:buffer].file_list, a:file)
@ -151,6 +167,24 @@ function! s:FormatFilename(filename, mappings, modifiers) abort
return ale#Escape(l:filename) return ale#Escape(l:filename)
endfunction endfunction
" Produce a command prefix to check to a particular directory for a command.
" %s format markers with filename-modifiers can be used as the directory, and
" will be returned verbatim for formatting in paths relative to files.
function! ale#command#CdString(directory) abort
let l:match = matchstrpos(a:directory, s:path_format_regex)
" Do not escape the directory here if it's a valid format string.
" This allows us to use sequences like %s:h, %s:h:h, etc.
let l:directory = l:match[1:] == [0, len(a:directory)]
\ ? a:directory
\ : ale#Escape(a:directory)
if has('win32')
return 'cd /d ' . l:directory . ' && '
endif
return 'cd ' . l:directory . ' && '
endfunction
" Given a command string, replace every... " Given a command string, replace every...
" %s -> with the current filename " %s -> with the current filename
" %t -> with the name of an unused file in a temporary directory " %t -> with the name of an unused file in a temporary directory
@ -161,11 +195,16 @@ function! ale#command#FormatCommand(
\ command, \ command,
\ pipe_file_if_needed, \ pipe_file_if_needed,
\ input, \ input,
\ cwd,
\ mappings, \ mappings,
\) abort \) abort
let l:temporary_file = '' let l:temporary_file = ''
let l:command = a:command let l:command = a:command
if !empty(a:cwd)
let l:command = ale#command#CdString(a:cwd) . l:command
endif
" First replace all uses of %%, used for literal percent characters, " First replace all uses of %%, used for literal percent characters,
" with an ugly string. " with an ugly string.
let l:command = substitute(l:command, '%%', '<<PERCENTS>>', 'g') let l:command = substitute(l:command, '%%', '<<PERCENTS>>', 'g')
@ -181,7 +220,7 @@ function! ale#command#FormatCommand(
let l:filename = fnamemodify(bufname(a:buffer), ':p') let l:filename = fnamemodify(bufname(a:buffer), ':p')
let l:command = substitute( let l:command = substitute(
\ l:command, \ l:command,
\ '\v\%s(%(:h|:t|:r|:e)*)', \ s:path_format_regex,
\ '\=s:FormatFilename(l:filename, a:mappings, submatch(1))', \ '\=s:FormatFilename(l:filename, a:mappings, submatch(1))',
\ 'g' \ 'g'
\) \)
@ -279,9 +318,16 @@ function! s:ExitCallback(buffer, line_list, Callback, data) abort
let l:result = a:data.result let l:result = a:data.result
let l:result.value = l:value let l:result.value = l:value
if get(l:result, 'result_callback', v:null) isnot v:null " Set the default cwd for this buffer in this call stack.
call call(l:result.result_callback, [l:value]) call ale#command#SetCwd(a:buffer, l:result.cwd)
endif
try
if get(l:result, 'result_callback', v:null) isnot v:null
call call(l:result.result_callback, [l:value])
endif
finally
call ale#command#ResetCwd(a:buffer)
endtry
endfunction endfunction
function! ale#command#Run(buffer, command, Callback, ...) abort function! ale#command#Run(buffer, command, Callback, ...) abort
@ -293,6 +339,13 @@ function! ale#command#Run(buffer, command, Callback, ...) abort
let l:output_stream = get(l:options, 'output_stream', 'stdout') let l:output_stream = get(l:options, 'output_stream', 'stdout')
let l:line_list = [] let l:line_list = []
let l:cwd = get(l:options, 'cwd', v:null)
if l:cwd is v:null
" Default the working directory to whatever it was for the last
" command run in the chain.
let l:cwd = get(get(s:buffer_data, a:buffer, {}), 'cwd', v:null)
endif
let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand( let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand(
\ a:buffer, \ a:buffer,
@ -300,6 +353,7 @@ function! ale#command#Run(buffer, command, Callback, ...) abort
\ a:command, \ a:command,
\ get(l:options, 'read_buffer', 0), \ get(l:options, 'read_buffer', 0),
\ get(l:options, 'input', v:null), \ get(l:options, 'input', v:null),
\ l:cwd,
\ get(l:options, 'filename_mappings', []), \ get(l:options, 'filename_mappings', []),
\) \)
let l:command = ale#job#PrepareCommand(a:buffer, l:command) let l:command = ale#job#PrepareCommand(a:buffer, l:command)
@ -366,10 +420,14 @@ function! ale#command#Run(buffer, command, Callback, ...) abort
" The `_deferred_job_id` is used for both checking the type of object, and " The `_deferred_job_id` is used for both checking the type of object, and
" for checking the job ID and status. " for checking the job ID and status.
" "
" The cwd is kept and used as the default value for the next command in
" the chain.
"
" The original command here is used in tests. " The original command here is used in tests.
let l:result = { let l:result = {
\ '_deferred_job_id': l:job_id, \ '_deferred_job_id': l:job_id,
\ 'executable': get(l:options, 'executable', ''), \ 'executable': get(l:options, 'executable', ''),
\ 'cwd': l:cwd,
\ 'command': a:command, \ 'command': a:command,
\} \}

View File

@ -413,6 +413,7 @@ function! s:RunJob(command, options) abort
return 0 return 0
endif endif
let l:cwd = a:options.cwd
let l:executable = a:options.executable let l:executable = a:options.executable
let l:buffer = a:options.buffer let l:buffer = a:options.buffer
let l:linter = a:options.linter let l:linter = a:options.linter
@ -425,6 +426,7 @@ function! s:RunJob(command, options) abort
\ 'executable': l:executable, \ 'executable': l:executable,
\}]) \}])
let l:result = ale#command#Run(l:buffer, l:command, l:Callback, { let l:result = ale#command#Run(l:buffer, l:command, l:Callback, {
\ 'cwd': l:cwd,
\ '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,
@ -541,8 +543,22 @@ function! s:RunIfExecutable(buffer, linter, lint_file, executable) abort
let l:job_type = a:lint_file ? 'file_linter' : 'linter' let l:job_type = a: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)
" Get the cwd for the linter and set it before we call GetCommand.
" This will ensure that ale#command#Run uses it by default.
let l:cwd = ale#linter#GetCwd(a:buffer, a:linter)
if l:cwd isnot v:null
call ale#command#SetCwd(a:buffer, l:cwd)
endif
let l:command = ale#linter#GetCommand(a:buffer, a:linter) let l:command = ale#linter#GetCommand(a:buffer, a:linter)
if l:cwd isnot v:null
call ale#command#ResetCwd(a:buffer)
endif
let l:options = { let l:options = {
\ 'cwd': l:cwd,
\ 'executable': a:executable, \ 'executable': a:executable,
\ 'buffer': a:buffer, \ 'buffer': a:buffer,
\ 'linter': a:linter, \ 'linter': a:linter,

View File

@ -172,6 +172,7 @@ function! s:RunJob(result, options) abort
let l:read_temporary_file = get(a:result, 'read_temporary_file', 0) let l:read_temporary_file = get(a:result, 'read_temporary_file', 0)
let l:read_buffer = get(a:result, 'read_buffer', 1) let l:read_buffer = get(a:result, 'read_buffer', 1)
let l:output_stream = get(a:result, 'output_stream', 'stdout') let l:output_stream = get(a:result, 'output_stream', 'stdout')
let l:cwd = get(a:result, 'cwd', v:null)
if l:read_temporary_file if l:read_temporary_file
let l:output_stream = 'none' let l:output_stream = 'none'
@ -190,6 +191,7 @@ function! s:RunJob(result, options) abort
\ 'read_buffer': l:read_buffer, \ 'read_buffer': l:read_buffer,
\ 'input': l:input, \ 'input': l:input,
\ 'log_output': 0, \ 'log_output': 0,
\ 'cwd': l:cwd,
\ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:fixer_name), \ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:fixer_name),
\}) \})

View File

@ -19,7 +19,9 @@ function! ale#fixers#autoimport#Fix(buffer) abort
endif endif
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'cwd': '%s:h',
\ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', \ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -',
\} \}
endfunction endfunction

View File

@ -17,25 +17,25 @@ function! ale#fixers#black#GetExecutable(buffer) abort
endfunction endfunction
function! ale#fixers#black#Fix(buffer) abort function! ale#fixers#black#Fix(buffer) abort
let l:cd_string = ale#Var(a:buffer, 'python_black_change_directory')
\ ? ale#path#BufferCdString(a:buffer)
\ : ''
let l:executable = ale#fixers#black#GetExecutable(a:buffer) let l:executable = ale#fixers#black#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run black' \ ? ' run black'
\ : '' \ : ''
let l:options = ale#Var(a:buffer, 'python_black_options') let l:options = ale#Var(a:buffer, 'python_black_options')
if expand('#' . a:buffer . ':e') is? 'pyi' if expand('#' . a:buffer . ':e') is? 'pyi'
let l:options .= '--pyi' let l:options .= '--pyi'
endif endif
return { let l:result = {
\ 'command': l:cd_string . ale#Escape(l:executable) . l:exec_args \ 'command': ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -', \ . ' -',
\} \}
if ale#Var(a:buffer, 'python_black_change_directory')
let l:result.cwd = '%s:h'
endif
return l:result
endfunction endfunction

View File

@ -53,8 +53,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
" Use --fix-to-stdout with eslint_d " Use --fix-to-stdout with eslint_d
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0]) if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
return { return {
\ 'command': ale#handlers#eslint#GetCdString(a:buffer) \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer),
\ . ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
@ -64,8 +64,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
" 4.9.0 is the first version with --fix-dry-run " 4.9.0 is the first version with --fix-dry-run
if ale#semver#GTE(a:version, [4, 9, 0]) if ale#semver#GTE(a:version, [4, 9, 0])
return { return {
\ 'command': ale#handlers#eslint#GetCdString(a:buffer) \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer),
\ . ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@ -73,8 +73,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
endif endif
return { return {
\ 'command': ale#handlers#eslint#GetCdString(a:buffer) \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer),
\ . ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . ale#Pad(l:options)
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
\ . ' --fix %t', \ . ' --fix %t',

View File

@ -17,9 +17,7 @@ endfunction
function! ale#fixers#isort#Fix(buffer) abort function! ale#fixers#isort#Fix(buffer) abort
let l:options = ale#Var(a:buffer, 'python_isort_options') let l:options = ale#Var(a:buffer, 'python_isort_options')
let l:executable = ale#fixers#isort#GetExecutable(a:buffer) let l:executable = ale#fixers#isort#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run isort' \ ? ' run isort'
\ : '' \ : ''
@ -29,8 +27,8 @@ function! ale#fixers#isort#Fix(buffer) abort
endif endif
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'cwd': '%s:h',
\ . ale#Escape(l:executable) . l:exec_args \ 'command': ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '') . ' -', \ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\} \}
endfunction endfunction

View File

@ -34,19 +34,11 @@ function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort
return a:output return a:output
endfunction endfunction
function! ale#fixers#prettier#GetProjectRoot(buffer) abort function! ale#fixers#prettier#GetCwd(buffer) abort
let l:config = ale#path#FindNearestFile(a:buffer, '.prettierignore') let l:config = ale#path#FindNearestFile(a:buffer, '.prettierignore')
if !empty(l:config)
return fnamemodify(l:config, ':h')
endif
" Fall back to the directory of the buffer " Fall back to the directory of the buffer
return fnamemodify(bufname(a:buffer), ':p:h') return !empty(l:config) ? fnamemodify(l:config, ':h') : '%s:h'
endfunction
function! ale#fixers#prettier#CdProjectRoot(buffer) abort
return ale#path#CdString(ale#fixers#prettier#GetProjectRoot(a:buffer))
endfunction endfunction
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
@ -103,8 +95,8 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
" Special error handling needed for prettier_d " Special error handling needed for prettier_d
if l:executable =~# 'prettier_d$' if l:executable =~# 'prettier_d$'
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'cwd': '%s:h',
\ . ale#Escape(l:executable) \ 'command':ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ 'process_with': 'ale#fixers#prettier#ProcessPrettierDOutput', \ 'process_with': 'ale#fixers#prettier#ProcessPrettierDOutput',
@ -114,8 +106,8 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
" 1.4.0 is the first version with --stdin-filepath " 1.4.0 is the first version with --stdin-filepath
if ale#semver#GTE(a:version, [1, 4, 0]) if ale#semver#GTE(a:version, [1, 4, 0])
return { return {
\ 'command': ale#fixers#prettier#CdProjectRoot(a:buffer) \ 'cwd': ale#fixers#prettier#GetCwd(a:buffer),
\ . ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\} \}

View File

@ -37,8 +37,8 @@ function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version) abort
" 4.4.0 is the first version with --stdin-filepath " 4.4.0 is the first version with --stdin-filepath
if ale#semver#GTE(a:version, [4, 4, 0]) if ale#semver#GTE(a:version, [4, 4, 0])
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'cwd': '%s:h',
\ . ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . l:eslint_config_option \ . l:eslint_config_option
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',

View File

@ -17,8 +17,8 @@ function! ale#fixers#stylelint#Fix(buffer) abort
let l:options = ale#Var(a:buffer, 'stylelint_options') let l:options = ale#Var(a:buffer, 'stylelint_options')
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'cwd': '%s:h',
\ . ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ' %t' \ . ' %t'
\ . ale#Pad(l:options) \ . ale#Pad(l:options)
\ . ' --fix', \ . ' --fix',

View File

@ -7,7 +7,6 @@ call ale#Set('yaml_yamlfix_use_global', get(g:, 'ale_use_global_executables', 0)
function! ale#fixers#yamlfix#Fix(buffer) abort function! ale#fixers#yamlfix#Fix(buffer) abort
let l:options = ale#Var(a:buffer, 'yaml_yamlfix_options') let l:options = ale#Var(a:buffer, 'yaml_yamlfix_options')
let l:executable = ale#python#FindExecutable( let l:executable = ale#python#FindExecutable(
\ a:buffer, \ a:buffer,
\ 'yaml_yamlfix', \ 'yaml_yamlfix',
@ -19,7 +18,8 @@ function! ale#fixers#yamlfix#Fix(buffer) abort
endif endif
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'cwd': '%s:h',
\ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', \ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\} \}
endfunction endfunction

View File

@ -50,18 +50,25 @@ function! ale#gradle#FindExecutable(buffer) abort
return '' return ''
endfunction endfunction
" Given a buffer number, build a command to print the classpath of the root " Given a buffer number, get a working directory and command to print the
" project. Returns an empty string if cannot build the command. " classpath of the root project.
"
" Returns an empty string for the command if Gradle is not detected.
function! ale#gradle#BuildClasspathCommand(buffer) abort function! ale#gradle#BuildClasspathCommand(buffer) abort
let l:executable = ale#gradle#FindExecutable(a:buffer) let l:executable = ale#gradle#FindExecutable(a:buffer)
let l:project_root = ale#gradle#FindProjectRoot(a:buffer)
if !empty(l:executable) && !empty(l:project_root) if !empty(l:executable)
return ale#path#CdString(l:project_root) let l:project_root = ale#gradle#FindProjectRoot(a:buffer)
\ . ale#Escape(l:executable)
\ . ' -I ' . ale#Escape(s:init_path) if !empty(l:project_root)
\ . ' -q printClasspath' return [
\ l:project_root,
\ ale#Escape(l:executable)
\ . ' -I ' . ale#Escape(s:init_path)
\ . ' -q printClasspath'
\]
endif
endif endif
return '' return ['', '']
endfunction endfunction

View File

@ -1,10 +1,9 @@
" Description: Handle errors for cppcheck. " Description: Handle errors for cppcheck.
function! ale#handlers#cppcheck#GetCdCommand(buffer) abort function! ale#handlers#cppcheck#GetCwd(buffer) abort
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer) let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
let l:cd_command = !empty(l:dir) ? ale#path#CdString(l:dir) : ''
return l:cd_command return !empty(l:dir) ? l:dir : ''
endfunction endfunction
function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort

View File

@ -39,9 +39,8 @@ function! ale#handlers#eslint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_eslint', s:executables) return ale#node#FindExecutable(a:buffer, 'javascript_eslint', s:executables)
endfunction endfunction
" Given a buffer, return a command prefix string which changes directory " Given a buffer, return an appropriate working directory for ESLint.
" as necessary for running ESLint. function! ale#handlers#eslint#GetCwd(buffer) abort
function! ale#handlers#eslint#GetCdString(buffer) abort
" ESLint 6 loads plugins/configs/parsers from the project root " ESLint 6 loads plugins/configs/parsers from the project root
" By default, the project root is simply the CWD of the running process. " By default, the project root is simply the CWD of the running process.
" https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md " https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md
@ -60,7 +59,7 @@ function! ale#handlers#eslint#GetCdString(buffer) abort
let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : '' let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : ''
endif endif
return !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : '' return !empty(l:project_dir) ? l:project_dir : ''
endfunction endfunction
function! ale#handlers#eslint#GetCommand(buffer) abort function! ale#handlers#eslint#GetCommand(buffer) abort
@ -68,8 +67,7 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'javascript_eslint_options') let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
return ale#handlers#eslint#GetCdString(a:buffer) return ale#node#Executable(a:buffer, l:executable)
\ . ale#node#Executable(a:buffer, l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -f json --stdin --stdin-filename %s' \ . ' -f json --stdin --stdin-filename %s'
endfunction endfunction

View File

@ -40,21 +40,21 @@ function! ale#handlers#shellcheck#GetDialectArgument(buffer) abort
return '' return ''
endfunction endfunction
function! ale#handlers#shellcheck#GetCwd(buffer) abort
return ale#Var(a:buffer, 'sh_shellcheck_change_directory') ? '%s:h' : ''
endfunction
function! ale#handlers#shellcheck#GetCommand(buffer, version) abort function! ale#handlers#shellcheck#GetCommand(buffer, version) abort
let l:options = ale#Var(a:buffer, 'sh_shellcheck_options') let l:options = ale#Var(a:buffer, 'sh_shellcheck_options')
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions') let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect') let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : '' let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
let l:cd_string = ale#Var(a:buffer, 'sh_shellcheck_change_directory')
\ ? ale#path#BufferCdString(a:buffer)
\ : ''
if l:dialect is# 'auto' if l:dialect is# 'auto'
let l:dialect = ale#handlers#shellcheck#GetDialectArgument(a:buffer) let l:dialect = ale#handlers#shellcheck#GetDialectArgument(a:buffer)
endif endif
return l:cd_string return '%e'
\ . '%e'
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
@ -111,6 +111,7 @@ function! ale#handlers#shellcheck#DefineLinter(filetype) abort
call ale#linter#Define(a:filetype, { call ale#linter#Define(a:filetype, {
\ 'name': 'shellcheck', \ 'name': 'shellcheck',
\ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')}, \ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')},
\ 'cwd': function('ale#handlers#shellcheck#GetCwd'),
\ 'command': {buffer -> ale#semver#RunWithVersionCheck( \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ buffer, \ buffer,
\ ale#Var(buffer, 'sh_shellcheck_executable'), \ ale#Var(buffer, 'sh_shellcheck_executable'),

View File

@ -151,17 +151,30 @@ function! ale#linter#PreProcess(filetype, linter) abort
endif endif
let l:obj.address = a:linter.address let l:obj.address = a:linter.address
if has_key(a:linter, 'cwd')
throw '`cwd` makes no sense for socket LSP connections'
endif
else else
throw '`address` must be defined for getting the LSP address' throw '`address` must be defined for getting the LSP address'
endif endif
if has_key(a:linter, 'cwd')
let l:obj.cwd = a:linter.cwd
if type(l:obj.cwd) isnot v:t_string
\&& type(l:obj.cwd) isnot v:t_func
throw '`cwd` must be a String or Function if defined'
endif
endif
if l:needs_lsp_details if l:needs_lsp_details
" Default to using the filetype as the language. " Default to using the filetype as the language.
let l:obj.language = get(a:linter, 'language', a:filetype) let l:obj.language = get(a:linter, 'language', a:filetype)
if type(l:obj.language) isnot v:t_string if type(l:obj.language) isnot v:t_string
\&& type(l:obj.language) isnot v:t_func \&& type(l:obj.language) isnot v:t_func
throw '`language` must be a String or Funcref if defined' throw '`language` must be a String or Function if defined'
endif endif
if has_key(a:linter, 'project_root') if has_key(a:linter, 'project_root')
@ -415,6 +428,12 @@ function! ale#linter#GetExecutable(buffer, linter) abort
\ : l:Executable \ : l:Executable
endfunction endfunction
function! ale#linter#GetCwd(buffer, linter) abort
let l:Cwd = get(a:linter, 'cwd', v:null)
return type(l:Cwd) is v:t_func ? l:Cwd(a:buffer) : l:Cwd
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.
function! ale#linter#GetCommand(buffer, linter) abort function! ale#linter#GetCommand(buffer, linter) abort
let l:Command = a:linter.command let l:Command = a:linter.command

View File

@ -290,6 +290,7 @@ function! s:StartLSP(options, address, executable, command) abort
\ a:command, \ a:command,
\ 0, \ 0,
\ v:false, \ v:false,
\ v:null,
\ [], \ [],
\)[1] \)[1]
let l:command = ale#job#PrepareCommand(l:buffer, l:command) let l:command = ale#job#PrepareCommand(l:buffer, l:command)

View File

@ -17,7 +17,6 @@ function! ale#maven#FindProjectRoot(buffer) abort
return '' return ''
endfunction endfunction
" Given a buffer number, find the path to the executable. " Given a buffer number, find the path to the executable.
" First search on the path for 'mvnw' (mvnw.cmd on Windows), if nothing is found, " First search on the path for 'mvnw' (mvnw.cmd on Windows), if nothing is found,
" try the global command. Returns an empty string if cannot find the executable. " try the global command. Returns an empty string if cannot find the executable.
@ -36,16 +35,23 @@ function! ale#maven#FindExecutable(buffer) abort
return '' return ''
endfunction endfunction
" Given a buffer number, build a command to print the classpath of the root " Given a buffer number, get a working directory and command to print the
" project. Returns an empty string if cannot build the command. " classpath of the root project.
"
" Returns an empty string for the command if Maven is not detected.
function! ale#maven#BuildClasspathCommand(buffer) abort function! ale#maven#BuildClasspathCommand(buffer) abort
let l:executable = ale#maven#FindExecutable(a:buffer) let l:executable = ale#maven#FindExecutable(a:buffer)
let l:project_root = ale#maven#FindProjectRoot(a:buffer)
if !empty(l:executable) && !empty(l:project_root) if !empty(l:executable)
return ale#path#CdString(l:project_root) let l:project_root = ale#maven#FindProjectRoot(a:buffer)
\ . l:executable . ' dependency:build-classpath'
if !empty(l:project_root)
return [
\ l:project_root,
\ ale#Escape(l:executable) . ' dependency:build-classpath'
\]
endif
endif endif
return '' return ['', '']
endfunction endfunction

View File

@ -77,26 +77,6 @@ function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abor
return l:path return l:path
endfunction endfunction
" Output 'cd <directory> && '
" This function can be used changing the directory for a linter command.
function! ale#path#CdString(directory) abort
if has('win32')
return 'cd /d ' . ale#Escape(a:directory) . ' && '
endif
return 'cd ' . ale#Escape(a:directory) . ' && '
endfunction
" Output 'cd <buffer_filename_directory> && '
" This function can be used changing the directory for a linter command.
function! ale#path#BufferCdString(buffer) abort
if has('win32')
return 'cd /d %s:h && '
endif
return 'cd %s:h && '
endfunction
" Return 1 if a path is an absolute path. " Return 1 if a path is an absolute path.
function! ale#path#IsAbsolute(filename) abort function! ale#path#IsAbsolute(filename) abort
if has('win32') && a:filename[:0] is# '\' if has('win32') && a:filename[:0] is# '\'

View File

@ -311,6 +311,7 @@ The full list of commands that will be temporarily defined for linter tests
given the above setup are as follows. given the above setup are as follows.
`GivenCommandOutput [...]` - Define output for ale#command#Run. `GivenCommandOutput [...]` - Define output for ale#command#Run.
`AssertLinterCwd cwd` - Check the `cwd` for the linter.
`AssertLinter executable, command` - Check the executable and command. `AssertLinter executable, command` - Check the executable and command.
`AssertLinterNotExecuted` - Check that linters will not be executed. `AssertLinterNotExecuted` - Check that linters will not be executed.
`AssertLSPLanguage language` - Check the language given to an LSP server. `AssertLSPLanguage language` - Check the language given to an LSP server.
@ -357,6 +358,7 @@ The full list of commands that will be temporarily defined for fixer tests
given the above setup are as follows. given the above setup are as follows.
`GivenCommandOutput [...]` - Define output for ale#command#Run. `GivenCommandOutput [...]` - Define output for ale#command#Run.
`AssertFixerCwd cwd` - Check the `cwd` for the fixer.
`AssertFixer results` - Check the fixer results `AssertFixer results` - Check the fixer results
`AssertFixerNotExecuted` - Check that fixers will not be executed. `AssertFixerNotExecuted` - Check that fixers will not be executed.

View File

@ -342,6 +342,12 @@ the buffers being checked.
When a |Dictionary| is returned for an |ALEFix| callback, the following keys When a |Dictionary| is returned for an |ALEFix| callback, the following keys
are supported for running the commands. are supported for running the commands.
`cwd` An optional |String| for setting the working directory
for the command.
If not set, or `v:null`, the `cwd` of the last command
that spawn this one will be used.
`command` A |String| for the command to run. This key is required. `command` A |String| for the command to run. This key is required.
When `%t` is included in a command string, a temporary When `%t` is included in a command string, a temporary
@ -3578,6 +3584,12 @@ ale#command#Run(buffer, command, callback, [options]) *ale#command#Run()*
< <
The following `options` can be provided. The following `options` can be provided.
`cwd` - An optional |String| for setting the working directory
for the command, just as per |ale#linter#Define|.
If not set, or `v:null`, the `cwd` of the last command
that spawned this one will be used.
`output_stream` - Either `'stdout'`, `'stderr'`, `'both'`, or `output_stream` - Either `'stdout'`, `'stderr'`, `'both'`, or
`'none`' for selecting which output streams to read `'none`' for selecting which output streams to read
lines from. lines from.
@ -3803,10 +3815,33 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
The result can be computed with |ale#command#Run()|. The result can be computed with |ale#command#Run()|.
The command string can be formatted with format
markers. See |ale-command-format-strings|.
This command will be fed the lines from the buffer to This command will be fed the lines from the buffer to
check, and will produce the lines of output given to check, and will produce the lines of output given to
the `callback`. the `callback`.
`cwd` An optional |String| for setting the working
directory for the command, or a |Funcref| for a
function to call for computing the command, accepting
a buffer number. The working directory can be
specified as a format string for determining the path
dynamically. See |ale-command-format-strings|.
To set the working directory to the directory
containing the file you're checking, you should
probably use `'%s:h'` as the option value.
If this option is absent or the string is empty, the
`command` will be run with no determined working
directory in particular.
The directory specified with this option will be used
as the default working directory for all commands run
in a chain with |ale#command#Run()|, unless otherwise
specified.
`output_stream` A |String| for the output stream the lines of output `output_stream` A |String| for the output stream the lines of output
should be read from for the command which is run. The should be read from for the command which is run. The
accepted values are `'stdout'`, `'stderr'`, and accepted values are `'stdout'`, `'stderr'`, and

View File

@ -17,14 +17,14 @@ Execute(The executable should be configurable):
let b:ale_c_cppcheck_executable = 'foobar' let b:ale_c_cppcheck_executable = 'foobar'
AssertLinterCwd ''
AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail
Execute(cppcheck for C should detect compile_commands.json files): Execute(cppcheck for C should detect compile_commands.json files):
call ale#test#SetFilename('cppcheck_paths/one/foo.c') call ale#test#SetFilename('cppcheck_paths/one/foo.c')
AssertLinter 'cppcheck', AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/one')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) AssertLinter 'cppcheck', ale#Escape('cppcheck')
\ . ale#Escape('cppcheck')
\ . ' -q --language=c' \ . ' -q --language=c'
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --project=' . ale#Escape('compile_commands.json') \ . ' --project=' . ale#Escape('compile_commands.json')
@ -33,9 +33,8 @@ Execute(cppcheck for C should detect compile_commands.json files):
Execute(cppcheck for C should detect compile_commands.json files in build directories): Execute(cppcheck for C should detect compile_commands.json files in build directories):
call ale#test#SetFilename('cppcheck_paths/with_build_dir/foo.cpp') call ale#test#SetFilename('cppcheck_paths/with_build_dir/foo.cpp')
AssertLinter 'cppcheck', AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir')) AssertLinter 'cppcheck', ale#Escape('cppcheck')
\ . ale#Escape('cppcheck')
\ . ' -q --language=c' \ . ' -q --language=c'
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json'))
@ -58,9 +57,8 @@ Execute(cppcheck for C should ignore compile_commands.json file if buffer is mod
set buftype= set buftype=
set modified set modified
AssertLinter 'cppcheck', AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/one')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) AssertLinter 'cppcheck', ale#Escape('cppcheck')
\ . ale#Escape('cppcheck')
\ . ' -q --language=c' \ . ' -q --language=c'
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --enable=style' \ . ' --enable=style'

View File

@ -118,20 +118,23 @@ Execute(--all-features should be used when g:ale_rust_cargo_default_feature_beha
GivenCommandOutput ['cargo 0.22.0 (3423351a5 2017-10-06)'] GivenCommandOutput ['cargo 0.22.0 (3423351a5 2017-10-06)']
AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --all-features'] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --all-features']
Execute(When a crate belongs to a workspace we should cd into the crate): Execute(Cargo should run from the crate directory when set to avoid the workspace):
let g:ale_rust_cargo_avoid_whole_workspace = 1 let g:ale_rust_cargo_avoid_whole_workspace = 1
call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs') call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs')
AssertLinterCwd ale#path#Simplify(g:dir . '/cargo_workspace_paths/subpath')
call ale#semver#ResetVersionCache()
AssertLinter 'cargo', [ AssertLinter 'cargo', [
\ ale#Escape('cargo') . ' --version', \ ale#Escape('cargo') . ' --version',
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/cargo_workspace_paths/subpath')) . ' && ' \ 'cargo check --frozen --message-format=json -q',
\ . 'cargo check --frozen --message-format=json -q',
\] \]
Execute(When a crate belongs to a workspace we chdir into the crate, unless we disabled it): Execute(Cargo should not run from the crate directory when not set to avoid the workspace):
let g:ale_rust_cargo_avoid_whole_workspace = 0 let g:ale_rust_cargo_avoid_whole_workspace = 0
call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs') call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs')
AssertLinterCwd ''
call ale#semver#ResetVersionCache()
AssertLinter 'cargo', [ AssertLinter 'cargo', [
\ ale#Escape('cargo') . ' --version', \ ale#Escape('cargo') . ' --version',
\ 'cargo check --frozen --message-format=json -q', \ 'cargo check --frozen --message-format=json -q',

View File

@ -17,14 +17,14 @@ Execute(The executable should be configurable):
let b:ale_cpp_cppcheck_executable = 'foobar' let b:ale_cpp_cppcheck_executable = 'foobar'
AssertLinterCwd ''
AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail
Execute(cppcheck for C++ should detect compile_commands.json files): Execute(cppcheck for C++ should detect compile_commands.json files):
call ale#test#SetFilename('cppcheck_paths/one/foo.cpp') call ale#test#SetFilename('cppcheck_paths/one/foo.cpp')
AssertLinter 'cppcheck', AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/one')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) AssertLinter 'cppcheck', ale#Escape('cppcheck')
\ . ale#Escape('cppcheck')
\ . ' -q --language=c++' \ . ' -q --language=c++'
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --project=' . ale#Escape('compile_commands.json') \ . ' --project=' . ale#Escape('compile_commands.json')
@ -33,9 +33,8 @@ Execute(cppcheck for C++ should detect compile_commands.json files):
Execute(cppcheck for C++ should detect compile_commands.json files in build directories): Execute(cppcheck for C++ should detect compile_commands.json files in build directories):
call ale#test#SetFilename('cppcheck_paths/with_build_dir/foo.cpp') call ale#test#SetFilename('cppcheck_paths/with_build_dir/foo.cpp')
AssertLinter 'cppcheck', AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir')) AssertLinter 'cppcheck', ale#Escape('cppcheck')
\ . ale#Escape('cppcheck')
\ . ' -q --language=c++' \ . ' -q --language=c++'
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json'))
@ -58,9 +57,8 @@ Execute(cppcheck for C++ should ignore compile_commands.json file if buffer is m
set buftype= set buftype=
set modified set modified
AssertLinter 'cppcheck', AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/one')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) AssertLinter 'cppcheck', ale#Escape('cppcheck')
\ . ale#Escape('cppcheck')
\ . ' -q --language=c++' \ . ' -q --language=c++'
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --enable=style' \ . ' --enable=style'

View File

@ -5,43 +5,38 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The csc linter should return the correct default command): Execute(The csc linter should return the correct default command):
AssertLinter 'csc', ale#path#CdString(g:dir) AssertLinterCwd expand('%:p:h')
\ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
Execute(The options should be be used in the command): Execute(The options should be be used in the command):
let g:ale_cs_csc_options = '' let g:ale_cs_csc_options = ''
AssertLinter 'csc', ale#path#CdString(g:dir) AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
\ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
Execute(The souce path should be be used in the command): Execute(The souce path should be be used in the command):
let g:ale_cs_csc_source = '../foo/bar' let g:ale_cs_csc_source = '../foo/bar'
AssertLinter 'csc', ale#path#CdString('../foo/bar') AssertLinterCwd '../foo/bar'
\ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
Execute(The list of search pathes for assemblies should be be used in the command if not empty): Execute(The list of search pathes for assemblies should be be used in the command if not empty):
let g:ale_cs_csc_assembly_path = ['/usr/lib/mono', '../foo/bar'] let g:ale_cs_csc_assembly_path = ['/usr/lib/mono', '../foo/bar']
AssertLinter 'csc', ale#path#CdString(g:dir) AssertLinter 'csc', 'csc /unsafe'
\ . 'csc /unsafe'
\ . ' /lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar') \ . ' /lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar')
\ . ' /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') \ . ' /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
let g:ale_cs_csc_assembly_path = [] let g:ale_cs_csc_assembly_path = []
AssertLinter 'csc', ale#path#CdString(g:dir) AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
\ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
Execute(The list of assemblies should be be used in the command if not empty): Execute(The list of assemblies should be be used in the command if not empty):
let g:ale_cs_csc_assemblies = ['foo.dll', 'bar.dll'] let g:ale_cs_csc_assemblies = ['foo.dll', 'bar.dll']
AssertLinter 'csc', ale#path#CdString(g:dir) AssertLinter 'csc', 'csc /unsafe'
\ . 'csc /unsafe'
\ . ' /r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll') \ . ' /r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll')
\ . ' /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') \ . ' /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
let g:ale_cs_csc_assemblies = [] let g:ale_cs_csc_assemblies = []
AssertLinter 'csc', ale#path#CdString(g:dir) AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')
\ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs')

View File

@ -5,43 +5,38 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The mcsc linter should return the correct default command): Execute(The mcsc linter should return the correct default command):
AssertLinter 'mcs', ale#path#CdString(g:dir) AssertLinterCwd expand('%:p:h')
\ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
Execute(The options should be be used in the command): Execute(The options should be be used in the command):
let g:ale_cs_mcsc_options = '-pkg:dotnet' let g:ale_cs_mcsc_options = '-pkg:dotnet'
AssertLinter 'mcs', ale#path#CdString(g:dir) AssertLinter 'mcs', 'mcs -unsafe -pkg:dotnet -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
\ . 'mcs -unsafe -pkg:dotnet -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
Execute(The souce path should be be used in the command): Execute(The souce path should be be used in the command):
let g:ale_cs_mcsc_source = '../foo/bar' let g:ale_cs_mcsc_source = '../foo/bar'
AssertLinter 'mcs', ale#path#CdString('../foo/bar') AssertLinterCwd '../foo/bar'
\ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
Execute(The list of search pathes for assemblies should be be used in the command if not empty): Execute(The list of search pathes for assemblies should be be used in the command if not empty):
let g:ale_cs_mcsc_assembly_path = ['/usr/lib/mono', '../foo/bar'] let g:ale_cs_mcsc_assembly_path = ['/usr/lib/mono', '../foo/bar']
AssertLinter 'mcs', ale#path#CdString(g:dir) AssertLinter 'mcs', 'mcs -unsafe'
\ . 'mcs -unsafe'
\ . ' -lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar') \ . ' -lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar')
\ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') \ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
let g:ale_cs_mcsc_assembly_path = [] let g:ale_cs_mcsc_assembly_path = []
AssertLinter 'mcs', ale#path#CdString(g:dir) AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
\ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
Execute(The list of assemblies should be be used in the command if not empty): Execute(The list of assemblies should be be used in the command if not empty):
let g:ale_cs_mcsc_assemblies = ['foo.dll', 'bar.dll'] let g:ale_cs_mcsc_assemblies = ['foo.dll', 'bar.dll']
AssertLinter 'mcs', ale#path#CdString(g:dir) AssertLinter 'mcs', 'mcs -unsafe'
\ . 'mcs -unsafe'
\ . ' -r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll') \ . ' -r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll')
\ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') \ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
let g:ale_cs_mcsc_assemblies = [] let g:ale_cs_mcsc_assemblies = []
AssertLinter 'mcs', ale#path#CdString(g:dir) AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
\ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')

View File

@ -0,0 +1,16 @@
Before:
call ale#assert#SetUpLinterTest('elixir', 'dialyxir')
call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex')
After:
call ale#assert#TearDownLinterTest()
Execute(Builds dialyxir command with a normal project):
AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/mix_project')
AssertLinter 'mix', 'mix help dialyzer && mix dialyzer'
Execute(Builds dialyxir command with an umbrella project):
call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex')
AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project')
AssertLinter 'mix', 'mix help dialyzer && mix dialyzer'

View File

@ -0,0 +1,16 @@
Before:
call ale#assert#SetUpLinterTest('elixir', 'dogma')
call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex')
After:
call ale#assert#TearDownLinterTest()
Execute(Builds dogma command with a normal project):
AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/mix_project')
AssertLinter 'mix', 'mix help dogma && mix dogma %s --format=flycheck'
Execute(Builds dogma command with an umbrella project):
call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex')
AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project')
AssertLinter 'mix', 'mix help dogma && mix dogma %s --format=flycheck'

View File

@ -1,47 +0,0 @@
Before:
call ale#assert#SetUpLinterTest('elixir', 'credo')
call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex')
After:
unlet! g:ale_elixir_credo_strict
call ale#assert#TearDownLinterTest()
Execute(Builds credo command with normal project):
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project'))
\ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with umbrella project):
call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex')
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project'))
\ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with --strict mode when set to 1):
let g:ale_elixir_credo_strict = 1
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project'))
\ . 'mix help credo && mix credo --strict --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with suggest mode by default):
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project'))
\ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with suggest mode when set to 0):
let g:ale_elixir_credo_strict = 0
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project'))
\ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with a custom config file):
let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs'
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project'))
\ . 'mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s'

View File

@ -0,0 +1,43 @@
Before:
call ale#assert#SetUpLinterTest('elixir', 'credo')
call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex')
After:
unlet! g:ale_elixir_credo_strict
call ale#assert#TearDownLinterTest()
Execute(Builds credo command with normal project):
AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/mix_project')
AssertLinter 'mix',
\ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with umbrella project):
call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex')
AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project')
AssertLinter 'mix',
\ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with --strict mode when set to 1):
let g:ale_elixir_credo_strict = 1
AssertLinter 'mix',
\ 'mix help credo && mix credo --strict --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with suggest mode by default):
AssertLinter 'mix',
\ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with suggest mode when set to 0):
let g:ale_elixir_credo_strict = 0
AssertLinter 'mix',
\ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with a custom config file):
let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs'
AssertLinter 'mix',
\ 'mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s'

View File

@ -1,9 +1,7 @@
Before: Before:
call ale#assert#SetUpLinterTest('elixir', 'mix') call ale#assert#SetUpLinterTest('elixir', 'mix')
call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex')
let g:env_prefix = has('win32') let g:env_prefix = ale#Env('MIX_BUILD_PATH', 'TEMP_DIR')
\ ? 'set MIX_BUILD_PATH=' . ale#Escape('TEMP_DIR') . ' && '
\ : 'MIX_BUILD_PATH=' . ale#Escape('TEMP_DIR') . ' '
After: After:
unlet! g:env_prefix unlet! g:env_prefix
@ -11,23 +9,11 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default mix command should be correct): Execute(The default mix command should be correct):
call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex') AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/mix_project')
AssertLinter 'mix', g:env_prefix . 'mix compile %s'
AssertLinter 'mix', Execute(Build mix commands with an umbrella root):
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex')
\ . g:env_prefix
\ . 'mix compile %s'
Execute(FindMixProjectRoot should detect the project root directory via mix.exs): AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project')
silent execute 'file ' . fnameescape(g:dir . '/elixir_paths/mix_project/lib/app.ex') AssertLinter 'mix', g:env_prefix . 'mix compile %s'
AssertEqual
\ ale#path#Simplify(g:dir . '/elixir_paths/mix_project'),
\ ale#handlers#elixir#FindMixProjectRoot(bufnr(''))
Execute(FindMixUmbrellaRoot should detect the umbrella root directory via mix.exs):
silent execute 'file ' . fnameescape(g:dir . '/elixir_paths/umbrella_project/apps/app1/lib/app.ex')
AssertEqual
\ ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project'),
\ ale#handlers#elixir#FindMixUmbrellaRoot(bufnr(''))

View File

@ -11,18 +11,18 @@ Execute(should get valid executable with default params):
let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm') let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm')
AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp')
AssertLinter g:executable, AssertLinter g:executable,
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp')) . ' && ' \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t'
\ . ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t'
Execute(should get elm-test executable for test code with elm >= 0.19): Execute(should get elm-test executable for test code with elm >= 0.19):
call ale#test#SetFilename('../elm-test-files/newapp/tests/TestSuite.elm') call ale#test#SetFilename('../elm-test-files/newapp/tests/TestSuite.elm')
let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm-test') let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm-test')
AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp')
AssertLinter g:executable, AssertLinter g:executable,
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp')) . ' && ' \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null --compiler '
\ . ale#Escape(g:executable) . ' make --report=json --output=/dev/null --compiler '
\ . ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm') . ' %t' \ . ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm') . ' %t'
Execute(should fallback to elm executable with elm >= 0.19): Execute(should fallback to elm executable with elm >= 0.19):
@ -30,27 +30,27 @@ Execute(should fallback to elm executable with elm >= 0.19):
let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp-notests/node_modules/.bin/elm') let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp-notests/node_modules/.bin/elm')
AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp-notests')
AssertLinter g:executable, AssertLinter g:executable,
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp-notests')) . ' && ' \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t'
\ . ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t'
Execute(should get plain elm executable for test code with elm < 0.19): Execute(should get plain elm executable for test code with elm < 0.19):
call ale#test#SetFilename('../elm-test-files/oldapp/tests/TestSuite.elm') call ale#test#SetFilename('../elm-test-files/oldapp/tests/TestSuite.elm')
let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/oldapp/node_modules/.bin/elm') let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/oldapp/node_modules/.bin/elm')
AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/oldapp')
AssertLinter g:executable, AssertLinter g:executable,
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/oldapp')) . ' && ' \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t'
\ . ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t'
Execute(should get valid executable with 'use_global' params): Execute(should get valid executable with 'use_global' params):
let g:ale_elm_make_use_global = 1 let g:ale_elm_make_use_global = 1
call ale#test#SetFilename('../elm-test-files/newapp/src/Main.elm') call ale#test#SetFilename('../elm-test-files/newapp/src/Main.elm')
AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp')
AssertLinter 'elm', AssertLinter 'elm',
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp')) . ' && ' \ ale#Escape('elm') . ' make --report=json --output=/dev/null %t'
\ . ale#Escape('elm') . ' make --report=json --output=/dev/null %t'
Execute(should get valid executable with 'use_global' and 'executable' params): Execute(should get valid executable with 'use_global' and 'executable' params):
let g:ale_elm_make_executable = 'other-elm' let g:ale_elm_make_executable = 'other-elm'
@ -58,6 +58,6 @@ Execute(should get valid executable with 'use_global' and 'executable' params):
call ale#test#SetFilename('../elm-test-files/newapp/src/Main.elm') call ale#test#SetFilename('../elm-test-files/newapp/src/Main.elm')
AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp')
AssertLinter 'other-elm', AssertLinter 'other-elm',
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp')) . ' && ' \ ale#Escape('other-elm') . ' make --report=json --output=/dev/null %t'
\ . ale#Escape('other-elm') . ' make --report=json --output=/dev/null %t'

View File

@ -0,0 +1,76 @@
Before:
call ale#assert#SetUpLinterTest('javascript', 'eslint')
runtime autoload/ale/handlers/eslint.vim
let b:args = ' -f json --stdin --stdin-filename %s'
After:
unlet! b:args
unlet! b:executable
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
AssertLinterCwd ''
AssertLinter 'eslint', ale#Escape('eslint') . b:args
Execute(create-react-app directories should be detected correctly):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js')
let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')
AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')
AssertLinter b:executable,
\ (has('win32') ? ale#Escape('node.exe') . ' ' : '')
\ . ale#Escape(b:executable) . b:args
Execute(use-global should override create-react-app detection):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js')
let g:ale_javascript_eslint_use_global = 1
let g:ale_javascript_eslint_executable = 'eslint_d'
let b:executable = 'eslint_d'
AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')
AssertLinter b:executable, ale#Escape(b:executable) . b:args
Execute(other app directories should be detected correctly):
call ale#test#SetFilename('../eslint-test-files/other-app/subdir/testfile.js')
let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')
AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files')
AssertLinter b:executable, ale#Escape(b:executable) . b:args
Execute(use-global should override other app directories):
call ale#test#SetFilename('../eslint-test-files/other-app/subdir/testfile.js')
let g:ale_javascript_eslint_use_global = 1
let g:ale_javascript_eslint_executable = 'eslint_d'
let b:executable = 'eslint_d'
AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files')
AssertLinter b:executable, ale#Escape(b:executable) . b:args
Execute(eslint_d should be detected correctly):
call ale#test#SetFilename('../eslint-test-files/app-with-eslint-d/testfile.js')
let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')
AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')
AssertLinter b:executable, ale#Escape(b:executable) . b:args
Execute(eslint.js executables should be run with node on Windows):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js')
let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')
AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')
AssertLinter b:executable,
\ (has('win32') ? ale#Escape('node.exe') . ' ' : '')
\ . ale#Escape(b:executable) . b:args
Execute(eslint.js should be run from a containing project with eslint):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-package-json/testfile.js')
let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')
AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')
AssertLinter b:executable,
\ (has('win32') ? ale#Escape('node.exe') . ' ' : '')
\ . ale#Escape(b:executable) . b:args

View File

@ -13,15 +13,13 @@ After:
Execute(The flake8 callbacks should return the correct default values): Execute(The flake8 callbacks should return the correct default values):
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\] \]
" The version check should be cached. " The version check should be cached.
GivenCommandOutput [] GivenCommandOutput []
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\] \]
" Try with older versions. " Try with older versions.
@ -29,13 +27,14 @@ Execute(The flake8 callbacks should return the correct default values):
GivenCommandOutput ['2.9.9'] GivenCommandOutput ['2.9.9']
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('flake8') . ' --format=default -',
\ . ale#Escape('flake8') . ' --format=default -',
\] \]
Execute(The option for disabling changing directories should work): Execute(The option for disabling changing directories should work):
let g:ale_python_flake8_change_directory = 'off' let g:ale_python_flake8_change_directory = 'off'
AssertLinterCwd ['', '']
call ale#semver#ResetVersionCache()
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
@ -43,6 +42,7 @@ Execute(The option for disabling changing directories should work):
let g:ale_python_flake8_change_directory = 0 let g:ale_python_flake8_change_directory = 0
AssertLinterCwd ['']
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\] \]
@ -50,6 +50,7 @@ Execute(The option for disabling changing directories should work):
" Invalid options should be considered the same as turning the setting off. " Invalid options should be considered the same as turning the setting off.
let g:ale_python_flake8_change_directory = 'xxx' let g:ale_python_flake8_change_directory = 'xxx'
AssertLinterCwd ['']
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\] \]
@ -57,10 +58,11 @@ Execute(The option for disabling changing directories should work):
Execute(The option for changing directory to project root should work): Execute(The option for changing directory to project root should work):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_tox/namespace/foo/bar.py') silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_tox/namespace/foo/bar.py')
AssertLinterCwd ale#python#FindProjectRootIni(bufnr(''))
call ale#semver#ResetVersionCache()
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#CdString(ale#python#FindProjectRootIni(bufnr(''))) \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\] \]
Execute(The option for changing directory to file dir should work): Execute(The option for changing directory to file dir should work):
@ -69,15 +71,13 @@ Execute(The option for changing directory to file dir should work):
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\] \]
let g:ale_python_flake8_change_directory = 1 let g:ale_python_flake8_change_directory = 1
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\] \]
Execute(The flake8 command callback should let you set options): Execute(The flake8 command callback should let you set options):
@ -86,8 +86,7 @@ Execute(The flake8 command callback should let you set options):
GivenCommandOutput ['3.0.4'] GivenCommandOutput ['3.0.4']
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('flake8') . ' --some-option'
\ . ale#Escape('flake8') . ' --some-option'
\ . ' --format=default --stdin-display-name %s -', \ . ' --format=default --stdin-display-name %s -',
\] \]
@ -95,17 +94,17 @@ Execute(The flake8 command callback should let you set options):
GivenCommandOutput ['2.9.9'] GivenCommandOutput ['2.9.9']
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('flake8') . ' --some-option --format=default -',
\ . ale#Escape('flake8') . ' --some-option --format=default -',
\] \]
Execute(You should be able to set a custom executable and it should be escaped): Execute(You should be able to set a custom executable and it should be escaped):
let g:ale_python_flake8_executable = 'executable with spaces' let g:ale_python_flake8_executable = 'executable with spaces'
AssertLinterCwd ['%s:h', '%s:h']
call ale#semver#ResetVersionCache()
AssertLinter 'executable with spaces', [ AssertLinter 'executable with spaces', [
\ ale#Escape('executable with spaces') . ' --version', \ ale#Escape('executable with spaces') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('executable with spaces')
\ . ale#Escape('executable with spaces')
\ . ' --format=default' \ . ' --format=default'
\ . ' --stdin-display-name %s -', \ . ' --stdin-display-name %s -',
\] \]
@ -119,8 +118,7 @@ Execute(The flake8 callbacks should detect virtualenv directories):
AssertLinter b:executable, [ AssertLinter b:executable, [
\ ale#Escape(b:executable) . ' --version', \ ale#Escape(b:executable) . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape(b:executable)
\ . ale#Escape(b:executable)
\ . ' --format=default' \ . ' --format=default'
\ . ' --stdin-display-name %s -', \ . ' --stdin-display-name %s -',
\] \]
@ -170,8 +168,7 @@ Execute(Using `python -m flake8` should be supported for running flake8):
GivenCommandOutput ['2.9.9'] GivenCommandOutput ['2.9.9']
AssertLinter 'python', [ AssertLinter 'python', [
\ ale#Escape('python') . ' -m flake8 --version', \ ale#Escape('python') . ' -m flake8 --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('python')
\ . ale#Escape('python')
\ . ' -m flake8 --some-option --format=default -' \ . ' -m flake8 --some-option --format=default -'
\] \]
@ -183,8 +180,7 @@ Execute(Using `python -m flake8` should be supported for running flake8):
GivenCommandOutput ['2.9.9'] GivenCommandOutput ['2.9.9']
AssertLinter 'python', [ AssertLinter 'python', [
\ ale#Escape('python') . ' -m flake8 --version', \ ale#Escape('python') . ' -m flake8 --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('python')
\ . ale#Escape('python')
\ . ' -m flake8 --some-option --format=default -' \ . ' -m flake8 --some-option --format=default -'
\] \]
@ -194,13 +190,12 @@ Execute(Setting executable to 'pipenv' should append 'run flake8'):
" FIXME: pipenv should check the version with flake8. " FIXME: pipenv should check the version with flake8.
GivenCommandOutput [] GivenCommandOutput []
AssertLinter 'path/to/pipenv', AssertLinter 'path/to/pipenv',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('path/to/pipenv') . ' run flake8 --format=default -'
\ . ale#Escape('path/to/pipenv') . ' run flake8 --format=default -'
Execute(Pipenv is detected when python_flake8_auto_pipenv is set): Execute(Pipenv is detected when python_flake8_auto_pipenv is set):
let g:ale_python_flake8_auto_pipenv = 1 let g:ale_python_flake8_auto_pipenv = 1
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinterCwd ale#python#FindProjectRootIni(bufnr(''))
AssertLinter 'pipenv', AssertLinter 'pipenv',
\ ale#path#CdString(ale#python#FindProjectRootIni(bufnr(''))) \ ale#Escape('pipenv') . ' run flake8 --format=default --stdin-display-name %s -'
\ . ale#Escape('pipenv') . ' run flake8 --format=default --stdin-display-name %s -'

View File

@ -9,33 +9,25 @@ After:
Restore Restore
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default commands should be correct): Execute(The default command should be correct):
AssertLinter 'go', AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) AssertLinter 'go', 'go test -c -o /dev/null ./'
\ . 'go test -c -o /dev/null ./'
Execute(Go environment variables should be supported): Execute(Go environment variables should be supported):
let b:ale_go_go111module = 'on' let b:ale_go_go111module = 'on'
AssertLinter 'go', AssertLinter 'go', ale#Env('GO111MODULE', 'on') . 'go test -c -o /dev/null ./'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Env('GO111MODULE', 'on')
\ . 'go test -c -o /dev/null ./'
unlet! b:ale_go_go111module unlet! b:ale_go_go111module
Execute(Extra options should be supported): Execute(Extra options should be supported):
let g:ale_go_gobuild_options = '--foo-bar' let g:ale_go_gobuild_options = '--foo-bar'
AssertLinter 'go', AssertLinter 'go', 'go test --foo-bar -c -o /dev/null ./'
\ ale#path#BufferCdString(bufnr(''))
\ . 'go test --foo-bar -c -o /dev/null ./'
let g:ale_go_gobuild_options = '' let g:ale_go_gobuild_options = ''
Execute(The executable should be configurable): Execute(The executable should be configurable):
let g:ale_go_go_executable = 'foobar' let g:ale_go_go_executable = 'foobar'
AssertLinter 'foobar', AssertLinter 'foobar', 'foobar test -c -o /dev/null ./'
\ ale#path#BufferCdString(bufnr(''))
\ . 'foobar test -c -o /dev/null ./'

View File

@ -12,9 +12,9 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The golangci-lint defaults should be correct): Execute(The golangci-lint defaults should be correct):
AssertLinterCwd '%s:h',
AssertLinter 'golangci-lint', AssertLinter 'golangci-lint',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('golangci-lint')
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#Escape(expand('%' . ':t')) \ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --enable-all' \ . ' --enable-all'
@ -22,8 +22,7 @@ Execute(The golangci-lint callback should use a configured executable):
let b:ale_go_golangci_lint_executable = 'something else' let b:ale_go_golangci_lint_executable = 'something else'
AssertLinter 'something else', AssertLinter 'something else',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('something else')
\ . ale#Escape('something else')
\ . ' run ' . ale#Escape(expand('%' . ':t')) \ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --enable-all' \ . ' --enable-all'
@ -31,8 +30,7 @@ Execute(The golangci-lint callback should use configured options):
let b:ale_go_golangci_lint_options = '--foobar' let b:ale_go_golangci_lint_options = '--foobar'
AssertLinter 'golangci-lint', AssertLinter 'golangci-lint',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('golangci-lint')
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#Escape(expand('%' . ':t')) \ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --foobar' \ . ' --foobar'
@ -40,8 +38,7 @@ Execute(The golangci-lint callback should support environment variables):
let b:ale_go_go111module = 'on' let b:ale_go_go111module = 'on'
AssertLinter 'golangci-lint', AssertLinter 'golangci-lint',
\ ale#path#BufferCdString(bufnr('')) \ ale#Env('GO111MODULE', 'on')
\ . ale#Env('GO111MODULE', 'on')
\ . ale#Escape('golangci-lint') \ . ale#Escape('golangci-lint')
\ . ' run ' . ale#Escape(expand('%' . ':t')) \ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --enable-all' \ . ' --enable-all'
@ -50,5 +47,4 @@ Execute(The golangci-lint `lint_package` option should use the correct command):
let b:ale_go_golangci_lint_package = 1 let b:ale_go_golangci_lint_package = 1
AssertLinter 'golangci-lint', AssertLinter 'golangci-lint',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('golangci-lint') . ' run --enable-all'
\ . ale#Escape('golangci-lint') . ' run --enable-all'

View File

@ -12,9 +12,9 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The gometalinter defaults should be correct): Execute(The gometalinter defaults should be correct):
AssertLinterCwd '%s:h',
AssertLinter 'gometalinter', AssertLinter 'gometalinter',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('gometalinter')
\ . ale#Escape('gometalinter')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' .' \ . ' .'
@ -22,8 +22,7 @@ Execute(The gometalinter callback should use a configured executable):
let b:ale_go_gometalinter_executable = 'something else' let b:ale_go_gometalinter_executable = 'something else'
AssertLinter 'something else', AssertLinter 'something else',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('something else')
\ . ale#Escape('something else')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' .' \ . ' .'
@ -31,8 +30,7 @@ Execute(The gometalinter callback should use configured options):
let b:ale_go_gometalinter_options = '--foobar' let b:ale_go_gometalinter_options = '--foobar'
AssertLinter 'gometalinter', AssertLinter 'gometalinter',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('gometalinter')
\ . ale#Escape('gometalinter')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' --foobar' . ' .' \ . ' --foobar' . ' .'
@ -40,8 +38,7 @@ Execute(The gometalinter should use configured environment variables):
let b:ale_go_go111module = 'off' let b:ale_go_go111module = 'off'
AssertLinter 'gometalinter', AssertLinter 'gometalinter',
\ ale#path#BufferCdString(bufnr('')) \ ale#Env('GO111MODULE', 'off')
\ . ale#Env('GO111MODULE', 'off')
\ . ale#Escape('gometalinter') \ . ale#Escape('gometalinter')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' .' \ . ' .'
@ -49,6 +46,4 @@ Execute(The gometalinter should use configured environment variables):
Execute(The gometalinter `lint_package` option should use the correct command): Execute(The gometalinter `lint_package` option should use the correct command):
let b:ale_go_gometalinter_lint_package = 1 let b:ale_go_gometalinter_lint_package = 1
AssertLinter 'gometalinter', AssertLinter 'gometalinter', ale#Escape('gometalinter') . ' .'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('gometalinter') . ' .'

View File

@ -10,13 +10,10 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default gosimple command should be correct): Execute(The default gosimple command should be correct):
AssertLinter 'gosimple', AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) AssertLinter 'gosimple', 'gosimple .'
\ . ' gosimple .'
Execute(The gosimple command should support Go environment variables): Execute(The gosimple command should support Go environment variables):
let b:ale_go_go111module = 'on' let b:ale_go_go111module = 'on'
AssertLinter 'gosimple', AssertLinter 'gosimple', ale#Env('GO111MODULE', 'on') . 'gosimple .'
\ ale#path#BufferCdString(bufnr(''))
\ . ' ' . ale#Env('GO111MODULE', 'on') . 'gosimple .'

View File

@ -10,19 +10,15 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default gotype command should be correct): Execute(The default gotype command should be correct):
AssertLinter 'gotype', AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) AssertLinter 'gotype', 'gotype -e .'
\ . ' gotype -e .'
Execute(The gotype callback should ignore test files): Execute(The gotype callback should ignore test files):
call ale#test#SetFilename('bla_test.go') call ale#test#SetFilename('bla_test.go')
AssertLinter 'gotype', '' AssertLinterNotExecuted
Execute(The gotype callback should support Go environment variables): Execute(The gotype callback should support Go environment variables):
let b:ale_go_go111module = 'on' let b:ale_go_go111module = 'on'
AssertLinter 'gotype', AssertLinter 'gotype', ale#Env('GO111MODULE', 'on') . 'gotype -e .'
\ ale#path#BufferCdString(bufnr(''))
\ . ' ' . ale#Env('GO111MODULE', 'on')
\ . 'gotype -e .'

View File

@ -13,22 +13,20 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default command should be correct): Execute(The default command should be correct):
AssertLinter 'go', ale#path#BufferCdString(bufnr('')) . ' go vet .' AssertLinter 'go', 'go vet .'
Execute(Extra options should be supported): Execute(Extra options should be supported):
let g:ale_go_govet_options = '--foo-bar' let g:ale_go_govet_options = '--foo-bar'
AssertLinter 'go', ale#path#BufferCdString(bufnr('')) . ' go vet --foo-bar .' AssertLinterCwd '%s:h'
AssertLinter 'go', 'go vet --foo-bar .'
Execute(The executable should be configurable): Execute(The executable should be configurable):
let g:ale_go_go_executable = 'foobar' let g:ale_go_go_executable = 'foobar'
AssertLinter 'foobar', ale#path#BufferCdString(bufnr('')) . ' foobar vet .' AssertLinter 'foobar', 'foobar vet .'
Execute(Go environment variables should be supported): Execute(Go environment variables should be supported):
let b:ale_go_go111module = 'on' let b:ale_go_go111module = 'on'
AssertLinter 'go', AssertLinter 'go', ale#Env('GO111MODULE', 'on') . 'go vet .'
\ ale#path#BufferCdString(bufnr('')) . ' '
\ . ale#Env('GO111MODULE', 'on')
\ . 'go vet .'

View File

@ -5,7 +5,5 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The linter should run from the directory of the file in the buffer): Execute(The linter should run from the directory of the file in the buffer):
AssertLinter 'gqlint', AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) AssertLinter 'gqlint', 'gqlint --reporter=simple %t'
\ . 'gqlint --reporter=simple'
\ . ' %t'

View File

@ -1,23 +1,13 @@
Before: Before:
Save g:ale_haskell_cabal_ghc_options call ale#assert#SetUpLinterTest('haskell', 'cabal_ghc')
unlet! g:ale_haskell_cabal_ghc_options
unlet! b:ale_haskell_cabal_ghc_options
runtime ale_linters/haskell/cabal_ghc.vim
After: After:
Restore call ale#assert#TearDownLinterTest()
unlet! b:ale_haskell_cabal_ghc_options
call ale#linter#Reset()
Execute(The options should be used in the command): Execute(The options should be used in the command):
AssertEqual AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) . 'cabal exec -- ghc -fno-code -v0 %t', AssertLinter 'cabal', 'cabal exec -- ghc -fno-code -v0 %t'
\ ale_linters#haskell#cabal_ghc#GetCommand(bufnr(''))
let b:ale_haskell_cabal_ghc_options = 'foobar' let b:ale_haskell_cabal_ghc_options = 'foobar'
AssertEqual AssertLinter 'cabal', 'cabal exec -- ghc foobar %t'
\ ale#path#BufferCdString(bufnr('')) . 'cabal exec -- ghc foobar %t',
\ ale_linters#haskell#cabal_ghc#GetCommand(bufnr(''))

View File

@ -10,8 +10,9 @@ Execute(The linter should not be executed when there's no stack.yaml file):
Execute(The linter should be executed when there is a stack.yaml file): Execute(The linter should be executed when there is a stack.yaml file):
call ale#test#SetFilename('stack_ghc_paths/test.hs') call ale#test#SetFilename('stack_ghc_paths/test.hs')
AssertLinter 'stack', ale#path#BufferCdString(bufnr('')) . 'stack ghc -- -fno-code -v0 %t' AssertLinterCwd '%s:h'
AssertLinter 'stack', 'stack ghc -- -fno-code -v0 %t'
let b:ale_haskell_stack_ghc_options = 'foobar' let b:ale_haskell_stack_ghc_options = 'foobar'
AssertLinter 'stack', ale#path#BufferCdString(bufnr('')) . 'stack ghc -- foobar %t' AssertLinter 'stack', 'stack ghc -- foobar %t'

View File

@ -3,8 +3,7 @@ Before:
call ale#test#SetFilename('dummy.java') call ale#test#SetFilename('dummy.java')
let g:cp_sep = has('unix') ? ':' : ';' let g:cp_sep = has('unix') ? ':' : ';'
let g:prefix = ale#path#BufferCdString(bufnr('')) let g:prefix = ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
function! GetCommand(previous_output) abort function! GetCommand(previous_output) abort
let l:command = ale_linters#java#javac#GetCommand( let l:command = ale_linters#java#javac#GetCommand(
@ -29,6 +28,7 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The javac callback should return the correct default value): Execute(The javac callback should return the correct default value):
AssertLinterCwd '%s:h'
AssertLinter 'javac', g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' AssertLinter 'javac', g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The javac callback should use string type g:ale_java_javac_classpath correctly): Execute(The javac callback should use string type g:ale_java_javac_classpath correctly):
@ -51,8 +51,7 @@ Execute(The executable should be configurable):
let g:ale_java_javac_executable = 'foobar' let g:ale_java_javac_executable = 'foobar'
AssertLinter 'foobar', AssertLinter 'foobar',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('foobar') . ' -Xlint'
\ . ale#Escape('foobar') . ' -Xlint'
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The javac callback should include discovered classpaths): Execute(The javac callback should include discovered classpaths):
@ -197,8 +196,7 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual AssertEqual
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([ \ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'), \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
@ -211,8 +209,7 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual AssertEqual
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([ \ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'), \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
@ -225,8 +222,7 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual AssertEqual
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([ \ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/') \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/')
@ -241,8 +237,7 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual AssertEqual
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([ \ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'), \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
@ -257,8 +252,7 @@ Execute(The javac callback should detect source directories):
call ale#engine#InitBufferInfo(bufnr('')) call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac', AssertLinter 'javac',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape( \ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/') \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
\ ) \ )
@ -277,8 +271,7 @@ Execute(The javac callback should combine detected source directories and classp
\], {}) \], {})
AssertEqual AssertEqual
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep)) \ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep))
\ . ' -sourcepath ' . ale#Escape( \ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/') \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
@ -300,8 +293,7 @@ Execute(The javac callback should include src/test/java for test paths):
call ale#engine#InitBufferInfo(bufnr('')) call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac', AssertLinter 'javac',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([ \ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/src/test/java/'), \ ale#path#Simplify(g:dir . '/java_paths/src/test/java/'),
@ -314,8 +306,7 @@ Execute(The javac callback should include src/main/jaxb when available):
call ale#engine#InitBufferInfo(bufnr('')) call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac', AssertLinter 'javac',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([ \ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/jaxb/'), \ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/jaxb/'),
@ -328,8 +319,7 @@ Execute(The javac callback should add -sourcepath even if src/java/main doesn't
call ale#engine#InitBufferInfo(bufnr('')) call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac', AssertLinter 'javac',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('javac') . ' -Xlint'
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([ \ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths_no_main/src/test/java/'), \ ale#path#Simplify(g:dir . '/java_paths_no_main/src/test/java/'),
\ ], g:cp_sep)) \ ], g:cp_sep))

View File

@ -5,9 +5,9 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default lintr command should be correct): Execute(The default lintr command should be correct):
AssertLinterCwd '%s:h'
AssertLinter 'Rscript', AssertLinter 'Rscript',
\ ale#path#BufferCdString(bufnr('')) \ 'Rscript --vanilla -e '
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));' \ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint(cache = FALSE, commandArgs(TRUE), ' \ . 'lint(cache = FALSE, commandArgs(TRUE), '
\ . 'with_defaults())') \ . 'with_defaults())')
@ -17,8 +17,7 @@ Execute(The lintr options should be configurable):
let b:ale_r_lintr_options = 'with_defaults(object_usage_linter = NULL)' let b:ale_r_lintr_options = 'with_defaults(object_usage_linter = NULL)'
AssertLinter 'Rscript', AssertLinter 'Rscript',
\ ale#path#BufferCdString(bufnr('')) \ 'Rscript --vanilla -e '
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));' \ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint(cache = FALSE, commandArgs(TRUE), ' \ . 'lint(cache = FALSE, commandArgs(TRUE), '
\ . 'with_defaults(object_usage_linter = NULL))') \ . 'with_defaults(object_usage_linter = NULL))')
@ -28,8 +27,7 @@ Execute(If the lint_package flag is set, lintr::lint_package should be called):
let b:ale_r_lintr_lint_package = 1 let b:ale_r_lintr_lint_package = 1
AssertLinter 'Rscript', AssertLinter 'Rscript',
\ ale#path#BufferCdString(bufnr('')) \ 'Rscript --vanilla -e '
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));' \ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint_package(cache = FALSE, ' \ . 'lint_package(cache = FALSE, '
\ . 'linters = with_defaults())') \ . 'linters = with_defaults())')

View File

@ -1,25 +1,22 @@
Before: Before:
call ale#assert#SetUpLinterTest('mercury', 'mmc') call ale#assert#SetUpLinterTest('mercury', 'mmc')
call ale#test#SetFilename('dummy')
After: After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default command should be correct): Execute(The default command should be correct):
AssertLinterCwd '%s:h'
AssertLinter 'mmc', AssertLinter 'mmc',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('mmc') . ' --errorcheck-only --make --output-compile-error-lines 100 %s:t:r'
\ . ale#Escape('mmc') . ' --errorcheck-only --make --output-compile-error-lines 100 dummy'
Execute(The executable should be configurable): Execute(The executable should be configurable):
let b:ale_mercury_mmc_executable = 'foo' let b:ale_mercury_mmc_executable = 'foo'
AssertLinter 'foo', AssertLinter 'foo',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('foo') . ' --errorcheck-only --make --output-compile-error-lines 100 %s:t:r'
\ . ale#Escape('foo') . ' --errorcheck-only --make --output-compile-error-lines 100 dummy'
Execute(The options should be configurable): Execute(The options should be configurable):
let b:ale_mercury_mmc_options = '--bar' let b:ale_mercury_mmc_options = '--bar'
AssertLinter 'mmc', AssertLinter 'mmc',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('mmc') . ' --errorcheck-only --bar %s:t:r'
\ . ale#Escape('mmc') . ' --errorcheck-only --bar dummy'

View File

@ -11,8 +11,9 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The mypy callbacks should return the correct default values): Execute(The mypy callbacks should return the correct default values):
AssertLinterCwd g:dir
AssertLinter 'mypy', AssertLinter 'mypy',
\ ale#path#CdString(g:dir) . ale#Escape('mypy') \ ale#Escape('mypy')
\ . ' --show-column-numbers' \ . ' --show-column-numbers'
\ . ' --shadow-file %s %t %s' \ . ' --shadow-file %s %t %s'
@ -20,7 +21,7 @@ Execute(The mypy executable should be configurable, and escaped properly):
let g:ale_python_mypy_executable = 'executable with spaces' let g:ale_python_mypy_executable = 'executable with spaces'
AssertLinter 'executable with spaces', AssertLinter 'executable with spaces',
\ ale#path#CdString(g:dir) . ale#Escape('executable with spaces') \ ale#Escape('executable with spaces')
\ . ' --show-column-numbers' \ . ' --show-column-numbers'
\ . ' --shadow-file %s %t %s' \ . ' --shadow-file %s %t %s'
@ -28,62 +29,62 @@ Execute(The mypy command callback should let you set options):
let g:ale_python_mypy_options = '--some-option' let g:ale_python_mypy_options = '--some-option'
AssertLinter 'mypy', AssertLinter 'mypy',
\ ale#path#CdString(g:dir) . ale#Escape('mypy') \ ale#Escape('mypy')
\ . ' --some-option' \ . ' --some-option'
\ . ' --show-column-numbers' \ . ' --show-column-numbers'
\ . ' --shadow-file %s %t %s' \ . ' --shadow-file %s %t %s'
Execute(The mypy command should switch directories to the detected project root): Execute(The mypy command should switch directories to the detected project root):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/no_virtualenv/subdir/foo/bar.py')
AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')
AssertLinter 'mypy', AssertLinter 'mypy',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) \ ale#Escape('mypy')
\ . ale#Escape('mypy')
\ . ' --show-column-numbers' \ . ' --show-column-numbers'
\ . ' --shadow-file %s %t %s' \ . ' --shadow-file %s %t %s'
Execute(The mypy callbacks should detect virtualenv directories and switch to the project root): Execute(The mypy callbacks should detect virtualenv directories and switch to the project root):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
let b:executable = ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/mypy') let b:executable = ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/mypy')
AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')
AssertLinter b:executable, AssertLinter b:executable,
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) \ ale#Escape(b:executable)
\ . ale#Escape(b:executable)
\ . ' --show-column-numbers' \ . ' --show-column-numbers'
\ . ' --shadow-file %s %t %s' \ . ' --shadow-file %s %t %s'
Execute(The mypy callbacks should cd to directory containing mypy.ini if found): Execute(The mypy callbacks should cd to directory containing mypy.ini if found):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py') call ale#test#SetFilename('python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py')
AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini')
AssertLinter 'mypy', AssertLinter 'mypy',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini')) \ ale#Escape('mypy')
\ . ale#Escape('mypy')
\ . ' --show-column-numbers' \ . ' --show-column-numbers'
\ . ' --shadow-file %s %t %s' \ . ' --shadow-file %s %t %s'
Execute(You should able able to use the global mypy instead): Execute(You should able able to use the global mypy instead):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
let g:ale_python_mypy_use_global = 1 let g:ale_python_mypy_use_global = 1
AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')
AssertLinter 'mypy', AssertLinter 'mypy',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) \ ale#Escape('mypy')
\ . ale#Escape('mypy')
\ . ' --show-column-numbers' \ . ' --show-column-numbers'
\ . ' --shadow-file %s %t %s' \ . ' --shadow-file %s %t %s'
Execute(Setting executable to 'pipenv' appends 'run mypy'): Execute(Setting executable to 'pipenv' appends 'run mypy'):
let g:ale_python_mypy_executable = 'path/to/pipenv' let g:ale_python_mypy_executable = 'path/to/pipenv'
AssertLinterCwd expand('#' . bufnr('') . ':p:h')
AssertLinter 'path/to/pipenv', AssertLinter 'path/to/pipenv',
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) \ ale#Escape('path/to/pipenv') . ' run mypy'
\ . ale#Escape('path/to/pipenv') . ' run mypy'
\ . ' --show-column-numbers --shadow-file %s %t %s' \ . ' --show-column-numbers --shadow-file %s %t %s'
Execute(Pipenv is detected when python_mypy_auto_pipenv is set): Execute(Pipenv is detected when python_mypy_auto_pipenv is set):
let g:ale_python_mypy_auto_pipenv = 1
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
let g:ale_python_mypy_auto_pipenv = 1
AssertLinterCwd expand('#' . bufnr('') . ':p:h')
AssertLinter 'pipenv', AssertLinter 'pipenv',
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) \ ale#Escape('pipenv') . ' run mypy --show-column-numbers --shadow-file %s %t %s'
\ . ale#Escape('pipenv') . ' run mypy --show-column-numbers --shadow-file %s %t %s'

View File

@ -11,8 +11,8 @@ Execute(The local phpcs executable should be used):
let g:executable = ale#path#Simplify(g:dir . '/../phpcs-test-files/project-with-phpcs/vendor/bin/phpcs') let g:executable = ale#path#Simplify(g:dir . '/../phpcs-test-files/project-with-phpcs/vendor/bin/phpcs')
AssertLinter g:executable, ale#path#BufferCdString(bufnr('')) AssertLinterCwd '%s:h'
\ . ale#Escape(g:executable) AssertLinter g:executable, ale#Escape(g:executable)
\ . ' -s --report=emacs --stdin-path=%s' \ . ' -s --report=emacs --stdin-path=%s'
Execute(use_global should override local executable detection): Execute(use_global should override local executable detection):
@ -20,27 +20,23 @@ Execute(use_global should override local executable detection):
call ale#test#SetFilename('../phpcs-test-files/project-with-phpcs/foo/test.php') call ale#test#SetFilename('../phpcs-test-files/project-with-phpcs/foo/test.php')
AssertLinter 'phpcs', ale#path#BufferCdString(bufnr('')) AssertLinter 'phpcs', ale#Escape('phpcs')
\ . ale#Escape('phpcs')
\ . ' -s --report=emacs --stdin-path=%s' \ . ' -s --report=emacs --stdin-path=%s'
Execute(Projects without local executables should use the global one): Execute(Projects without local executables should use the global one):
call ale#test#SetFilename('../phpcs-test-files/project-without-phpcs/foo/test.php') call ale#test#SetFilename('../phpcs-test-files/project-without-phpcs/foo/test.php')
AssertLinter 'phpcs', ale#path#BufferCdString(bufnr('')) AssertLinter 'phpcs', ale#Escape('phpcs')
\ . ale#Escape('phpcs')
\ . ' -s --report=emacs --stdin-path=%s' \ . ' -s --report=emacs --stdin-path=%s'
Execute(User provided options should be used): Execute(User provided options should be used):
let g:ale_php_phpcs_options = '--my-user-provided-option my-value' let g:ale_php_phpcs_options = '--my-user-provided-option my-value'
AssertLinter 'phpcs', ale#path#BufferCdString(bufnr('')) AssertLinter 'phpcs', ale#Escape('phpcs')
\ . ale#Escape('phpcs')
\ . ' -s --report=emacs --stdin-path=%s --my-user-provided-option my-value' \ . ' -s --report=emacs --stdin-path=%s --my-user-provided-option my-value'
Execute(The _standard option should be used): Execute(The _standard option should be used):
let g:ale_php_phpcs_standard = 'foobar' let g:ale_php_phpcs_standard = 'foobar'
AssertLinter 'phpcs', ale#path#BufferCdString(bufnr('')) AssertLinter 'phpcs', ale#Escape('phpcs')
\ . ale#Escape('phpcs')
\ . ' -s --report=emacs --stdin-path=%s --standard=' . ale#Escape('foobar') \ . ' -s --report=emacs --stdin-path=%s --standard=' . ale#Escape('foobar')

View File

@ -6,35 +6,28 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The pydocstyle command callback should return default string): Execute(The pydocstyle command callback should return default string):
AssertLinter 'pydocstyle', AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) AssertLinter 'pydocstyle', ale#Escape('pydocstyle') . ' %s:t'
\ . ale#Escape('pydocstyle') . ' %s:t'
Execute(The pydocstyle command callback should allow options): Execute(The pydocstyle command callback should allow options):
let g:ale_python_pydocstyle_options = '--verbose' let g:ale_python_pydocstyle_options = '--verbose'
AssertLinter 'pydocstyle', AssertLinter 'pydocstyle', ale#Escape('pydocstyle') . ' --verbose %s:t'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('pydocstyle') . ' --verbose %s:t'
Execute(The pydocstyle executable should be configurable): Execute(The pydocstyle executable should be configurable):
let g:ale_python_pydocstyle_executable = '~/.local/bin/pydocstyle' let g:ale_python_pydocstyle_executable = '~/.local/bin/pydocstyle'
AssertLinter '~/.local/bin/pydocstyle', AssertLinter '~/.local/bin/pydocstyle',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('~/.local/bin/pydocstyle') . ' %s:t'
\ . ale#Escape('~/.local/bin/pydocstyle') . ' %s:t'
Execute(Setting executable to 'pipenv' appends 'run pydocstyle'): Execute(Setting executable to 'pipenv' appends 'run pydocstyle'):
let g:ale_python_pydocstyle_executable = 'path/to/pipenv' let g:ale_python_pydocstyle_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv', AssertLinter 'path/to/pipenv',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('path/to/pipenv') . ' run pydocstyle %s:t'
\ . ale#Escape('path/to/pipenv') . ' run pydocstyle %s:t'
Execute(Pipenv is detected when python_pydocstyle_auto_pipenv is set): Execute(Pipenv is detected when python_pydocstyle_auto_pipenv is set):
let g:ale_python_pydocstyle_auto_pipenv = 1 let g:ale_python_pydocstyle_auto_pipenv = 1
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv', AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pydocstyle %s:t'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('pipenv') . ' run pydocstyle %s:t'

View File

@ -12,74 +12,65 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The pylama command callback should return a default): Execute(The default pylama command should be correct):
AssertLinter 'pylama', AssertLinterCwd ale#path#Simplify(g:dir)
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail
\ . ale#Escape('pylama') . b:command_tail
Execute(The option for disabling changing directories should work): Execute(The option for disabling changing directories should work):
let g:ale_python_pylama_change_directory = 0 let g:ale_python_pylama_change_directory = 0
AssertLinterCwd ''
AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail
Execute(The pylama executable should be configurable, and escaped properly): Execute(The pylama executable should be configurable, and escaped properly):
let g:ale_python_pylama_executable = 'executable with spaces' let g:ale_python_pylama_executable = 'executable with spaces'
AssertLinterCwd ale#path#Simplify(g:dir)
AssertLinter 'executable with spaces', AssertLinter 'executable with spaces',
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) \ ale#Escape('executable with spaces') . b:command_tail
\ . ale#Escape('executable with spaces') . b:command_tail
Execute(The pylama command callback should let you set options): Execute(The pylama command callback should let you set options):
let g:ale_python_pylama_options = '--some-option' let g:ale_python_pylama_options = '--some-option'
AssertLinter 'pylama', AssertLinterCwd ale#path#Simplify(g:dir)
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) AssertLinter 'pylama', ale#Escape('pylama') . ' --some-option' . b:command_tail
\ . ale#Escape('pylama') . ' --some-option' . b:command_tail
Execute(The pylama command callback should switch directories to the detected project root): Execute(The pylama command callback should switch directories to the detected project root):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py')
AssertLinter 'pylama', AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail
\ . ale#Escape('pylama') . b:command_tail
Execute(The pylama command callback shouldn't detect virtualenv directories where they don't exist): Execute(The pylama command callback shouldn't detect virtualenv directories where they don't exist):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/no_virtualenv/subdir/foo/bar.py')
AssertLinter 'pylama', AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail
\ . ale#Escape('pylama') . b:command_tail
Execute(The pylama command callback should detect virtualenv directories and switch to the project root): Execute(The pylama command callback should detect virtualenv directories and switch to the project root):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
let b:executable = ale#path#Simplify( let b:executable = ale#path#Simplify(
\ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/pylama' \ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/pylama'
\) \)
AssertLinter b:executable, AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) AssertLinter b:executable, ale#Escape(b:executable) . b:command_tail
\ . ale#Escape(b:executable) . b:command_tail
Execute(You should able able to use the global pylama instead): Execute(You should able able to use the global pylama instead):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
let g:ale_python_pylama_use_global = 1 let g:ale_python_pylama_use_global = 1
AssertLinter 'pylama', AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail
\ . ale#Escape('pylama') . b:command_tail
Execute(Setting executable to 'pipenv' appends 'run pylama'): Execute(Setting executable to 'pipenv' appends 'run pylama'):
let g:ale_python_pylama_executable = 'path/to/pipenv' let g:ale_python_pylama_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv', AssertLinter 'path/to/pipenv',
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) \ ale#Escape('path/to/pipenv') . ' run pylama' . b:command_tail
\ . ale#Escape('path/to/pipenv') . ' run pylama' . b:command_tail
Execute(Pipenv is detected when python_pylama_auto_pipenv is set): Execute(Pipenv is detected when python_pylama_auto_pipenv is set):
let g:ale_python_pylama_auto_pipenv = 1 let g:ale_python_pylama_auto_pipenv = 1
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv', AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pylama' . b:command_tail
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pipenv') . ' run pylama' . b:command_tail

View File

@ -18,75 +18,64 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The pylint callbacks should return the correct default values): Execute(The pylint callbacks should return the correct default values):
AssertLinter 'pylint', AssertLinterCwd expand('%:p:h')
\ ale#path#CdString(expand('%:p:h')) AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail
\ . ale#Escape('pylint') . b:command_tail
Execute(Pylint should run with the --from-stdin in new enough versions): Execute(Pylint should run with the --from-stdin in new enough versions):
GivenCommandOutput ['pylint 2.4.0'] GivenCommandOutput ['pylint 2.4.0']
AssertLinter 'pylint', AssertLinterCwd expand('%:p:h')
\ ale#path#CdString(expand('%:p:h')) AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail[:-3] . '--from-stdin %s'
\ . ale#Escape('pylint') . b:command_tail[:-3] . '--from-stdin %s'
Execute(The option for disabling changing directories should work): Execute(The option for disabling changing directories should work):
let g:ale_python_pylint_change_directory = 0 let g:ale_python_pylint_change_directory = 0
AssertLinterCwd ''
AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail
Execute(The pylint executable should be configurable, and escaped properly): Execute(The pylint executable should be configurable, and escaped properly):
let g:ale_python_pylint_executable = 'executable with spaces' let g:ale_python_pylint_executable = 'executable with spaces'
AssertLinter 'executable with spaces', AssertLinter 'executable with spaces', ale#Escape('executable with spaces') . b:command_tail
\ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('executable with spaces') . b:command_tail
Execute(The pylint command callback should let you set options): Execute(The pylint command callback should let you set options):
let g:ale_python_pylint_options = '--some-option' let g:ale_python_pylint_options = '--some-option'
AssertLinter 'pylint', AssertLinter 'pylint', ale#Escape('pylint') . ' --some-option' . b:command_tail
\ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('pylint') . ' --some-option' . b:command_tail
Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist): Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/no_virtualenv/subdir/foo/bar.py')
AssertLinter 'pylint', AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail
\ . ale#Escape('pylint') . b:command_tail
Execute(The pylint callbacks should detect virtualenv directories): Execute(The pylint callbacks should detect virtualenv directories):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
let b:executable = ale#path#Simplify( let b:executable = ale#path#Simplify(
\ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/pylint' \ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/pylint'
\) \)
AssertLinter b:executable, AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) AssertLinter b:executable, ale#Escape(b:executable) . b:command_tail
\ . ale#Escape(b:executable) . b:command_tail
Execute(You should able able to use the global pylint instead): Execute(You should able able to use the global pylint instead):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
let g:ale_python_pylint_use_global = 1 let g:ale_python_pylint_use_global = 1
AssertLinter 'pylint', AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail
\ . ale#Escape('pylint') . b:command_tail
Execute(Setting executable to 'pipenv' appends 'run pylint'): Execute(Setting executable to 'pipenv' appends 'run pylint'):
let g:ale_python_pylint_executable = 'path/to/pipenv' let g:ale_python_pylint_executable = 'path/to/pipenv'
let g:ale_python_pylint_use_global = 1
AssertLinter 'path/to/pipenv', AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run pylint'
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('path/to/pipenv') . ' run pylint'
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
Execute(Pipenv is detected when python_pylint_auto_pipenv is set): Execute(Pipenv is detected when python_pylint_auto_pipenv is set):
let g:ale_python_pylint_auto_pipenv = 1 let g:ale_python_pylint_auto_pipenv = 1
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv', AssertLinterCwd expand('%:p:h')
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pylint'
\ . ale#Escape('pipenv') . ' run pylint'
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'

View File

@ -5,9 +5,9 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default command should be correct): Execute(The default command should be correct):
AssertLinter 'ruby', ale#Escape('ruby') . ' -w -c %t' AssertLinter 'ruby', ale#Escape('ruby') . ' -w -c -T1 %t'
Execute(The executable should be configurable): Execute(The executable should be configurable):
let g:ale_ruby_ruby_executable = 'foobar' let g:ale_ruby_ruby_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar') . ' -w -c %t' AssertLinter 'foobar', ale#Escape('foobar') . ' -w -c -T1 %t'

View File

@ -2,67 +2,63 @@ Before:
call ale#assert#SetUpLinterTest('sh', 'shellcheck') call ale#assert#SetUpLinterTest('sh', 'shellcheck')
call ale#test#SetFilename('test.sh') call ale#test#SetFilename('test.sh')
let b:prefix = ale#path#BufferCdString(bufnr(''))
let b:suffix = ' -f gcc -' let b:suffix = ' -f gcc -'
After: After:
unlet! b:is_bash unlet! b:is_bash
unlet! b:prefix
unlet! b:suffix unlet! b:suffix
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default shellcheck command should be correct): Execute(The default shellcheck command should be correct):
AssertLinter 'shellcheck', b:prefix . ale#Escape('shellcheck') . b:suffix AssertLinterCwd '%s:h'
AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix
Execute(The option disabling changing directories should work): Execute(The option disabling changing directories should work):
let g:ale_sh_shellcheck_change_directory = 0 let g:ale_sh_shellcheck_change_directory = 0
AssertLinterCwd ''
AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix
Execute(The shellcheck command should accept options): Execute(The shellcheck command should accept options):
let b:ale_sh_shellcheck_options = '--foobar' let b:ale_sh_shellcheck_options = '--foobar'
AssertLinter 'shellcheck', AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' --foobar' . b:suffix
\ b:prefix . ale#Escape('shellcheck') . ' --foobar' . b:suffix
Execute(The shellcheck command should accept options and exclusions): Execute(The shellcheck command should accept options and exclusions):
let b:ale_sh_shellcheck_options = '--foobar' let b:ale_sh_shellcheck_options = '--foobar'
let b:ale_sh_shellcheck_exclusions = 'foo,bar' let b:ale_sh_shellcheck_exclusions = 'foo,bar'
AssertLinter 'shellcheck', AssertLinter 'shellcheck',
\ b:prefix . ale#Escape('shellcheck') . ' --foobar -e foo,bar' . b:suffix \ ale#Escape('shellcheck') . ' --foobar -e foo,bar' . b:suffix
Execute(The shellcheck command should include the dialect): Execute(The shellcheck command should include the dialect):
let b:is_bash = 1 let b:is_bash = 1
AssertLinter 'shellcheck', AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' -s bash' . b:suffix
\ b:prefix . ale#Escape('shellcheck') . ' -s bash' . b:suffix
Execute(The shellcheck command should use ale_sh_shellcheck_dialect): Execute(The shellcheck command should use ale_sh_shellcheck_dialect):
let b:ale_sh_shellcheck_dialect = 'ksh93' let b:ale_sh_shellcheck_dialect = 'ksh93'
AssertLinter 'shellcheck', AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' -s ksh93' . b:suffix
\ b:prefix . ale#Escape('shellcheck') . ' -s ksh93' . b:suffix
Execute(The shellcheck command should allow unspecified dialect): Execute(The shellcheck command should allow unspecified dialect):
let b:ale_sh_shellcheck_dialect = '' let b:ale_sh_shellcheck_dialect = ''
AssertLinter 'shellcheck', AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix
\ b:prefix . ale#Escape('shellcheck') . b:suffix
Execute(The shellcheck command should include the dialect before options and exclusions): Execute(The shellcheck command should include the dialect before options and exclusions):
let b:is_bash = 1 let b:is_bash = 1
let b:ale_sh_shellcheck_options = '--foobar' let b:ale_sh_shellcheck_options = '--foobar'
let b:ale_sh_shellcheck_exclusions = 'foo,bar' let b:ale_sh_shellcheck_exclusions = 'foo,bar'
AssertLinter 'shellcheck', b:prefix . ale#Escape('shellcheck') AssertLinter 'shellcheck', ale#Escape('shellcheck')
\ . ' -s bash --foobar -e foo,bar' \ . ' -s bash --foobar -e foo,bar'
\ . b:suffix \ . b:suffix
Execute(The -x option should be added when the version is new enough): Execute(The -x option should be added when the version is new enough):
AssertLinter 'shellcheck', [ AssertLinter 'shellcheck', [
\ ale#Escape('shellcheck') . ' --version', \ ale#Escape('shellcheck') . ' --version',
\ b:prefix . ale#Escape('shellcheck') . b:suffix, \ ale#Escape('shellcheck') . b:suffix,
\] \]
GivenCommandOutput [ GivenCommandOutput [
@ -73,13 +69,13 @@ Execute(The -x option should be added when the version is new enough):
\] \]
AssertLinter 'shellcheck', [ AssertLinter 'shellcheck', [
\ ale#Escape('shellcheck') . ' --version', \ ale#Escape('shellcheck') . ' --version',
\ b:prefix . ale#Escape('shellcheck') . ' -x' . b:suffix, \ ale#Escape('shellcheck') . ' -x' . b:suffix,
\] \]
" We should cache the version check " We should cache the version check
GivenCommandOutput [] GivenCommandOutput []
AssertLinter 'shellcheck', [ AssertLinter 'shellcheck', [
\ b:prefix . ale#Escape('shellcheck') . ' -x' . b:suffix, \ ale#Escape('shellcheck') . ' -x' . b:suffix,
\] \]
Execute(The -x option should not be added when the version is too old): Execute(The -x option should not be added when the version is too old):
@ -91,7 +87,7 @@ Execute(The -x option should not be added when the version is too old):
\] \]
AssertLinter 'shellcheck', [ AssertLinter 'shellcheck', [
\ ale#Escape('shellcheck') . ' --version', \ ale#Escape('shellcheck') . ' --version',
\ b:prefix . ale#Escape('shellcheck') . b:suffix, \ ale#Escape('shellcheck') . b:suffix,
\] \]
Execute(The version check shouldn't be run again for old versions): Execute(The version check shouldn't be run again for old versions):
@ -103,8 +99,8 @@ Execute(The version check shouldn't be run again for old versions):
\] \]
AssertLinter 'shellcheck', [ AssertLinter 'shellcheck', [
\ ale#Escape('shellcheck') . ' --version', \ ale#Escape('shellcheck') . ' --version',
\ b:prefix . ale#Escape('shellcheck') . b:suffix, \ ale#Escape('shellcheck') . b:suffix,
\] \]
AssertLinter 'shellcheck', [ AssertLinter 'shellcheck', [
\ b:prefix . ale#Escape('shellcheck') . b:suffix, \ ale#Escape('shellcheck') . b:suffix,
\] \]

View File

@ -10,39 +10,26 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The staticcheck callback should return the right defaults): Execute(The staticcheck callback should return the right defaults):
AssertLinter 'staticcheck', AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) AssertLinter 'staticcheck', 'staticcheck %s:t'
\ . 'staticcheck '
\ . ale#Escape(expand('%' . ':t'))
Execute(The staticcheck callback should use configured options): Execute(The staticcheck callback should use configured options):
let b:ale_go_staticcheck_options = '-test' let b:ale_go_staticcheck_options = '-test'
AssertLinter 'staticcheck', AssertLinter 'staticcheck', 'staticcheck -test %s:t'
\ ale#path#BufferCdString(bufnr(''))
\ . 'staticcheck '
\ . '-test ' . ale#Escape(expand('%' . ':t'))
Execute(The staticcheck `lint_package` option should use the correct command): Execute(The staticcheck `lint_package` option should use the correct command):
let b:ale_go_staticcheck_lint_package = 1 let b:ale_go_staticcheck_lint_package = 1
AssertLinter 'staticcheck', AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) AssertLinter 'staticcheck', 'staticcheck .'
\ . 'staticcheck .',
Execute(The staticcheck callback should use the `GO111MODULE` option if set): Execute(The staticcheck callback should use the `GO111MODULE` option if set):
let b:ale_go_go111module = 'off' let b:ale_go_go111module = 'off'
AssertLinter 'staticcheck', AssertLinter 'staticcheck', ale#Env('GO111MODULE', 'off') . 'staticcheck %s:t'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Env('GO111MODULE', 'off')
\ . 'staticcheck '
\ . ale#Escape(expand('%' . ':t'))
" Test with lint_package option set " Test with lint_package option set
let b:ale_go_staticcheck_lint_package = 1 let b:ale_go_staticcheck_lint_package = 1
AssertLinter 'staticcheck', AssertLinter 'staticcheck', ale#Env('GO111MODULE', 'off') . 'staticcheck .'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Env('GO111MODULE', 'off')
\ . 'staticcheck .'

View File

@ -6,22 +6,18 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The default tslint command should be correct): Execute(The default tslint command should be correct):
AssertLinter 'tslint', AssertLinterCwd '%s:h'
\ ale#path#BufferCdString(bufnr('')) AssertLinter 'tslint', ale#Escape('tslint') . ' --format json %t'
\ . ale#Escape('tslint') . ' --format json %t'
Execute(The rules directory option should be included if set): Execute(The rules directory option should be included if set):
let b:ale_typescript_tslint_rules_dir = '/foo/bar' let b:ale_typescript_tslint_rules_dir = '/foo/bar'
AssertLinter 'tslint', AssertLinter 'tslint',
\ ale#path#BufferCdString(bufnr('')) \ ale#Escape('tslint') . ' --format json'
\ . ale#Escape('tslint') . ' --format json'
\ . ' -r ' . ale#Escape('/foo/bar') \ . ' -r ' . ale#Escape('/foo/bar')
\ . ' %t' \ . ' %t'
Execute(The executable should be configurable and escaped): Execute(The executable should be configurable and escaped):
let b:ale_typescript_tslint_executable = 'foo bar' let b:ale_typescript_tslint_executable = 'foo bar'
AssertLinter 'foo bar', AssertLinter 'foo bar', ale#Escape('foo bar') . ' --format json %t'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('foo bar') . ' --format json %t'

View File

@ -11,58 +11,48 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The vulture command callback should lint file directory by default): Execute(The vulture command callback should lint file directory by default):
AssertLinter 'vulture', AssertLinterCwd expand('#' . bufnr('') . ':p:h')
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) AssertLinter 'vulture', ale#Escape('vulture') . ' .'
\ . ale#Escape('vulture') . ' .'
Execute(The vulture command callback should lint project root, when present): Execute(The vulture command callback should lint project root, when present):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/no_virtualenv/subdir/foo/bar.py')
AssertLinter 'vulture', AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) AssertLinter 'vulture', ale#Escape('vulture') . ' .'
\ . ale#Escape('vulture') . ' .'
Execute(The option for disabling change directory works and only lints file): Execute(The option for disabling change directory works and only lints file):
let g:ale_python_vulture_change_directory = 0 let g:ale_python_vulture_change_directory = 0
AssertLinterCwd ''
AssertLinter 'vulture', ale#Escape('vulture') . ' %s' AssertLinter 'vulture', ale#Escape('vulture') . ' %s'
Execute(The vulture executable should be configurable, and escaped properly): Execute(The vulture executable should be configurable, and escaped properly):
let g:ale_python_vulture_executable = 'executable with spaces' let g:ale_python_vulture_executable = 'executable with spaces'
AssertLinter 'executable with spaces', AssertLinter 'executable with spaces', ale#Escape('executable with spaces') . ' .'
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('executable with spaces') . ' .'
Execute(The vulture command callback should let you set options): Execute(The vulture command callback should let you set options):
let g:ale_python_vulture_options = '--some-option' let g:ale_python_vulture_options = '--some-option'
AssertLinter 'vulture', AssertLinter 'vulture', ale#Escape('vulture') . ' --some-option .'
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('vulture') . ' --some-option .'
Execute(The vulture command callback should detect virtualenv directories and switch to the project root): Execute(The vulture command callback should detect virtualenv directories and switch to the project root):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
let b:executable = ale#path#Simplify( let b:executable = ale#path#Simplify(
\ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/vulture' \ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/vulture'
\) \)
AssertLinter b:executable, AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) AssertLinter b:executable, ale#Escape(b:executable) . ' .'
\ . ale#Escape(b:executable) . ' .'
Execute(You should able able to use the global vulture instead): Execute(You should able able to use the global vulture instead):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
let g:ale_python_vulture_use_global = 1 let g:ale_python_vulture_use_global = 1
AssertLinter 'vulture', AssertLinter 'vulture', ale#Escape('vulture') . ' .'
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
\ . ale#Escape('vulture') . ' .'
Execute(Setting executable to 'pipenv' appends 'run vulture'): Execute(Setting executable to 'pipenv' appends 'run vulture'):
let g:ale_python_vulture_executable = 'path/to/pipenv' let g:ale_python_vulture_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv', AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run vulture' . ' .'
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('path/to/pipenv') . ' run vulture' . ' .'

View File

@ -28,8 +28,8 @@ Execute(The autoimport callback should return the correct default values):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual AssertEqual
\ { \ {
\ 'command': ale#path#BufferCdString(bufnr('')) \ 'cwd': '%s:h',
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) . ' -', \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) . ' -',
\ }, \ },
\ ale#fixers#autoimport#Fix(bufnr('')) \ ale#fixers#autoimport#Fix(bufnr(''))
@ -43,8 +43,8 @@ Execute(The autoimport callback should respect custom options):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual AssertEqual
\ { \ {
\ 'command': ale#path#BufferCdString(bufnr('')) \ 'cwd': '%s:h',
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport'))
\ . ' --multi-line=3 --trailing-comma -', \ . ' --multi-line=3 --trailing-comma -',
\ }, \ },
\ ale#fixers#autoimport#Fix(bufnr('')) \ ale#fixers#autoimport#Fix(bufnr(''))

View File

@ -1,30 +1,23 @@
Before: Before:
Save g:ale_python_black_executable call ale#assert#SetUpFixerTest('python', 'black')
Save g:ale_python_black_options
" Use an invalid global executable, so we don't match it.
let g:ale_python_black_executable = 'xxxinvalid'
let g:ale_python_black_options = ''
let g:ale_python_black_auto_pipenv = 0
call ale#test#SetDirectory('/testplugin/test/fixers')
silent cd .. silent cd ..
silent cd command_callback silent cd command_callback
let g:dir = getcwd() let g:dir = getcwd()
let b:bin_dir = has('win32') ? 'Scripts' : 'bin' let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
After: After:
Restore call ale#assert#TearDownFixerTest()
unlet! g:dir
unlet! b:bin_dir unlet! b:bin_dir
call ale#test#RestoreDirectory()
Execute(The black callback should return the correct default values): Execute(The black callback should return the correct default values):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual AssertEqual
\ {'command': ale#path#BufferCdString(bufnr('')) . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' -'}, \ {
\ 'cwd': '%s:h',
\ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' -'},
\ ale#fixers#black#Fix(bufnr('')) \ ale#fixers#black#Fix(bufnr(''))
Execute(The black callback should include options): Execute(The black callback should include options):
@ -40,6 +33,7 @@ Execute(The black callback should include --pyi for .pyi files):
let g:ale_python_black_change_directory = 0 let g:ale_python_black_change_directory = 0
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.pyi') silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.pyi')
AssertEqual AssertEqual
\ {'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' --pyi -' }, \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' --pyi -' },
\ ale#fixers#black#Fix(bufnr('')) \ ale#fixers#black#Fix(bufnr(''))
@ -48,7 +42,7 @@ Execute(Pipenv is detected when python_black_auto_pipenv is set):
let g:ale_python_black_auto_pipenv = 1 let g:ale_python_black_auto_pipenv = 1
let g:ale_python_black_change_directory = 0 let g:ale_python_black_change_directory = 0
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py') call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertEqual AssertEqual
\ {'command': ale#Escape('pipenv') . ' run black -'}, \ {'command': ale#Escape('pipenv') . ' run black -'},

Some files were not shown because too many files have changed in this diff Show More