summaryrefslogtreecommitdiff
path: root/ale_linters
diff options
context:
space:
mode:
Diffstat (limited to 'ale_linters')
-rw-r--r--ale_linters/c/clang.vim5
-rw-r--r--ale_linters/c/gcc.vim5
-rw-r--r--ale_linters/chef/cookstyle.vim54
-rw-r--r--ale_linters/cpp/clang.vim5
-rw-r--r--ale_linters/cpp/gcc.vim5
-rw-r--r--ale_linters/d/dmd.vim21
-rw-r--r--ale_linters/elixir/elixir_ls.vim2
-rw-r--r--ale_linters/elm/elm_lsp.vim22
-rw-r--r--ale_linters/erlang/syntaxerl.vim17
-rw-r--r--ale_linters/eruby/erubi.vim17
-rw-r--r--ale_linters/go/gotype.vim2
-rw-r--r--ale_linters/haml/hamllint.vim2
-rw-r--r--ale_linters/java/javac.vim28
-rwxr-xr-xale_linters/javascript/flow.vim36
-rw-r--r--ale_linters/json/jsonlint.vim23
-rw-r--r--ale_linters/kotlin/kotlinc.vim41
-rw-r--r--ale_linters/php/langserver.vim6
-rw-r--r--ale_linters/php/phpstan.vim37
-rw-r--r--ale_linters/powershell/psscriptanalyzer.vim105
-rw-r--r--ale_linters/python/flake8.vim30
-rw-r--r--ale_linters/ruby/rails_best_practices.vim4
-rw-r--r--ale_linters/ruby/reek.vim29
-rw-r--r--ale_linters/rust/cargo.vim28
-rw-r--r--ale_linters/sh/shellcheck.vim34
-rw-r--r--ale_linters/slim/slimlint.vim2
-rw-r--r--ale_linters/swift/sourcekitlsp.vim13
-rw-r--r--ale_linters/vim/vint.vim36
27 files changed, 373 insertions, 236 deletions
diff --git a/ale_linters/c/clang.vim b/ale_linters/c/clang.vim
index 5b243bfe..681101fc 100644
--- a/ale_linters/c/clang.vim
+++ b/ale_linters/c/clang.vim
@@ -19,9 +19,6 @@ call ale#linter#Define('c', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_clang_executable')},
-\ 'command_chain': [
-\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#c#clang#GetCommand'}
-\ ],
+\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clang#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})
diff --git a/ale_linters/c/gcc.vim b/ale_linters/c/gcc.vim
index ccb1912b..d965965d 100644
--- a/ale_linters/c/gcc.vim
+++ b/ale_linters/c/gcc.vim
@@ -19,9 +19,6 @@ call ale#linter#Define('c', {
\ 'name': 'gcc',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_gcc_executable')},
-\ 'command_chain': [
-\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#c#gcc#GetCommand'}
-\ ],
+\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#gcc#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})
diff --git a/ale_linters/chef/cookstyle.vim b/ale_linters/chef/cookstyle.vim
new file mode 100644
index 00000000..50bae2aa
--- /dev/null
+++ b/ale_linters/chef/cookstyle.vim
@@ -0,0 +1,54 @@
+" Author: Raphael Hoegger - https://github.com/pfuender
+" Description: Cookstyle (RuboCop based), a code style analyzer for Ruby files
+
+call ale#Set('chef_cookstyle_executable', 'cookstyle')
+call ale#Set('chef_cookstyle_options', '')
+
+function! ale_linters#chef#cookstyle#GetCommand(buffer) abort
+ let l:options = ale#Var(a:buffer, 'chef_cookstyle_options')
+
+ return '%e' . ale#Pad(escape(l:options, '~')) . ' --force-exclusion --format json --stdin ' . ' %s'
+endfunction
+
+function! ale_linters#chef#cookstyle#Handle(buffer, lines) abort
+ if len(a:lines) == 0
+ return []
+ endif
+
+ let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], {})
+
+ if !has_key(l:errors, 'summary')
+ \|| l:errors['summary']['offense_count'] == 0
+ \|| empty(l:errors['files'])
+ return []
+ endif
+
+ let l:output = []
+
+ for l:error in l:errors['files'][0]['offenses']
+ let l:start_col = str2nr(l:error['location']['start_column'])
+ let l:end_col = str2nr(l:error['location']['last_column'])
+
+ if !l:end_col
+ let l:end_col = l:start_col + 1
+ endif
+
+ call add(l:output, {
+ \ 'lnum': str2nr(l:error['location']['line']),
+ \ 'col': l:start_col,
+ \ 'end_col': l:end_col,
+ \ 'code': l:error['cop_name'],
+ \ 'text': l:error['message'],
+ \ 'type': l:error['severity'] is? 'convention' ? 'W' : 'E',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('chef', {
+\ 'name': 'cookstyle',
+\ 'executable': {b -> ale#Var(b, 'chef_cookstyle_executable')},
+\ 'command': function('ale_linters#chef#cookstyle#GetCommand'),
+\ 'callback': 'ale_linters#chef#cookstyle#Handle',
+\})
diff --git a/ale_linters/cpp/clang.vim b/ale_linters/cpp/clang.vim
index 5a465812..e48291eb 100644
--- a/ale_linters/cpp/clang.vim
+++ b/ale_linters/cpp/clang.vim
@@ -19,9 +19,6 @@ call ale#linter#Define('cpp', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'cpp_clang_executable')},
-\ 'command_chain': [
-\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#cpp#clang#GetCommand'},
-\ ],
+\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clang#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})
diff --git a/ale_linters/cpp/gcc.vim b/ale_linters/cpp/gcc.vim
index 831620d5..c427020b 100644
--- a/ale_linters/cpp/gcc.vim
+++ b/ale_linters/cpp/gcc.vim
@@ -20,9 +20,6 @@ call ale#linter#Define('cpp', {
\ 'aliases': ['g++'],
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'cpp_gcc_executable')},
-\ 'command_chain': [
-\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#cpp#gcc#GetCommand'},
-\ ],
+\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#gcc#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})
diff --git a/ale_linters/d/dmd.vim b/ale_linters/d/dmd.vim
index c816d592..14461ae6 100644
--- a/ale_linters/d/dmd.vim
+++ b/ale_linters/d/dmd.vim
@@ -1,7 +1,7 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: "dmd for D files"
-function! ale_linters#d#dmd#DUBCommand(buffer) abort
+function! ale_linters#d#dmd#GetDUBCommand(buffer) abort
" If we can't run dub, then skip this command.
if !executable('dub')
" Returning an empty string skips to the DMD command.
@@ -21,7 +21,18 @@ function! ale_linters#d#dmd#DUBCommand(buffer) abort
\ . ' && dub describe --import-paths'
endfunction
-function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort
+function! ale_linters#d#dmd#RunDUBCommand(buffer) abort
+ let l:command = ale_linters#d#dmd#GetDUBCommand(a:buffer)
+
+ if empty(l:command)
+ " If we can't run DUB, just run DMD.
+ return ale_linters#d#dmd#DMDCommand(a:buffer, [], {})
+ endif
+
+ return ale#command#Run(a:buffer, l:command, function('ale_linters#d#dmd#DMDCommand'))
+endfunction
+
+function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) abort
let l:import_list = []
" Build a list of import paths generated from DUB, if available.
@@ -57,9 +68,7 @@ endfunction
call ale#linter#Define('d', {
\ 'name': 'dmd',
\ 'executable': 'dmd',
-\ 'command_chain': [
-\ {'callback': 'ale_linters#d#dmd#DUBCommand', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#d#dmd#DMDCommand', 'output_stream': 'stderr'},
-\ ],
+\ 'command': function('ale_linters#d#dmd#RunDUBCommand'),
\ 'callback': 'ale_linters#d#dmd#Handle',
+\ 'output_stream': 'stderr',
\})
diff --git a/ale_linters/elixir/elixir_ls.vim b/ale_linters/elixir/elixir_ls.vim
index d5db7cd0..d5517de5 100644
--- a/ale_linters/elixir/elixir_ls.vim
+++ b/ale_linters/elixir/elixir_ls.vim
@@ -6,7 +6,7 @@ call ale#Set('elixir_elixir_ls_config', {})
function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort
let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_elixir_ls_release'))
- let l:cmd = ale#Has('win32') ? '\language_server.bat' : '/language_server.sh'
+ let l:cmd = has('win32') ? '\language_server.bat' : '/language_server.sh'
return l:dir . l:cmd
endfunction
diff --git a/ale_linters/elm/elm_lsp.vim b/ale_linters/elm/elm_lsp.vim
new file mode 100644
index 00000000..2259286f
--- /dev/null
+++ b/ale_linters/elm/elm_lsp.vim
@@ -0,0 +1,22 @@
+" Author: antew - https://github.com/antew
+" Description: LSP integration for elm, currently supports diagnostics (linting)
+
+call ale#Set('elm_lsp_executable', 'elm-lsp')
+call ale#Set('elm_lsp_use_global', get(g:, 'ale_use_global_executables', 0))
+
+function! elm_lsp#GetRootDir(buffer) abort
+ let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
+
+ return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
+endfunction
+
+call ale#linter#Define('elm', {
+\ 'name': 'elm_lsp',
+\ 'lsp': 'stdio',
+\ 'executable': {b -> ale#node#FindExecutable(b, 'elm_lsp', [
+\ 'node_modules/.bin/elm-lsp',
+\ ])},
+\ 'command': '%e --stdio',
+\ 'project_root': function('elm_lsp#GetRootDir'),
+\ 'language': 'elm'
+\})
diff --git a/ale_linters/erlang/syntaxerl.vim b/ale_linters/erlang/syntaxerl.vim
index 2b7276a1..5d555a8d 100644
--- a/ale_linters/erlang/syntaxerl.vim
+++ b/ale_linters/erlang/syntaxerl.vim
@@ -3,7 +3,17 @@
call ale#Set('erlang_syntaxerl_executable', 'syntaxerl')
-function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output) abort
+function! ale_linters#erlang#syntaxerl#RunHelpCommand(buffer) abort
+ let l:executable = ale#Var(a:buffer, 'erlang_syntaxerl_executable')
+
+ return ale#command#Run(
+ \ a:buffer,
+ \ ale#Escape(l:executable) . ' -h',
+ \ function('ale_linters#erlang#syntaxerl#GetCommand'),
+ \)
+endfunction
+
+function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output, meta) abort
let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1
return '%e' . (l:use_b_option ? ' -b %s %t' : ' %t')
@@ -27,9 +37,6 @@ endfunction
call ale#linter#Define('erlang', {
\ 'name': 'syntaxerl',
\ 'executable': {b -> ale#Var(b, 'erlang_syntaxerl_executable')},
-\ 'command_chain': [
-\ {'callback': {-> '%e -h'}},
-\ {'callback': 'ale_linters#erlang#syntaxerl#GetCommand'},
-\ ],
+\ 'command': {b -> ale_linters#erlang#syntaxerl#RunHelpCommand(b)},
\ 'callback': 'ale_linters#erlang#syntaxerl#Handle',
\})
diff --git a/ale_linters/eruby/erubi.vim b/ale_linters/eruby/erubi.vim
index 6f2d3ac6..ddca3f61 100644
--- a/ale_linters/eruby/erubi.vim
+++ b/ale_linters/eruby/erubi.vim
@@ -1,14 +1,10 @@
" Author: Eddie Lebow https://github.com/elebow
" Description: eruby checker using `erubi`
-function! ale_linters#eruby#erubi#CheckErubi(buffer) abort
- return 'ruby -r erubi/capture_end -e ' . ale#Escape('""')
-endfunction
-
-function! ale_linters#eruby#erubi#GetCommand(buffer, check_erubi_output) abort
+function! ale_linters#eruby#erubi#GetCommand(buffer, output, meta) abort
let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
- if (!empty(a:check_erubi_output))
+ if !empty(a:output)
" The empty command in CheckErubi returns nothing if erubi runs and
" emits an error if erubi is not present
return ''
@@ -27,9 +23,10 @@ endfunction
call ale#linter#Define('eruby', {
\ 'name': 'erubi',
\ 'executable': 'ruby',
-\ 'command_chain': [
-\ {'callback': 'ale_linters#eruby#erubi#CheckErubi'},
-\ {'callback': 'ale_linters#eruby#erubi#GetCommand', 'output_stream': 'stderr'},
-\ ],
+\ 'command': {buffer -> ale#command#Run(
+\ buffer,
+\ 'ruby -r erubi/capture_end -e ' . ale#Escape('""'),
+\ function('ale_linters#eruby#erubi#GetCommand'),
+\ )},
\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
\})
diff --git a/ale_linters/go/gotype.vim b/ale_linters/go/gotype.vim
index 159df892..d5d563aa 100644
--- a/ale_linters/go/gotype.vim
+++ b/ale_linters/go/gotype.vim
@@ -6,7 +6,7 @@ function! ale_linters#go#gotype#GetCommand(buffer) abort
return ''
endif
- return ale#path#BufferCdString(a:buffer) . ' gotype .'
+ return ale#path#BufferCdString(a:buffer) . ' gotype -e .'
endfunction
call ale#linter#Define('go', {
diff --git a/ale_linters/haml/hamllint.vim b/ale_linters/haml/hamllint.vim
index 7d7278aa..9fcd999f 100644
--- a/ale_linters/haml/hamllint.vim
+++ b/ale_linters/haml/hamllint.vim
@@ -19,7 +19,7 @@ function! ale_linters#haml#hamllint#GetCommand(buffer) abort
" See https://github.com/brigade/haml-lint/blob/master/lib/haml_lint/linter/rubocop.rb#L89
" HamlLint::Linter::RuboCop#rubocop_flags
if !empty(l:rubocop_config_file_path)
- if ale#Has('win32')
+ if has('win32')
let l:prefix = 'set HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path) . ' &&'
else
let l:prefix = 'HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path)
diff --git a/ale_linters/java/javac.vim b/ale_linters/java/javac.vim
index 50cabacd..7ca95ba5 100644
--- a/ale_linters/java/javac.vim
+++ b/ale_linters/java/javac.vim
@@ -7,21 +7,29 @@ call ale#Set('java_javac_executable', 'javac')
call ale#Set('java_javac_options', '')
call ale#Set('java_javac_classpath', '')
-function! ale_linters#java#javac#GetImportPaths(buffer) abort
+function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
+ let l:command = ''
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path) && executable('mvn')
- return ale#path#CdString(fnamemodify(l:pom_path, ':h'))
+ let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath'
endif
- let l:classpath_command = ale#gradle#BuildClasspathCommand(a:buffer)
+ " Try to use Gradle if Maven isn't available.
+ if empty(l:command)
+ let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
+ endif
- if !empty(l:classpath_command)
- return l:classpath_command
+ if empty(l:command)
+ return ale_linters#java#javac#GetCommand(a:buffer, [], {})
endif
- return ''
+ return ale#command#Run(
+ \ a:buffer,
+ \ l:command,
+ \ function('ale_linters#java#javac#GetCommand')
+ \)
endfunction
function! s:BuildClassPathOption(buffer, import_paths) abort
@@ -37,7 +45,7 @@ function! s:BuildClassPathOption(buffer, import_paths) abort
\ : ''
endfunction
-function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort
+function! ale_linters#java#javac#GetCommand(buffer, import_paths, meta) abort
let l:cp_option = s:BuildClassPathOption(a:buffer, a:import_paths)
let l:sp_option = ''
@@ -120,9 +128,7 @@ endfunction
call ale#linter#Define('java', {
\ 'name': 'javac',
\ 'executable': {b -> ale#Var(b, 'java_javac_executable')},
-\ 'command_chain': [
-\ {'callback': 'ale_linters#java#javac#GetImportPaths', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#java#javac#GetCommand', 'output_stream': 'stderr'},
-\ ],
+\ 'command': function('ale_linters#java#javac#RunWithImportPaths'),
+\ 'output_stream': 'stderr',
\ 'callback': 'ale_linters#java#javac#Handle',
\})
diff --git a/ale_linters/javascript/flow.vim b/ale_linters/javascript/flow.vim
index 05aae030..3135e2e9 100755
--- a/ale_linters/javascript/flow.vim
+++ b/ale_linters/javascript/flow.vim
@@ -27,32 +27,13 @@ function! ale_linters#javascript#flow#GetExecutable(buffer) abort
\])
endfunction
-function! ale_linters#javascript#flow#VersionCheck(buffer) abort
- let l:executable = ale_linters#javascript#flow#GetExecutable(a:buffer)
-
- if empty(l:executable)
- return ''
- endif
-
- return ale#Escape(l:executable) . ' --version'
-endfunction
-
-function! ale_linters#javascript#flow#GetCommand(buffer, version_lines) abort
- let l:executable = ale_linters#javascript#flow#GetExecutable(a:buffer)
-
- if empty(l:executable)
- return ''
- endif
-
- let l:version = ale#semver#GetVersion(l:executable, a:version_lines)
-
+function! ale_linters#javascript#flow#GetCommand(buffer, version) abort
" If we can parse the version number, then only use --respect-pragma
" if the version is >= 0.36.0, which added the argument.
let l:use_respect_pragma = ale#Var(a:buffer, 'javascript_flow_use_respect_pragma')
- \ && (empty(l:version) || ale#semver#GTE(l:version, [0, 36]))
+ \ && (empty(a:version) || ale#semver#GTE(a:version, [0, 36]))
- return ale#Escape(l:executable)
- \ . ' check-contents'
+ return '%e check-contents'
\ . (l:use_respect_pragma ? ' --respect-pragma': '')
\ . ' --json --from ale %s < %t'
\ . (!has('win32') ? '; echo' : '')
@@ -87,7 +68,6 @@ function! s:ExtraErrorMsg(current, new) abort
return l:newMsg
endfunction
-
function! s:GetDetails(error) abort
let l:detail = ''
@@ -169,10 +149,12 @@ endfunction
call ale#linter#Define('javascript', {
\ 'name': 'flow',
\ 'executable': function('ale_linters#javascript#flow#GetExecutable'),
-\ 'command_chain': [
-\ {'callback': 'ale_linters#javascript#flow#VersionCheck'},
-\ {'callback': 'ale_linters#javascript#flow#GetCommand'},
-\ ],
+\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
+\ buffer,
+\ ale_linters#javascript#flow#GetExecutable(buffer),
+\ '%e --version',
+\ function('ale_linters#javascript#flow#GetCommand'),
+\ )},
\ 'callback': 'ale_linters#javascript#flow#Handle',
\ 'read_buffer': 0,
\})
diff --git a/ale_linters/json/jsonlint.vim b/ale_linters/json/jsonlint.vim
index f01553d6..f677b488 100644
--- a/ale_linters/json/jsonlint.vim
+++ b/ale_linters/json/jsonlint.vim
@@ -1,4 +1,21 @@
-" Author: KabbAmine <amine.kabb@gmail.com>
+" Author: KabbAmine <amine.kabb@gmail.com>, David Sierra <https://github.com/davidsierradz>
+
+call ale#Set('json_jsonlint_executable', 'jsonlint')
+call ale#Set('json_jsonlint_use_global', get(g:, 'ale_use_global_executables', 0))
+
+function! ale_linters#json#jsonlint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'json_jsonlint', [
+ \ 'node_modules/.bin/jsonlint',
+ \ 'node_modules/jsonlint/lib/cli.js',
+ \])
+endfunction
+
+function! ale_linters#json#jsonlint#GetCommand(buffer) abort
+ let l:executable = ale_linters#json#jsonlint#GetExecutable(a:buffer)
+
+ return ale#node#Executable(a:buffer, l:executable)
+ \ . ' --compact -'
+endfunction
function! ale_linters#json#jsonlint#Handle(buffer, lines) abort
" Matches patterns like the following:
@@ -19,8 +36,8 @@ endfunction
call ale#linter#Define('json', {
\ 'name': 'jsonlint',
-\ 'executable': 'jsonlint',
+\ 'executable': function('ale_linters#json#jsonlint#GetExecutable'),
\ 'output_stream': 'stderr',
-\ 'command': 'jsonlint --compact -',
+\ 'command': function('ale_linters#json#jsonlint#GetCommand'),
\ 'callback': 'ale_linters#json#jsonlint#Handle',
\})
diff --git a/ale_linters/kotlin/kotlinc.vim b/ale_linters/kotlin/kotlinc.vim
index 32dcc6d1..fddd6625 100644
--- a/ale_linters/kotlin/kotlinc.vim
+++ b/ale_linters/kotlin/kotlinc.vim
@@ -11,26 +11,33 @@ let g:ale_kotlin_kotlinc_module_filename = get(g:, 'ale_kotlin_kotlinc_module_fi
let s:classpath_sep = has('unix') ? ':' : ';'
-function! ale_linters#kotlin#kotlinc#GetImportPaths(buffer) abort
+function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort
" exec maven/gradle only if classpath is not set
if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# ''
- return ''
- else
- let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
+ return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {})
+ endif
- if !empty(l:pom_path) && executable('mvn')
- return ale#path#CdString(fnamemodify(l:pom_path, ':h'))
- \ . 'mvn dependency:build-classpath'
- endif
+ let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
- let l:classpath_command = ale#gradle#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
- if !empty(l:classpath_command)
- return l:classpath_command
- endif
+ " Try to use Gradle if Maven isn't available.
+ if empty(l:command)
+ let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
+ endif
- return ''
+ if empty(l:command)
+ return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {})
endif
+
+ return ale#command#Run(
+ \ a:buffer,
+ \ l:command,
+ \ function('ale_linters#kotlin#kotlinc#GetCommand')
+ \)
endfunction
function! s:BuildClassPathOption(buffer, import_paths) abort
@@ -46,7 +53,7 @@ function! s:BuildClassPathOption(buffer, import_paths) abort
\ : ''
endfunction
-function! ale_linters#kotlin#kotlinc#GetCommand(buffer, import_paths) abort
+function! ale_linters#kotlin#kotlinc#GetCommand(buffer, import_paths, meta) abort
let l:kotlinc_opts = ale#Var(a:buffer, 'kotlin_kotlinc_options')
let l:command = 'kotlinc '
@@ -165,11 +172,7 @@ endfunction
call ale#linter#Define('kotlin', {
\ 'name': 'kotlinc',
\ 'executable': 'kotlinc',
-\ 'command_chain': [
-\ {'callback': 'ale_linters#kotlin#kotlinc#GetImportPaths', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#kotlin#kotlinc#GetCommand', 'output_stream': 'stderr'},
-\ ],
+\ 'command': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'),
\ 'callback': 'ale_linters#kotlin#kotlinc#Handle',
\ 'lint_file': 1,
\})
-
diff --git a/ale_linters/php/langserver.vim b/ale_linters/php/langserver.vim
index c88281c4..fdd1bf2b 100644
--- a/ale_linters/php/langserver.vim
+++ b/ale_linters/php/langserver.vim
@@ -5,6 +5,12 @@ call ale#Set('php_langserver_executable', 'php-language-server.php')
call ale#Set('php_langserver_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#php#langserver#GetProjectRoot(buffer) abort
+ let l:composer_path = ale#path#FindNearestFile(a:buffer, 'composer.json')
+
+ if (!empty(l:composer_path))
+ return fnamemodify(l:composer_path, ':h')
+ endif
+
let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
diff --git a/ale_linters/php/phpstan.vim b/ale_linters/php/phpstan.vim
index 34d4e799..ecd80a83 100644
--- a/ale_linters/php/phpstan.vim
+++ b/ale_linters/php/phpstan.vim
@@ -6,34 +6,13 @@ let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpsta
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4')
let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '')
-function! ale_linters#php#phpstan#GetExecutable(buffer) abort
- return ale#Var(a:buffer, 'php_phpstan_executable')
-endfunction
-
-function! ale_linters#php#phpstan#VersionCheck(buffer) abort
- let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer)
-
- " If we have previously stored the version number in a cache, then
- " don't look it up again.
- if ale#semver#HasVersion(l:executable)
- " Returning an empty string skips this command.
- return ''
- endif
-
- let l:executable = ale#Escape(l:executable)
-
- return l:executable . ' --version'
-endfunction
-
-function! ale_linters#php#phpstan#GetCommand(buffer, version_output) abort
+function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration')
let l:configuration_option = !empty(l:configuration)
\ ? ' -c ' . l:configuration
\ : ''
- let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer)
- let l:version = ale#semver#GetVersion(l:executable, a:version_output)
- let l:error_format = ale#semver#GTE(l:version, [0, 10, 3])
+ let l:error_format = ale#semver#GTE(a:version, [0, 10, 3])
\ ? ' --error-format raw'
\ : ' --errorFormat raw'
@@ -65,10 +44,12 @@ endfunction
call ale#linter#Define('php', {
\ 'name': 'phpstan',
-\ 'executable': function('ale_linters#php#phpstan#GetExecutable'),
-\ 'command_chain': [
-\ {'callback': 'ale_linters#php#phpstan#VersionCheck'},
-\ {'callback': 'ale_linters#php#phpstan#GetCommand'},
-\ ],
+\ 'executable': {b -> ale#Var(b, 'php_phpstan_executable')},
+\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
+\ buffer,
+\ ale#Var(buffer, 'php_phpstan_executable'),
+\ '%e --version',
+\ function('ale_linters#php#phpstan#GetCommand'),
+\ )},
\ 'callback': 'ale_linters#php#phpstan#Handle',
\})
diff --git a/ale_linters/powershell/psscriptanalyzer.vim b/ale_linters/powershell/psscriptanalyzer.vim
new file mode 100644
index 00000000..8d1804f8
--- /dev/null
+++ b/ale_linters/powershell/psscriptanalyzer.vim
@@ -0,0 +1,105 @@
+" Author: Jesse Harris - https://github.com/zigford
+" Description: This file adds support for lintng powershell scripts
+" using the PSScriptAnalyzer module.
+
+" let g:ale_powershell_psscriptanalyzer_exclusions =
+" \ 'PSAvoidUsingWriteHost,PSAvoidGlobalVars'
+call ale#Set('powershell_psscriptanalyzer_exclusions', '')
+call ale#Set('powershell_psscriptanalyzer_executable', 'pwsh')
+call ale#Set('powershell_psscriptanalyzer_module',
+\ 'psscriptanalyzer')
+
+function! ale_linters#powershell#psscriptanalyzer#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'powershell_psscriptanalyzer_executable')
+endfunction
+
+" Write a powershell script to a temp file for execution
+" return the command used to execute it
+function! s:TemporaryPSScript(buffer, input) abort
+ let l:filename = 'script.ps1'
+ " Create a temp dir to house our temp .ps1 script
+ " a temp dir is needed as powershell needs the .ps1
+ " extension
+ let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
+ let l:tempscript = l:tempdir . l:filename
+ " Create the temporary directory for the file, unreadable by 'other'
+ " users.
+ call mkdir(l:tempdir, '', 0750)
+ " Automatically delete the directory later.
+ call ale#command#ManageDirectory(a:buffer, l:tempdir)
+ " Write the script input out to a file.
+ call ale#util#Writefile(a:buffer, a:input, l:tempscript)
+
+ return l:tempscript
+endfunction
+
+function! ale_linters#powershell#psscriptanalyzer#RunPowerShell(buffer, command) abort
+ let l:executable = ale_linters#powershell#psscriptanalyzer#GetExecutable(
+ \ a:buffer)
+ let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
+
+ return ale#Escape(l:executable)
+ \ . ' -Exe Bypass -NoProfile -File '
+ \ . ale#Escape(l:tempscript)
+ \ . ' %t'
+endfunction
+
+" Run Invoke-ScriptAnalyzer and output each linting message as 4 seperate lines
+" for each parsing
+function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
+ let l:exclude_option = ale#Var(
+ \ a:buffer, 'powershell_psscriptanalyzer_exclusions')
+ let l:module = ale#Var(
+ \ a:buffer, 'powershell_psscriptanalyzer_module')
+ let l:script = ['Param($Script);
+ \ Invoke-ScriptAnalyzer "$Script" '
+ \ . (!empty(l:exclude_option) ? '-Exclude ' . l:exclude_option : '')
+ \ . '| ForEach-Object {
+ \ $_.Line;
+ \ $_.Severity;
+ \ $_.Message;
+ \ $_.RuleName}']
+
+ return ale_linters#powershell#psscriptanalyzer#RunPowerShell(
+ \ a:buffer, l:script)
+endfunction
+
+" add every 4 lines to an item(Dict) and every item to a list
+" return the list
+function! ale_linters#powershell#psscriptanalyzer#Handle(buffer, lines) abort
+ let l:output = []
+ let l:lcount = 0
+
+ for l:line in a:lines
+ if l:lcount is# 0
+ " the very first line
+ let l:item = {'lnum': str2nr(l:line)}
+ elseif l:lcount is# 1
+ if l:line is# 'Error'
+ let l:item['type'] = 'E'
+ elseif l:line is# 'Information'
+ let l:item['type'] = 'I'
+ else
+ let l:item['type'] = 'W'
+ endif
+ elseif l:lcount is# 2
+ let l:item['text'] = l:line
+ elseif l:lcount is# 3
+ let l:item['code'] = l:line
+ call add(l:output, l:item)
+ let l:lcount = -1
+ endif
+
+ let l:lcount = l:lcount + 1
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('powershell', {
+\ 'name': 'psscriptanalyzer',
+\ 'executable_callback': 'ale_linters#powershell#psscriptanalyzer#GetExecutable',
+\ 'command_callback': 'ale_linters#powershell#psscriptanalyzer#GetCommand',
+\ 'output_stream': 'stdout',
+\ 'callback': 'ale_linters#powershell#psscriptanalyzer#Handle',
+\})
diff --git a/ale_linters/python/flake8.vim b/ale_linters/python/flake8.vim
index 993d7adb..e2e7b743 100644
--- a/ale_linters/python/flake8.vim
+++ b/ale_linters/python/flake8.vim
@@ -24,28 +24,25 @@ function! ale_linters#python#flake8#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'python_flake8_executable')
endfunction
-function! ale_linters#python#flake8#VersionCheck(buffer) abort
+function! ale_linters#python#flake8#RunWithVersionCheck(buffer) abort
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
- " If we have previously stored the version number in a cache, then
- " don't look it up again.
- if ale#semver#HasVersion(l:executable)
- " Returning an empty string skips this command.
- return ''
- endif
-
- let l:executable = ale#Escape(l:executable)
let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : ''
-
- return l:executable . l:module_string . ' --version'
+ let l:command = ale#Escape(l:executable) . l:module_string . ' --version'
+
+ return ale#semver#RunWithVersionCheck(
+ \ a:buffer,
+ \ l:executable,
+ \ l:command,
+ \ function('ale_linters#python#flake8#GetCommand'),
+ \)
endfunction
-function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
+function! ale_linters#python#flake8#GetCommand(buffer, version) abort
let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory')
\ ? ale#path#BufferCdString(a:buffer)
\ : ''
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
- let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run flake8'
@@ -53,7 +50,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
" Only include the --stdin-display-name argument if we can parse the
" flake8 version, and it is recent enough to support it.
- let l:display_name_args = ale#semver#GTE(l:version, [3, 0, 0])
+ let l:display_name_args = ale#semver#GTE(a:version, [3, 0, 0])
\ ? ' --stdin-display-name %s'
\ : ''
@@ -144,9 +141,6 @@ endfunction
call ale#linter#Define('python', {
\ 'name': 'flake8',
\ 'executable': function('ale_linters#python#flake8#GetExecutable'),
-\ 'command_chain': [
-\ {'callback': 'ale_linters#python#flake8#VersionCheck'},
-\ {'callback': 'ale_linters#python#flake8#GetCommand', 'output_stream': 'both'},
-\ ],
+\ 'command': function('ale_linters#python#flake8#RunWithVersionCheck'),
\ 'callback': 'ale_linters#python#flake8#Handle',
\})
diff --git a/ale_linters/ruby/rails_best_practices.vim b/ale_linters/ruby/rails_best_practices.vim
index 680cc364..a94fb671 100644
--- a/ale_linters/ruby/rails_best_practices.vim
+++ b/ale_linters/ruby/rails_best_practices.vim
@@ -30,8 +30,8 @@ function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort
endif
let l:executable = ale#Var(a:buffer, 'ruby_rails_best_practices_executable')
- let l:output_file = ale#Has('win32') ? '%t ' : '/dev/stdout '
- let l:cat_file = ale#Has('win32') ? '; type %t' : ''
+ let l:output_file = has('win32') ? '%t ' : '/dev/stdout '
+ let l:cat_file = has('win32') ? '; type %t' : ''
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
\ . ' --silent -f json --output-file ' . l:output_file
diff --git a/ale_linters/ruby/reek.vim b/ale_linters/ruby/reek.vim
index 26f6e36c..e39e366f 100644
--- a/ale_linters/ruby/reek.vim
+++ b/ale_linters/ruby/reek.vim
@@ -6,26 +6,11 @@ call ale#Set('ruby_reek_show_wiki_link', 0)
call ale#Set('ruby_reek_options', '')
call ale#Set('ruby_reek_executable', 'reek')
-function! ale_linters#ruby#reek#VersionCheck(buffer) abort
- " If we have previously stored the version number in a cache, then
- " don't look it up again.
- if ale#semver#HasVersion('reek')
- " Returning an empty string skips this command.
- return ''
- endif
-
- let l:executable = ale#Var(a:buffer, 'ruby_reek_executable')
-
- return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek')
- \ . ' --version'
-endfunction
-
-function! ale_linters#ruby#reek#GetCommand(buffer, version_output) abort
- let l:version = ale#semver#GetVersion('reek', a:version_output)
+function! ale_linters#ruby#reek#GetCommand(buffer, version) abort
let l:executable = ale#Var(a:buffer, 'ruby_reek_executable')
" Tell reek what the filename is if the version of reek is new enough.
- let l:display_name_args = ale#semver#GTE(l:version, [5, 0, 0])
+ let l:display_name_args = ale#semver#GTE(a:version, [5, 0, 0])
\ ? ' --stdin-filename %s'
\ : ''
@@ -70,9 +55,11 @@ endfunction
call ale#linter#Define('ruby', {
\ 'name': 'reek',
\ 'executable': {b -> ale#Var(b, 'ruby_reek_executable')},
-\ 'command_chain': [
-\ {'callback': 'ale_linters#ruby#reek#VersionCheck'},
-\ {'callback': 'ale_linters#ruby#reek#GetCommand'},
-\ ],
+\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
+\ buffer,
+\ ale#Var(buffer, 'ruby_reek_executable'),
+\ '%e --version',
+\ function('ale_linters#ruby#reek#GetCommand'),
+\ )},
\ 'callback': 'ale_linters#ruby#reek#Handle',
\})
diff --git a/ale_linters/rust/cargo.vim b/ale_linters/rust/cargo.vim
index b4eabfae..f98dee9b 100644
--- a/ale_linters/rust/cargo.vim
+++ b/ale_linters/rust/cargo.vim
@@ -22,26 +22,18 @@ function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
endif
endfunction
-function! ale_linters#rust#cargo#VersionCheck(buffer) abort
- return !ale#semver#HasVersion('cargo')
- \ ? 'cargo --version'
- \ : ''
-endfunction
-
-function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
- let l:version = ale#semver#GetVersion('cargo', a:version_output)
-
+function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
- \ && ale#semver#GTE(l:version, [0, 17, 0])
+ \ && ale#semver#GTE(a:version, [0, 17, 0])
let l:use_all_targets = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
- \ && ale#semver#GTE(l:version, [0, 22, 0])
+ \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:use_examples = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_examples')
- \ && ale#semver#GTE(l:version, [0, 22, 0])
+ \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:use_tests = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_tests')
- \ && ale#semver#GTE(l:version, [0, 22, 0])
+ \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
@@ -94,10 +86,12 @@ endfunction
call ale#linter#Define('rust', {
\ 'name': 'cargo',
\ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'),
-\ 'command_chain': [
-\ {'callback': 'ale_linters#rust#cargo#VersionCheck'},
-\ {'callback': 'ale_linters#rust#cargo#GetCommand'},
-\ ],
+\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
+\ buffer,
+\ ale_linters#rust#cargo#GetCargoExecutable(buffer),
+\ '%e --version',
+\ function('ale_linters#rust#cargo#GetCommand'),
+\ )},
\ 'callback': 'ale#handlers#rust#HandleRustErrors',
\ 'output_stream': 'both',
\ 'lint_file': 1,
diff --git a/ale_linters/sh/shellcheck.vim b/ale_linters/sh/shellcheck.vim
index bb7048cd..3920cab8 100644
--- a/ale_linters/sh/shellcheck.vim
+++ b/ale_linters/sh/shellcheck.vim
@@ -11,10 +11,6 @@ call ale#Set('sh_shellcheck_executable', 'shellcheck')
call ale#Set('sh_shellcheck_dialect', 'auto')
call ale#Set('sh_shellcheck_options', '')
-function! ale_linters#sh#shellcheck#GetExecutable(buffer) abort
- return ale#Var(a:buffer, 'sh_shellcheck_executable')
-endfunction
-
function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
@@ -39,30 +35,18 @@ function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
return ''
endfunction
-function! ale_linters#sh#shellcheck#VersionCheck(buffer) abort
- let l:executable = ale_linters#sh#shellcheck#GetExecutable(a:buffer)
-
- " Don't check the version again if we've already cached it.
- return !ale#semver#HasVersion(l:executable)
- \ ? ale#Escape(l:executable) . ' --version'
- \ : ''
-endfunction
-
-function! ale_linters#sh#shellcheck#GetCommand(buffer, version_output) abort
- let l:executable = ale_linters#sh#shellcheck#GetExecutable(a:buffer)
- let l:version = ale#semver#GetVersion(l:executable, a:version_output)
-
+function! ale_linters#sh#shellcheck#GetCommand(buffer, version) abort
let l:options = ale#Var(a:buffer, 'sh_shellcheck_options')
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
- let l:external_option = ale#semver#GTE(l:version, [0, 4, 0]) ? ' -x' : ''
+ let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
if l:dialect is# 'auto'
let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
endif
return ale#path#BufferCdString(a:buffer)
- \ . ale#Escape(l:executable)
+ \ . '%e'
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
@@ -108,10 +92,12 @@ endfunction
call ale#linter#Define('sh', {
\ 'name': 'shellcheck',
-\ 'executable': function('ale_linters#sh#shellcheck#GetExecutable'),
-\ 'command_chain': [
-\ {'callback': 'ale_linters#sh#shellcheck#VersionCheck'},
-\ {'callback': 'ale_linters#sh#shellcheck#GetCommand'},
-\ ],
+\ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')},
+\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
+\ buffer,
+\ ale#Var(buffer, 'sh_shellcheck_executable'),
+\ '%e --version',
+\ function('ale_linters#sh#shellcheck#GetCommand'),
+\ )},
\ 'callback': 'ale_linters#sh#shellcheck#Handle',
\})
diff --git a/ale_linters/slim/slimlint.vim b/ale_linters/slim/slimlint.vim
index 1a4008ae..1b365e25 100644
--- a/ale_linters/slim/slimlint.vim
+++ b/ale_linters/slim/slimlint.vim
@@ -11,7 +11,7 @@ function! ale_linters#slim#slimlint#GetCommand(buffer) abort
"
" See https://github.com/sds/slim-lint/blob/master/lib/slim_lint/linter/README.md#rubocop
if !empty(l:rubocop_config)
- if ale#Has('win32')
+ if has('win32')
let l:command = 'set SLIM_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config) . ' && ' . l:command
else
let l:command = 'SLIM_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config) . ' ' . l:command
diff --git a/ale_linters/swift/sourcekitlsp.vim b/ale_linters/swift/sourcekitlsp.vim
new file mode 100644
index 00000000..560893bf
--- /dev/null
+++ b/ale_linters/swift/sourcekitlsp.vim
@@ -0,0 +1,13 @@
+" Author: Dan Loman <https://github.com/namolnad>
+" Description: Support for sourcekit-lsp https://github.com/apple/sourcekit-lsp
+
+call ale#Set('sourcekit_lsp_executable', 'sourcekit-lsp')
+
+call ale#linter#Define('swift', {
+\ 'name': 'sourcekitlsp',
+\ 'lsp': 'stdio',
+\ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')},
+\ 'command': '%e',
+\ 'project_root': function('ale#swift#FindProjectRoot'),
+\ 'language': 'swift',
+\})
diff --git a/ale_linters/vim/vint.vim b/ale_linters/vim/vint.vim
index 3808c47e..65e19126 100644
--- a/ale_linters/vim/vint.vim
+++ b/ale_linters/vim/vint.vim
@@ -7,29 +7,13 @@ call ale#Set('vim_vint_executable', 'vint')
let s:enable_neovim = has('nvim') ? ' --enable-neovim' : ''
let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})"'
-function! ale_linters#vim#vint#GetExecutable(buffer) abort
- return ale#Var(a:buffer, 'vim_vint_executable')
-endfunction
-
-function! ale_linters#vim#vint#VersionCommand(buffer) abort
- let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer)
-
- " Check the Vint version if we haven't checked it already.
- return !ale#semver#HasVersion(l:executable)
- \ ? ale#Escape(l:executable) . ' --version'
- \ : ''
-endfunction
-
-function! ale_linters#vim#vint#GetCommand(buffer, version_output) abort
- let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer)
- let l:version = ale#semver#GetVersion(l:executable, a:version_output)
-
- let l:can_use_no_color_flag = empty(l:version)
- \ || ale#semver#GTE(l:version, [0, 3, 7])
+function! ale_linters#vim#vint#GetCommand(buffer, version) abort
+ let l:can_use_no_color_flag = empty(a:version)
+ \ || ale#semver#GTE(a:version, [0, 3, 7])
let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w'
- return ale#Escape(l:executable)
+ return '%e'
\ . ' ' . l:warning_flag
\ . (l:can_use_no_color_flag ? ' --no-color' : '')
\ . s:enable_neovim
@@ -65,10 +49,12 @@ endfunction
call ale#linter#Define('vim', {
\ 'name': 'vint',
-\ 'executable': function('ale_linters#vim#vint#GetExecutable'),
-\ 'command_chain': [
-\ {'callback': 'ale_linters#vim#vint#VersionCommand', 'output_stream': 'stderr'},
-\ {'callback': 'ale_linters#vim#vint#GetCommand', 'output_stream': 'stdout'},
-\ ],
+\ 'executable': {buffer -> ale#Var(buffer, 'vim_vint_executable')},
+\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
+\ buffer,
+\ ale#Var(buffer, 'vim_vint_executable'),
+\ '%e --version',
+\ function('ale_linters#vim#vint#GetCommand'),
+\ )},
\ 'callback': 'ale_linters#vim#vint#Handle',
\})