diff options
59 files changed, 1168 insertions, 193 deletions
diff --git a/ale_linters/bats/shellcheck.vim b/ale_linters/bats/shellcheck.vim new file mode 100644 index 00000000..5c2a0ea9 --- /dev/null +++ b/ale_linters/bats/shellcheck.vim @@ -0,0 +1,4 @@ +" Author: Ian2020 <https://github.com/Ian2020> +" Description: shellcheck linter for bats scripts. + +call ale#handlers#shellcheck#DefineLinter('bats') diff --git a/ale_linters/dockerfile/dockerfile_lint.vim b/ale_linters/dockerfile/dockerfile_lint.vim index 95768b12..0c0ad533 100644 --- a/ale_linters/dockerfile/dockerfile_lint.vim +++ b/ale_linters/dockerfile/dockerfile_lint.vim @@ -32,14 +32,29 @@ function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort let l:line = get(l:object, 'line', -1) let l:message = l:object['message'] + let l:link = get(l:object, 'reference_url', '') + + if type(l:link) == v:t_list + " Somehow, reference_url is returned as two-part list. + " Anchor markers in that list are sometimes duplicated. + " See https://github.com/projectatomic/dockerfile_lint/issues/134 + let l:link = join(l:link, '') + let l:link = substitute(l:link, '##', '#', '') + endif + + let l:detail = l:message + if get(l:object, 'description', 'None') isnot# 'None' - let l:message = l:message . '. ' . l:object['description'] + let l:detail .= "\n\n" . l:object['description'] endif + let l:detail .= "\n\n" . l:link + call add(l:messages, { \ 'lnum': l:line, \ 'text': l:message, \ 'type': ale_linters#dockerfile#dockerfile_lint#GetType(l:type), + \ 'detail': l:detail, \}) endfor endfor diff --git a/ale_linters/go/revive.vim b/ale_linters/go/revive.vim new file mode 100644 index 00000000..b14b5ab9 --- /dev/null +++ b/ale_linters/go/revive.vim @@ -0,0 +1,21 @@ +" Author: Penghui Liao <liaoishere@gmail.com> +" Description: Adds support for revive + +call ale#Set('go_revive_executable', 'revive') +call ale#Set('go_revive_options', '') + +function! ale_linters#go#revive#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'go_revive_options') + + return ale#go#EnvString(a:buffer) . '%e' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' %t' +endfunction + +call ale#linter#Define('go', { +\ 'name': 'revive', +\ 'output_stream': 'both', +\ 'executable': {b -> ale#Var(b, 'go_revive_executable')}, +\ 'command': function('ale_linters#go#revive#GetCommand'), +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/ale_linters/java/eclipselsp.vim b/ale_linters/java/eclipselsp.vim index 2648893b..c981b749 100644 --- a/ale_linters/java/eclipselsp.vim +++ b/ale_linters/java/eclipselsp.vim @@ -7,6 +7,7 @@ call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls' call ale#Set('java_eclipselsp_config_path', '') call ale#Set('java_eclipselsp_workspace_path', '') call ale#Set('java_eclipselsp_executable', 'java') +call ale#Set('java_eclipselsp_javaagent', '') function! ale_linters#java#eclipselsp#Executable(buffer) abort return ale#Var(a:buffer, 'java_eclipselsp_executable') @@ -19,25 +20,32 @@ endfunction function! ale_linters#java#eclipselsp#JarPath(buffer) abort let l:path = ale_linters#java#eclipselsp#TargetPath(a:buffer) + if has('win32') + let l:platform = 'win32' + elseif has('macunix') + let l:platform = 'macosx' + else + let l:platform = 'linux' + endif + " Search jar file within repository path when manually built using mvn - let l:repo_path = l:path . '/org.eclipse.jdt.ls.product/target/repository' - let l:files = globpath(l:repo_path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1) + let l:files = globpath(l:path, '**/'.l:platform.'/**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1) - if len(l:files) == 1 + if len(l:files) > 1 return l:files[0] endif " Search jar file within VSCode extensions folder. - let l:files = globpath(l:path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1) + let l:files = globpath(l:path, '**/'.l:platform.'/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1) - if len(l:files) == 1 + if len(l:files) > 1 return l:files[0] endif " Search jar file within system package path let l:files = globpath('/usr/share/java/jdtls/plugins', 'org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1) - if len(l:files) == 1 + if len(l:files) > 1 return l:files[0] endif @@ -100,12 +108,30 @@ function! ale_linters#java#eclipselsp#WorkspacePath(buffer) abort return ale#path#Dirname(ale#java#FindProjectRoot(a:buffer)) endfunction +function! ale_linters#java#eclipselsp#Javaagent(buffer) abort + let l:rets = [] + let l:raw = ale#Var(a:buffer, 'java_eclipselsp_javaagent') + + if empty(l:raw) + return '' + endif + + let l:jars = split(l:raw) + + for l:jar in l:jars + call add(l:rets, ale#Escape('-javaagent:' . l:jar)) + endfor + + return join(l:rets, ' ') +endfunction + function! ale_linters#java#eclipselsp#Command(buffer, version) abort let l:path = ale#Var(a:buffer, 'java_eclipselsp_path') let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer) let l:cmd = [ ale#Escape(l:executable), + \ ale_linters#java#eclipselsp#Javaagent(a:buffer), \ '-Declipse.application=org.eclipse.jdt.ls.core.id1', \ '-Dosgi.bundles.defaultStartLevel=4', \ '-Declipse.product=org.eclipse.jdt.ls.core.product', @@ -147,7 +173,8 @@ function! ale_linters#java#eclipselsp#RunWithVersionCheck(buffer) abort return ale#command#Run( \ a:buffer, \ l:command, - \ function('ale_linters#java#eclipselsp#CommandWithVersion') + \ function('ale_linters#java#eclipselsp#CommandWithVersion'), + \ { 'output_stream': 'both' } \) endfunction diff --git a/ale_linters/java/javac.vim b/ale_linters/java/javac.vim index 8bb52c0b..f866eb09 100644 --- a/ale_linters/java/javac.vim +++ b/ale_linters/java/javac.vim @@ -6,6 +6,7 @@ let s:classpath_sep = has('unix') ? ':' : ';' call ale#Set('java_javac_executable', 'javac') call ale#Set('java_javac_options', '') call ale#Set('java_javac_classpath', '') +call ale#Set('java_javac_sourcepath', '') function! ale_linters#java#javac#RunWithImportPaths(buffer) abort let l:command = '' @@ -40,10 +41,15 @@ endfunction function! s:BuildClassPathOption(buffer, import_paths) abort " Filter out lines like [INFO], etc. let l:class_paths = filter(a:import_paths[:], 'v:val !~# ''[''') - call extend( - \ l:class_paths, - \ split(ale#Var(a:buffer, 'java_javac_classpath'), s:classpath_sep), - \) + let l:cls_path = ale#Var(a:buffer, 'java_javac_classpath') + + if !empty(l:cls_path) && type(l:cls_path) is v:t_string + call extend(l:class_paths, split(l:cls_path, s:classpath_sep)) + endif + + if !empty(l:cls_path) && type(l:cls_path) is v:t_list + call extend(l:class_paths, l:cls_path) + endif return !empty(l:class_paths) \ ? '-cp ' . ale#Escape(join(l:class_paths, s:classpath_sep)) @@ -79,6 +85,27 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths, meta) abort endif endif + let l:source_paths = [] + let l:source_path = ale#Var(a:buffer, 'java_javac_sourcepath') + + if !empty(l:source_path) && type(l:source_path) is v:t_string + let l:source_paths = split(l:source_path, s:classpath_sep) + endif + + if !empty(l:source_path) && type(l:source_path) is v:t_list + let l:source_paths = l:source_path + endif + + if !empty(l:source_paths) + for l:path in l:source_paths + let l:sp_path = ale#path#FindNearestDirectory(a:buffer, l:path) + + if !empty(l:sp_path) + call add(l:sp_dirs, l:sp_path) + endif + endfor + endif + if !empty(l:sp_dirs) let l:sp_option = '-sourcepath ' \ . ale#Escape(join(l:sp_dirs, s:classpath_sep)) diff --git a/ale_linters/kotlin/kotlinc.vim b/ale_linters/kotlin/kotlinc.vim index 3c6854fa..66c075be 100644 --- a/ale_linters/kotlin/kotlinc.vim +++ b/ale_linters/kotlin/kotlinc.vim @@ -174,6 +174,7 @@ endfunction call ale#linter#Define('kotlin', { \ 'name': 'kotlinc', \ 'executable': 'kotlinc', +\ 'output_stream': 'stderr', \ 'command': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'), \ 'callback': 'ale_linters#kotlin#kotlinc#Handle', \ 'lint_file': 1, diff --git a/ale_linters/puppet/puppet.vim b/ale_linters/puppet/puppet.vim index ae648615..59228dc8 100644 --- a/ale_linters/puppet/puppet.vim +++ b/ale_linters/puppet/puppet.vim @@ -8,13 +8,15 @@ function! ale_linters#puppet#puppet#Handle(buffer, lines) abort " Error: Could not parse for environment production: Syntax error at ':' at /root/puppetcode/modules/nginx/manifests/init.pp:43:12 " Error: Could not parse for environment production: Syntax error at '='; expected '}' at /root/puppetcode/modules/pancakes/manifests/init.pp:5" " Error: Could not parse for environment production: Syntax error at 'parameter1' (file: /tmp/modules/mariadb/manifests/slave.pp, line: 4, column: 5) - let l:pattern = '^Error: .*: \(.\+\) \((file:\|at\) .\+\.pp\(, line: \|:\)\(\d\+\)\(, column: \|:\)\=\(\d*\)' + " Error: Illegal attempt to assign to 'a Name'. Not an assignable reference (file: /tmp/modules/waffles/manifests/syrup.pp, line: 5, column: 11) + " Error: Could not parse for environment production: Syntax error at end of input (file: /tmp/modules/bob/manifests/init.pp) + let l:pattern = '^Error:\%(.*:\)\? \(.\+\) \((file:\|at\) .\+\.pp\(\(, line: \|:\)\(\d\+\)\(, column: \|:\)\=\(\d*\)\|)$\)' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) call add(l:output, { - \ 'lnum': l:match[4] + 0, - \ 'col': l:match[6] + 0, + \ 'lnum': l:match[5] + 0, + \ 'col': l:match[7] + 0, \ 'text': l:match[1], \}) endfor diff --git a/ale_linters/rust/analyzer.vim b/ale_linters/rust/analyzer.vim new file mode 100644 index 00000000..3666ec03 --- /dev/null +++ b/ale_linters/rust/analyzer.vim @@ -0,0 +1,24 @@ +" Author: Jon Gjengset <jon@thesquareplanet.com> +" Description: The next generation language server for Rust + +call ale#Set('rust_analyzer_executable', 'rust-analyzer') +call ale#Set('rust_analyzer_config', {}) + +function! ale_linters#rust#analyzer#GetCommand(buffer) abort + return '%e' +endfunction + +function! ale_linters#rust#analyzer#GetProjectRoot(buffer) abort + let l:cargo_file = ale#path#FindNearestFile(a:buffer, 'Cargo.toml') + + return !empty(l:cargo_file) ? fnamemodify(l:cargo_file, ':h') : '' +endfunction + +call ale#linter#Define('rust', { +\ 'name': 'analyzer', +\ 'lsp': 'stdio', +\ 'lsp_config': {b -> ale#Var(b, 'rust_analyzer_config')}, +\ 'executable': {b -> ale#Var(b, 'rust_analyzer_executable')}, +\ 'command': function('ale_linters#rust#analyzer#GetCommand'), +\ 'project_root': function('ale_linters#rust#analyzer#GetProjectRoot'), +\}) diff --git a/ale_linters/scala/metals.vim b/ale_linters/scala/metals.vim index f78c7119..da9e855d 100644 --- a/ale_linters/scala/metals.vim +++ b/ale_linters/scala/metals.vim @@ -32,6 +32,8 @@ function! ale_linters#scala#metals#GetProjectRoot(buffer) abort \) endif endfor + + return '' endfunction function! ale_linters#scala#metals#GetCommand(buffer) abort diff --git a/ale_linters/sh/shellcheck.vim b/ale_linters/sh/shellcheck.vim index 1d8b6096..d9945126 100644 --- a/ale_linters/sh/shellcheck.vim +++ b/ale_linters/sh/shellcheck.vim @@ -1,107 +1,4 @@ " Author: w0rp <devw0rp@gmail.com> -" Description: This file adds support for using the shellcheck linter with -" shell scripts. +" Description: shellcheck linter for shell scripts. -" This global variable can be set with a string of comma-separated error -" codes to exclude from shellcheck. For example: -" -" let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004' -call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_exclusions', '')) -call ale#Set('sh_shellcheck_executable', 'shellcheck') -call ale#Set('sh_shellcheck_dialect', 'auto') -call ale#Set('sh_shellcheck_options', '') -call ale#Set('sh_shellcheck_change_directory', 1) - -function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort - let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) - - if !empty(l:shell_type) - " Use the dash dialect for /bin/ash, etc. - if l:shell_type is# 'ash' - return 'dash' - endif - - return l:shell_type - endif - - " If there's no hashbang, try using Vim's buffer variables. - if getbufvar(a:buffer, 'is_bash', 0) - return 'bash' - elseif getbufvar(a:buffer, 'is_sh', 0) - return 'sh' - elseif getbufvar(a:buffer, 'is_kornshell', 0) - return 'ksh' - endif - - return '' -endfunction - -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(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' - let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer) - endif - - return l:cd_string - \ . '%e' - \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') - \ . (!empty(l:options) ? ' ' . l:options : '') - \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') - \ . l:external_option - \ . ' -f gcc -' -endfunction - -function! ale_linters#sh#shellcheck#Handle(buffer, lines) abort - let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+) \[([^\]]+)\]$' - let l:output = [] - - for l:match in ale#util#GetMatches(a:lines, l:pattern) - if l:match[4] is# 'error' - let l:type = 'E' - elseif l:match[4] is# 'note' - let l:type = 'I' - else - let l:type = 'W' - endif - - let l:item = { - \ 'lnum': str2nr(l:match[2]), - \ 'type': l:type, - \ 'text': l:match[5], - \ 'code': l:match[6], - \} - - if !empty(l:match[3]) - let l:item.col = str2nr(l:match[3]) - endif - - " If the filename is something like <stdin>, <nofile> or -, then - " this is an error for the file we checked. - if l:match[1] isnot# '-' && l:match[1][0] isnot# '<' - let l:item['filename'] = l:match[1] - endif - - call add(l:output, l:item) - endfor - - return l:output -endfunction - -call ale#linter#Define('sh', { -\ 'name': 'shellcheck', -\ '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', -\}) +call ale#handlers#shellcheck#DefineLinter('sh') diff --git a/ale_linters/terraform/terraform_lsp.vim b/ale_linters/terraform/terraform_lsp.vim new file mode 100644 index 00000000..e2408c15 --- /dev/null +++ b/ale_linters/terraform/terraform_lsp.vim @@ -0,0 +1,25 @@ +" Author: OJFord <dev@ojford.com> +" Description: terraform-lsp integration for ALE (cf. https://github.com/juliosueiras/terraform-lsp) + +call ale#Set('terraform_langserver_executable', 'terraform-lsp') +call ale#Set('terraform_langserver_options', '') + +function! ale_linters#terraform#terraform_lsp#GetCommand(buffer) abort + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'terraform_langserver_options')) +endfunction + +function! ale_linters#terraform#terraform_lsp#GetProjectRoot(buffer) abort + let l:tf_dir = ale#path#FindNearestDirectory(a:buffer, '.terraform') + + return !empty(l:tf_dir) ? fnamemodify(l:tf_dir, ':h:h') : '' +endfunction + +call ale#linter#Define('terraform', { +\ 'name': 'terraform_lsp', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'terraform_langserver_executable')}, +\ 'command': function('ale_linters#terraform#terraform_lsp#GetCommand'), +\ 'project_root': function('ale_linters#terraform#terraform_lsp#GetProjectRoot'), +\ 'language': 'terraform', +\}) diff --git a/ale_linters/verilog/verilator.vim b/ale_linters/verilog/verilator.vim index 64bb6e41..029dd4c9 100644 --- a/ale_linters/verilog/verilator.vim +++ b/ale_linters/verilog/verilator.vim @@ -28,21 +28,30 @@ function! ale_linters#verilog#verilator#Handle(buffer, lines) abort " %Warning-UNDRIVEN: test.v:3: Signal is not driven: clk " %Warning-UNUSED: test.v:4: Signal is not used: dout " %Warning-BLKSEQ: test.v:10: Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=). - let l:pattern = '^%\(Warning\|Error\)[^:]*:\([^:]\+\):\(\d\+\): \(.\+\)$' + " Since version 4.032 (04/2020) verilator linter messages also contain the column number, + " and look like: + " %Error: /tmp/test.sv:3:1: syntax error, unexpected endmodule, expecting ';' + " + " to stay compatible with old versions of the tool, the column number is + " optional in the researched pattern + let l:pattern = '^%\(Warning\|Error\)[^:]*:\([^:]\+\):\(\d\+\):\(\d\+\)\?:\? \(.\+\)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) - let l:line = l:match[3] + 0 - let l:type = l:match[1] is# 'Error' ? 'E' : 'W' - let l:text = l:match[4] + let l:item = { + \ 'lnum': str2nr(l:match[3]), + \ 'text': l:match[5], + \ 'type': l:match[1] is# 'Error' ? 'E' : 'W', + \} + + if !empty(l:match[4]) + let l:item.col = str2nr(l:match[4]) + endif + let l:file = l:match[2] if l:file =~# '_verilator_linted.v' - call add(l:output, { - \ 'lnum': l:line, - \ 'text': l:text, - \ 'type': l:type, - \}) + call add(l:output, l:item) endif endfor diff --git a/ale_linters/vim/vimls.vim b/ale_linters/vim/vimls.vim new file mode 100644 index 00000000..26014d66 --- /dev/null +++ b/ale_linters/vim/vimls.vim @@ -0,0 +1,61 @@ +" Author: Jeffrey Lau - https://github.com/zoonfafer +" Description: Vim Language Server integration for ALE + +call ale#Set('vim_vimls_executable', 'vim-language-server') +call ale#Set('vim_vimls_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('vim_vimls_config', {}) + +function! ale_linters#vim#vimls#GetProjectRoot(buffer) abort + let l:trigger_file_candidates = [ + \ '.vimrc', + \ 'init.vim', + \] + + for l:candidate in l:trigger_file_candidates + let l:trigger_file = fnamemodify(bufname(a:buffer), ':t') + + if l:trigger_file is# l:candidate + return fnamemodify( + \ bufname(a:buffer), + \ ':h', + \) + endif + endfor + + let l:trigger_dir_candidates = [ + \ 'autoload', + \ 'plugin', + \ '.git', + \] + + let l:path_upwards = ale#path#Upwards(fnamemodify(bufname(a:buffer), ':p:h')) + + for l:path in l:path_upwards + for l:candidate in l:trigger_dir_candidates + let l:trigger_dir = ale#path#Simplify( + \ l:path . '/' . l:candidate, + \) + + if isdirectory(l:trigger_dir) + return fnamemodify( + \ l:trigger_dir, + \ ':p:h:h', + \) + endif + endfor + endfor + + return '' +endfunction + +call ale#linter#Define('vim', { +\ 'name': 'vimls', +\ 'lsp': 'stdio', +\ 'lsp_config': {b -> ale#Var(b, 'vim_vimls_config')}, +\ 'executable': {b -> ale#node#FindExecutable(b, 'vim_vimls', [ +\ 'node_modules/.bin/vim-language-server', +\ ])}, +\ 'command': '%e --stdio', +\ 'language': 'vim', +\ 'project_root': function('ale_linters#vim#vimls#GetProjectRoot'), +\}) diff --git a/ale_linters/zig/zls.vim b/ale_linters/zig/zls.vim new file mode 100644 index 00000000..1390f6b1 --- /dev/null +++ b/ale_linters/zig/zls.vim @@ -0,0 +1,20 @@ +" Author: CherryMan <skipper308@hotmail.ca> +" Description: A language server for Zig + +call ale#Set('zig_zls_executable', 'zls') +call ale#Set('zig_zls_config', {}) + +function! ale_linters#zig#zls#GetProjectRoot(buffer) abort + let l:build_rs = ale#path#FindNearestFile(a:buffer, 'build.zig') + + return !empty(l:build_rs) ? fnamemodify(l:build_rs, ':h') : '' +endfunction + +call ale#linter#Define('zig', { +\ 'name': 'zls', +\ 'lsp': 'stdio', +\ 'lsp_config': {b -> ale#Var(b, 'zig_zls_config')}, +\ 'executable': {b -> ale#Var(b, 'zig_zls_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#zig#zls#GetProjectRoot'), +\}) diff --git a/autoload/ale.vim b/autoload/ale.vim index ee1a0d54..6251b47b 100644 --- a/autoload/ale.vim +++ b/autoload/ale.vim @@ -163,7 +163,7 @@ function! ale#Queue(delay, ...) abort endif endfunction -let s:current_ale_version = [2, 6, 0] +let s:current_ale_version = [2, 7, 0] " A function used to check for ALE features in files outside of the project. function! ale#Has(feature) abort @@ -258,9 +258,9 @@ function! ale#GetLocItemMessage(item, format_string) abort " Replace special markers with certain information. " \=l:variable is used to avoid escaping issues. + let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g') let l:msg = substitute(l:msg, '\V%severity%', '\=l:severity', 'g') let l:msg = substitute(l:msg, '\V%linter%', '\=l:linter_name', 'g') - let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g') " Replace %s with the text. let l:msg = substitute(l:msg, '\V%s', '\=a:item.text', 'g') diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim index 62e692b1..f725875c 100644 --- a/autoload/ale/fixers/eslint.vim +++ b/autoload/ale/fixers/eslint.vim @@ -53,7 +53,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort " Use --fix-to-stdout with eslint_d if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0]) return { - \ 'command': ale#node#Executable(a:buffer, l:executable) + \ 'command': ale#handlers#eslint#GetCdString(a:buffer) + \ . ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', @@ -63,7 +64,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort " 4.9.0 is the first version with --fix-dry-run if ale#semver#GTE(a:version, [4, 9, 0]) return { - \ 'command': ale#node#Executable(a:buffer, l:executable) + \ 'command': ale#handlers#eslint#GetCdString(a:buffer) + \ . ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -71,7 +73,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort endif return { - \ 'command': ale#node#Executable(a:buffer, l:executable) + \ 'command': ale#handlers#eslint#GetCdString(a:buffer) + \ . ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') \ . ' --fix %t', diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim index 156b939f..e37d6902 100644 --- a/autoload/ale/handlers/eslint.vim +++ b/autoload/ale/handlers/eslint.vim @@ -1,6 +1,11 @@ " Author: w0rp <devw0rp@gmail.com> " Description: Functions for working with eslint, for checking or fixing files. +let s:executables = [ +\ 'node_modules/.bin/eslint_d', +\ 'node_modules/eslint/bin/eslint.js', +\ 'node_modules/.bin/eslint', +\] let s:sep = has('win32') ? '\' : '/' call ale#Set('javascript_eslint_options', '') @@ -30,29 +35,39 @@ function! ale#handlers#eslint#FindConfig(buffer) abort endfunction function! ale#handlers#eslint#GetExecutable(buffer) abort - return ale#node#FindExecutable(a:buffer, 'javascript_eslint', [ - \ 'node_modules/.bin/eslint_d', - \ 'node_modules/eslint/bin/eslint.js', - \ 'node_modules/.bin/eslint', - \]) + return ale#node#FindExecutable(a:buffer, 'javascript_eslint', s:executables) endfunction -function! ale#handlers#eslint#GetCommand(buffer) abort - let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) - - let l:options = ale#Var(a:buffer, 'javascript_eslint_options') - +" Given a buffer, return a command prefix string which changes directory +" as necessary for running ESLint. +function! ale#handlers#eslint#GetCdString(buffer) abort " ESLint 6 loads plugins/configs/parsers from the project root " 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/dense-analysis/ale/issues/2787 - " Identify project root from presence of node_modules dir. + " + " If eslint is installed in a directory which contains the buffer, assume + " it is the ESLint project root. Otherwise, use nearest node_modules. " Note: If node_modules not present yet, can't load local deps anyway. - let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') - let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : '' - let l:cd_command = !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : '' + let l:executable = ale#node#FindNearestExecutable(a:buffer, s:executables) + + if !empty(l:executable) + let l:nmi = strridx(l:executable, 'node_modules') + let l:project_dir = l:executable[0:l:nmi - 2] + else + let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') + let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : '' + endif + + return !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : '' +endfunction + +function! ale#handlers#eslint#GetCommand(buffer) abort + let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) + + let l:options = ale#Var(a:buffer, 'javascript_eslint_options') - return l:cd_command + return ale#handlers#eslint#GetCdString(a:buffer) \ . ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -f json --stdin --stdin-filename %s' diff --git a/autoload/ale/handlers/shellcheck.vim b/autoload/ale/handlers/shellcheck.vim new file mode 100644 index 00000000..b16280f0 --- /dev/null +++ b/autoload/ale/handlers/shellcheck.vim @@ -0,0 +1,107 @@ +" Author: w0rp <devw0rp@gmail.com> +" Description: This file adds support for using the shellcheck linter + +function! ale#handlers#shellcheck#GetDialectArgument(buffer) abort + let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) + + if !empty(l:shell_type) + " Use the dash dialect for /bin/ash, etc. + if l:shell_type is# 'ash' + return 'dash' + endif + + return l:shell_type + endif + + " If there's no hashbang, try using Vim's buffer variables. + if getbufvar(a:buffer, 'is_bash', 0) + return 'bash' + elseif getbufvar(a:buffer, 'is_sh', 0) + return 'sh' + elseif getbufvar(a:buffer, 'is_kornshell', 0) + return 'ksh' + endif + + return '' +endfunction + +function! ale#handlers#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(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' + let l:dialect = ale#handlers#shellcheck#GetDialectArgument(a:buffer) + endif + + return l:cd_string + \ . '%e' + \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') + \ . l:external_option + \ . ' -f gcc -' +endfunction + +function! ale#handlers#shellcheck#Handle(buffer, lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+) \[([^\]]+)\]$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + if l:match[4] is# 'error' + let l:type = 'E' + elseif l:match[4] is# 'note' + let l:type = 'I' + else + let l:type = 'W' + endif + + let l:item = { + \ 'lnum': str2nr(l:match[2]), + \ 'type': l:type, + \ 'text': l:match[5], + \ 'code': l:match[6], + \} + + if !empty(l:match[3]) + let l:item.col = str2nr(l:match[3]) + endif + + " If the filename is something like <stdin>, <nofile> or -, then + " this is an error for the file we checked. + if l:match[1] isnot# '-' && l:match[1][0] isnot# '<' + let l:item['filename'] = l:match[1] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +function! ale#handlers#shellcheck#DefineLinter(filetype) abort + " This global variable can be set with a string of comma-separated error + " codes to exclude from shellcheck. For example: + " let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004' + call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_exclusions', '')) + call ale#Set('sh_shellcheck_executable', 'shellcheck') + call ale#Set('sh_shellcheck_dialect', 'auto') + call ale#Set('sh_shellcheck_options', '') + call ale#Set('sh_shellcheck_change_directory', 1) + + call ale#linter#Define(a:filetype, { + \ 'name': 'shellcheck', + \ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')}, + \ 'command': {buffer -> ale#semver#RunWithVersionCheck( + \ buffer, + \ ale#Var(buffer, 'sh_shellcheck_executable'), + \ '%e --version', + \ function('ale#handlers#shellcheck#GetCommand'), + \ )}, + \ 'callback': 'ale#handlers#shellcheck#Handle', + \}) +endfunction diff --git a/autoload/ale/node.vim b/autoload/ale/node.vim index 69060122..9b9b335a 100644 --- a/autoload/ale/node.vim +++ b/autoload/ale/node.vim @@ -12,6 +12,18 @@ function! ale#node#FindExecutable(buffer, base_var_name, path_list) abort return ale#Var(a:buffer, a:base_var_name . '_executable') endif + let l:nearest = ale#node#FindNearestExecutable(a:buffer, a:path_list) + + if !empty(l:nearest) + return l:nearest + endif + + return ale#Var(a:buffer, a:base_var_name . '_executable') +endfunction + +" Given a buffer number, a base variable name, and a list of paths to search +" for in ancestor directories, detect the executable path for a Node program. +function! ale#node#FindNearestExecutable(buffer, path_list) abort for l:path in a:path_list let l:executable = ale#path#FindNearestFile(a:buffer, l:path) @@ -20,7 +32,7 @@ function! ale#node#FindExecutable(buffer, base_var_name, path_list) abort endif endfor - return ale#Var(a:buffer, a:base_var_name . '_executable') + return '' endfunction " Create a executable string which executes a Node.js script command with a diff --git a/doc/ale-bats.txt b/doc/ale-bats.txt new file mode 100644 index 00000000..cf2199ec --- /dev/null +++ b/doc/ale-bats.txt @@ -0,0 +1,13 @@ +=============================================================================== +ALE Bats Integration *ale-bats-options* + + +=============================================================================== +shellcheck *ale-bats-shellcheck* + +The `shellcheck` linter for Bats uses the sh options for `shellcheck`; see: +|ale-sh-shellcheck|. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-cloudformation.txt b/doc/ale-cloudformation.txt index 59c6af06..9724403b 100644 --- a/doc/ale-cloudformation.txt +++ b/doc/ale-cloudformation.txt @@ -7,8 +7,40 @@ cfn-python-lint *ale-cloudformation-cfn-python-lint* cfn-python-lint is a linter for AWS CloudFormation template file. -https://github.com/awslabs/cfn-python-lint +Website: https://github.com/awslabs/cfn-python-lint +Installation +------------------------------------------------------------------------------- + + +Install cfn-python-lint using either pip or brew: > + +`pip install cfn-lint`. If pip is not available, run +`python setup.py clean --all` then `python setup.py install`. + + Homebrew (macOS): + +`brew install cfn-lint` + +< +Configuration +------------------------------------------------------------------------------- + +To get cloudformation linter to work on only CloudFormation files we must set +the buffer |filetype| to yaml.cloudformation. +This causes ALE to lint the file with linters configured for cloudformation and +yaml files. + +Just put: + +> + + au BufRead,BufNewFile *.template.yaml set filetype=yaml.cloudformation + +< + +on `ftdetect/cloudformation.vim` + +This will get both cloudformation and yaml linters to work on any file with `.template.yaml` ext. =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: - diff --git a/doc/ale-go.txt b/doc/ale-go.txt index be53783e..5c0791bc 100644 --- a/doc/ale-go.txt +++ b/doc/ale-go.txt @@ -220,6 +220,25 @@ g:ale_go_govet_options *g:ale_go_govet_options* =============================================================================== +revive *ale-go-revive* + +g:ale_go_revive_executable *g:ale_go_revive_executable* + *b:ale_go_revive_executable* + Type: |String| + Default: `'revive'` + + This variable can be set to change the revive executable path. + + +g:ale_go_revive_options *g:ale_go_revive_options* + *b:ale_go_revive_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the revive + + +=============================================================================== staticcheck *ale-go-staticcheck* g:ale_go_staticcheck_options *g:ale_go_staticcheck_options* diff --git a/doc/ale-java.txt b/doc/ale-java.txt index 32f0e6eb..d2001ca7 100644 --- a/doc/ale-java.txt +++ b/doc/ale-java.txt @@ -46,7 +46,7 @@ javac *ale-java-javac* g:ale_java_javac_classpath *g:ale_java_javac_classpath* *b:ale_java_javac_classpath* - Type: |String| + Type: |String| or |List| Default: `''` This variable can be set to change the global classpath for Java. @@ -67,6 +67,30 @@ g:ale_java_javac_options *g:ale_java_javac_options* This variable can be set to pass additional options to javac. +g:ale_java_javac_sourcepath *g:ale_java_javac_sourcepath* + *b:ale_java_javac_sourcepath* + Type: |String| or |List| + Default: `''` + +This variable can set multiple source code paths, the source code path is a +relative path (relative to the project root directory). + +Example: + +String type: +Note that the unix system separator is a colon(`:`) window system +is a semicolon(`;`). +> + let g:ale_java_javac_sourcepath = 'build/gen/source/xx/main:build/gen/source' +< +List type: +> + let g:ale_java_javac_sourcepath = [ + \ 'build/generated/source/querydsl/main', + \ 'target/generated-sources/source/querydsl/main' + \ ] +< + =============================================================================== google-java-format *ale-java-google-java-format* @@ -222,6 +246,17 @@ g:ale_java_eclipselsp_workspace_path *g:ale_java_eclipselsp_workspace_path* absolute path of the Eclipse workspace. If not set this value will be set to the parent folder of the project root. +g:ale_java_eclipselsp_javaagent *g:ale_java_eclipselsp_javaagent* + *b:ale_java_eclipselsp_javaagent* + + Type: |String| + Default: `''` + + A variable to add java agent for annotation processing such as Lombok. + If you have multiple java agent files, use space to separate them. For example: +> + let g:ale_java_eclipselsp_javaagent='/eclipse/lombok.jar /eclipse/jacoco.jar' +< =============================================================================== uncrustify *ale-java-uncrustify* diff --git a/doc/ale-rust.txt b/doc/ale-rust.txt index 44a79b18..46d4714b 100644 --- a/doc/ale-rust.txt +++ b/doc/ale-rust.txt @@ -9,7 +9,7 @@ Integration Information files for Rust distributed in Vim >=8.0.0501 or upstream: https://github.com/rust-lang/rust.vim - Note that there are three possible linters for Rust files: + Note that there are several possible linters and fixers for Rust files: 1. rustc -- The Rust compiler is used to check the currently edited file. So, if your project consists of multiple files, you will get some errors @@ -23,7 +23,12 @@ Integration Information over cargo. rls implements the Language Server Protocol for incremental compilation of Rust code, and can check Rust files while you type. `rls` requires Rust files to contained in Cargo projects. - 4. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to + 4. analyzer -- If you have rust-analyzer installed, you might prefer using + this linter over cargo and rls. rust-analyzer also implements the + Language Server Protocol for incremental compilation of Rust code, and is + the next iteration of rls. rust-analyzer, like rls, requires Rust files + to contained in Cargo projects. + 5. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to consistently reformat your Rust code. Only cargo is enabled by default. To switch to using rustc instead of cargo, @@ -37,6 +42,25 @@ Integration Information =============================================================================== +analyzer *ale-rust-analyzer* + +g:ale_rust_analyzer_executable *g:ale_rust_analyzer_executable* + *b:ale_rust_analyzer_executable* + Type: |String| + Default: `'rust-analyzer'` + + This variable can be modified to change the executable path for + `rust-analyzer`. + + +g:ale_rust_analyzer_config *g:ale_rust_analyzer_config* + *b:ale_rust_analyzer_config* + Type: |Dictionary| + Default: `{}` + + Dictionary with configuration settings for rust-analyzer. + +=============================================================================== cargo *ale-rust-cargo* g:ale_rust_cargo_use_check *g:ale_rust_cargo_use_check* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 29dabab7..4b4002af 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -35,6 +35,8 @@ Notes: * `shell` (-n flag) * `shellcheck` * `shfmt` +* Bats + * `shellcheck` * BibTeX * `bibclean` * Bourne Shell @@ -162,6 +164,7 @@ Notes: * `gosimple`!! * `gotype`!! * `go vet`!! + * `revive`!! * `staticcheck`!! * GraphQL * `eslint` @@ -408,6 +411,7 @@ Notes: * Rust * `cargo`!! * `rls` + * `rust-analyzer` * `rustc` (see |ale-integration-rust|) * `rustfmt` * Sass @@ -485,6 +489,7 @@ Notes: * `vcom` * `xvhdl` * Vim + * `vimls` * `vint` * Vim help^ * `alex`!! @@ -505,3 +510,5 @@ Notes: * `yamllint` * YANG * `yang-lsp` +* Zig + * `zls` diff --git a/doc/ale-terraform.txt b/doc/ale-terraform.txt index 387fd732..f62db190 100644 --- a/doc/ale-terraform.txt +++ b/doc/ale-terraform.txt @@ -33,6 +33,25 @@ g:ale_terraform_terraform_executable *g:ale_terraform_terraform_executable* =============================================================================== +terraform-lsp *ale-terraform-terraform-lsp* + +g:ale_terraform_langserver_executable *g:ale_terraform_langserver_executable* + *b:ale_terraform_langserver_executable* + Type: |String| + Default: `'terraform-lsp'` + + This variable can be changed to use a different executable for terraform-lsp. + + +g:ale_terraform_langserver_options *g:ale_terraform_langserver_options* + *b:ale_terraform_langserver_options* + Type: |String| + Default: `''` + + This variable can be changed to pass custom CLI flags to terraform-lsp. + + +=============================================================================== tflint *ale-terraform-tflint* g:ale_terraform_tflint_executable *g:ale_terraform_tflint_executable* diff --git a/doc/ale-vim.txt b/doc/ale-vim.txt index 772bad23..f85b43eb 100644 --- a/doc/ale-vim.txt +++ b/doc/ale-vim.txt @@ -3,6 +3,61 @@ ALE Vim Integration *ale-vim-options* =============================================================================== +vimls *ale-vim-vimls* + + The `vim-language-server` is the engine that powers VimL editor support + using the Language Server Protocol. See the installation instructions: + https://github.com/iamcco/vim-language-server#install + +g:ale_vim_vimls_executable *g:ale_vim_vimls_executable* + *b:ale_vim_vimls_executable* + Type: |String| + Default: `'vim-language-server'` + + This option can be set to change the executable path for vimls. + + +g:ale_vim_vimls_config *g:ale_vim_vimls_config* + *b:ale_vim_vimls_config* + Type: |Dictionary| + Default: `{}` + + Dictionary containing configuration settings that will be passed to the + language server. For example: > + { + \ 'vim': { + \ 'iskeyword': '@,48-57,_,192-255,-#', + \ 'vimruntime': '', + \ 'runtimepath': '', + \ 'diagnostic': { + \ 'enable': v:true + \ }, + \ 'indexes': { + \ 'runtimepath': v:true, + \ 'gap': 100, + \ 'count': 3, + \ 'projectRootPatterns' : ['.git', 'autoload', 'plugin'] + \ }, + \ 'suggest': { + \ 'fromVimruntime': v:true, + \ 'fromRuntimepath': v:false + \ }, + \ } + \} +< + Consult the vim-language-server documentation for more information about + settings. + + +g:ale_vim_vimls_use_global *g:ale_vim_vimls_use_global* + *b:ale_vim_vimls_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== vint *ale-vim-vint* g:ale_vim_vint_executable *g:ale_vim_vint_executable* diff --git a/doc/ale-zig.txt b/doc/ale-zig.txt new file mode 100644 index 00000000..70a53bbb --- /dev/null +++ b/doc/ale-zig.txt @@ -0,0 +1,33 @@ +=============================================================================== +ALE Zig Integration *ale-zig-options* + *ale-integration-zig* + +=============================================================================== +Integration Information + + Currently, the only supported linter for zig is zls. + +=============================================================================== +zls *ale-zig-zls* + +g:ale_zig_zls_executable *g:ale_zig_zls_executable* + *b:ale_zig_zls_executable* + Type: |String| + Default: `'zls'` + + This variable can be modified to change the executable path for `zls`. + + +g:ale_zig_zls_config *g:ale_zig_zls_config* + *b:ale_zig_zls_config* + Type: |Dictionary| + Default: `{}` + + WARNING: As of writing, zls does not support receiving configuration + from the client. This variable is a PLACEHOLDER until it does. + + Dictionary with configuration settings for zls. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index 469fa106..09f29c8d 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2279,6 +2279,8 @@ documented in additional help files. gcc...................................|ale-asm-gcc| awk.....................................|ale-awk-options| gawk..................................|ale-awk-gawk| + bats....................................|ale-bats-options| + shellcheck............................|ale-bats-shellcheck| bib.....................................|ale-bib-options| bibclean..............................|ale-bib-bibclean| c.......................................|ale-c-options| @@ -2377,6 +2379,7 @@ documented in additional help files. gometalinter..........................|ale-go-gometalinter| gopls.................................|ale-go-gopls| govet.................................|ale-go-govet| + revive................................|ale-go-revive| staticcheck...........................|ale-go-staticcheck| graphql.................................|ale-graphql-options| eslint................................|ale-graphql-eslint| @@ -2579,6 +2582,7 @@ documented in additional help files. sorbet................................|ale-ruby-sorbet| standardrb............................|ale-ruby-standardrb| rust....................................|ale-rust-options| + analyzer..............................|ale-rust-analyzer| cargo.................................|ale-rust-cargo| rls...................................|ale-rust-rls| rustc.................................|ale-rust-rustc| @@ -2623,6 +2627,7 @@ documented in additional help files. terraform...............................|ale-terraform-options| terraform-fmt-fixer...................|ale-terraform-fmt-fixer| terraform.............................|ale-terraform-terraform| + terraform-lsp.........................|ale-terraform-terraform-lsp| tflint................................|ale-terraform-tflint| tex.....................................|ale-tex-options| chktex................................|ale-tex-chktex| @@ -2654,6 +2659,7 @@ documented in additional help files. vcom..................................|ale-vhdl-vcom| xvhdl.................................|ale-vhdl-xvhdl| vim.....................................|ale-vim-options| + vimls.................................|ale-vim-vimls| vint..................................|ale-vim-vint| vim help................................|ale-vim-help-options| write-good............................|ale-vim-help-write-good| @@ -2670,6 +2676,8 @@ documented in additional help files. yamllint..............................|ale-yaml-yamllint| yang....................................|ale-yang-options| yang-lsp..............................|ale-yang-lsp| + zig.....................................|ale-zig-options| + zls...................................|ale-zig-zls| =============================================================================== diff --git a/supported-tools.md b/supported-tools.md index 0abc6b75..5243a310 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -44,6 +44,8 @@ formatting. * shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set) * [shellcheck](https://www.shellcheck.net/) * [shfmt](https://github.com/mvdan/sh) +* Bats + * [shellcheck](https://www.shellcheck.net/) * BibTeX * [bibclean](http://ftp.math.utah.edu/pub/bibclean/) * Bourne Shell @@ -171,6 +173,7 @@ formatting. * [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) :warning: :floppy_disk: * [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) :warning: :floppy_disk: * [go vet](https://golang.org/cmd/vet/) :floppy_disk: + * [revive](https://github.com/mgechev/revive) :warning: :floppy_disk: * [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) :warning: :floppy_disk: * GraphQL * [eslint](http://eslint.org/) @@ -417,6 +420,7 @@ formatting. * Rust * [cargo](https://github.com/rust-lang/cargo) :floppy_disk: (see `:help ale-integration-rust` for configuration instructions) * [rls](https://github.com/rust-lang-nursery/rls) :warning: + * [rust-analyzer](https://github.com/rust-analyzer/rust-analyzer) :warning: * [rustc](https://www.rust-lang.org/) :warning: * [rustfmt](https://github.com/rust-lang-nursery/rustfmt) * Sass @@ -494,6 +498,7 @@ formatting. * [vcom](https://www.mentor.com/products/fv/questa/) * [xvhdl](https://www.xilinx.com/products/design-tools/vivado.html) * Vim + * [vimls](https://github.com/iamcco/vim-language-server) * [vint](https://github.com/Kuniwak/vint) * Vim help * [alex](https://github.com/wooorm/alex) :warning: :floppy_disk: @@ -514,3 +519,5 @@ formatting. * [yamllint](https://yamllint.readthedocs.io/) * YANG * [yang-lsp](https://github.com/theia-ide/yang-lsp) +* Zig + * [zls](https://github.com/zigtools/zls) diff --git a/test/command_callback/java_paths/build/gen/main/java/com/something/dummy b/test/command_callback/java_paths/build/gen/main/java/com/something/dummy new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/java_paths/build/gen/main/java/com/something/dummy diff --git a/test/command_callback/java_paths/build/gen2/main/java/com/something/dummy b/test/command_callback/java_paths/build/gen2/main/java/com/something/dummy new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/java_paths/build/gen2/main/java/com/something/dummy diff --git a/test/command_callback/test_eclipselsp_command_callback.vader b/test/command_callback/test_eclipselsp_command_callback.vader index f25ed5fc..6bbc4053 100644 --- a/test/command_callback/test_eclipselsp_command_callback.vader +++ b/test/command_callback/test_eclipselsp_command_callback.vader @@ -54,6 +54,7 @@ Execute(VersionCheck should return correct version): Execute(The eclipselsp callback should return the correct default value): let cmd = [ ale#Escape('java'), + \ '', \ '-Declipse.application=org.eclipse.jdt.ls.core.id1', \ '-Dosgi.bundles.defaultStartLevel=4', \ '-Declipse.product=org.eclipse.jdt.ls.core.product', @@ -72,6 +73,7 @@ Execute(The eclipselsp callback should return the correct default value): Execute(The eclipselsp callback should allow custom executable): let b:ale_java_eclipselsp_executable='/bin/foobar' let cmd = [ ale#Escape('/bin/foobar'), + \ '', \ '-Declipse.application=org.eclipse.jdt.ls.core.id1', \ '-Dosgi.bundles.defaultStartLevel=4', \ '-Declipse.product=org.eclipse.jdt.ls.core.product', @@ -87,9 +89,12 @@ Execute(The eclipselsp callback should allow custom executable): \] AssertLinter '/bin/foobar', join(cmd, ' ') -Execute(The eclipselsp callback should allow custom configuration path): +Execute(The eclipselsp callback should allow custom configuration path and javaagent): let b:ale_java_eclipselsp_config_path = '/home/config' + let b:ale_java_eclipselsp_javaagent = '/home/lombok.jar /home/lombok2.jar' let cmd = [ ale#Escape('java'), + \ ale#Escape('-javaagent:/home/lombok.jar'), + \ ale#Escape('-javaagent:/home/lombok2.jar'), \ '-Declipse.application=org.eclipse.jdt.ls.core.id1', \ '-Dosgi.bundles.defaultStartLevel=4', \ '-Declipse.product=org.eclipse.jdt.ls.core.product', diff --git a/test/command_callback/test_javac_command_callback.vader b/test/command_callback/test_javac_command_callback.vader index 42c64e54..d2eebf7a 100644 --- a/test/command_callback/test_javac_command_callback.vader +++ b/test/command_callback/test_javac_command_callback.vader @@ -31,7 +31,7 @@ After: Execute(The javac callback should return the correct default value): AssertLinter 'javac', g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' -Execute(The javac callback should use g:ale_java_javac_classpath correctly): +Execute(The javac callback should use string type g:ale_java_javac_classpath correctly): let g:ale_java_javac_classpath = 'foo.jar' AssertLinter 'javac', @@ -39,6 +39,14 @@ Execute(The javac callback should use g:ale_java_javac_classpath correctly): \ . ' -cp ' . ale#Escape('foo.jar') \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' +Execute(The javac callback should use list type g:ale_java_javac_classpath correctly): + let g:ale_java_javac_classpath = ['foo.jar'] + + AssertLinter 'javac', + \ g:prefix + \ . ' -cp ' . ale#Escape('foo.jar') + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + Execute(The executable should be configurable): let g:ale_java_javac_executable = 'foobar' @@ -108,6 +116,137 @@ Execute(The javac callback should combine discovered classpaths and manual ones) \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + let g:ale_java_javac_classpath = ['configured.jar'] + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [ + \ '[DEBUG] Ignore this.', + \ '[INFO] Something we should ignore.', + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \], {}) + + AssertEqual + \ g:prefix + \ . ' -cp ' + \ . ale#Escape(join( + \ [ + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \ 'configured.jar', + \ ], + \ g:cp_sep + \ )) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_classpath = ['configured.jar', 'configured2.jar'] + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [ + \ '[DEBUG] Ignore this.', + \ '[INFO] Something we should ignore.', + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \], {}) + + AssertEqual + \ g:prefix + \ . ' -cp ' + \ . ale#Escape(join( + \ [ + \ '/foo/bar.jar', + \ '/xyz/abc.jar', + \ 'configured.jar', + \ 'configured2.jar', + \ ], + \ g:cp_sep + \ )) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + +Execute(The javac callback should use string type g:ale_java_javac_sourcepath correctly): + let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main' + + AssertLinter 'javac', + \ g:prefix + \ . ' -sourcepath ' . ale#Escape( + \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/') + \ ) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should use list type g:ale_java_javac_sourcepath correctly): + let g:ale_java_javac_sourcepath = ['java_paths/build/gen/main'] + + AssertLinter 'javac', + \ g:prefix + \ . ' -sourcepath ' . ale#Escape( + \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/') + \ ) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback shouldn't add -sourcepath when g:ale_java_javac_sourcepath variable path doesn't exist): + let g:ale_java_javac_sourcepath = 'java_paths/build/gen3/main' + + AssertLinter 'javac', + \ g:prefix + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' + +Execute(The javac callback should combine discovered sourcepath and manual ones): + call ale#engine#Cleanup(bufnr('')) + call ale#test#SetFilename('java_paths/src/main/java/com/something/dummy.java') + call ale#engine#InitBufferInfo(bufnr('')) + + let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main' + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) + + AssertEqual + \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), + \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'), + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main' + \ . g:cp_sep . 'java_paths/build/gen2/main' + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) + + AssertEqual + \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ 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/gen2/main/') + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_sourcepath = ['java_paths/build/gen/main'] + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) + + AssertEqual + \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), + \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/') + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + + let g:ale_java_javac_sourcepath = [ + \ 'java_paths/build/gen/main', + \ 'java_paths/build/gen2/main' + \ ] + let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) + + AssertEqual + \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint' + \ . ' -sourcepath ' . ale#Escape(join([ + \ 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/gen2/main/') + \ ], g:cp_sep)) + \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t', + \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g') + Execute(The javac callback should detect source directories): call ale#engine#Cleanup(bufnr('')) noautocmd e! java_paths/src/main/java/com/something/dummy diff --git a/test/command_callback/test_revive_command_callbacks.vader b/test/command_callback/test_revive_command_callbacks.vader new file mode 100644 index 00000000..172294f3 --- /dev/null +++ b/test/command_callback/test_revive_command_callbacks.vader @@ -0,0 +1,30 @@ +Before: + Save g:ale_go_go111module + + call ale#assert#SetUpLinterTest('go', 'revive') + +After: + Restore + + unlet! b:ale_go_go111module + + call ale#assert#TearDownLinterTest() + +Execute(The default revive command should be correct): + AssertLinter 'revive', ale#Escape('revive') . ' %t' + +Execute(The revive executable should be configurable): + let b:ale_go_revive_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' %t' + +Execute(The revive options should be configurable): + let b:ale_go_revive_options = '--foo' + + AssertLinter 'revive', ale#Escape('revive') . ' --foo %t' + +Execute(The revive command should support Go environment variables): + let b:ale_go_go111module = 'on' + + AssertLinter 'revive', + \ ale#Env('GO111MODULE', 'on') . ale#Escape('revive') . ' %t' diff --git a/test/command_callback/test_rust_analyzer_callbacks.vader b/test/command_callback/test_rust_analyzer_callbacks.vader new file mode 100644 index 00000000..95866076 --- /dev/null +++ b/test/command_callback/test_rust_analyzer_callbacks.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpLinterTest('rust', 'analyzer') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'rust-analyzer', ale#Escape('rust-analyzer') + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('rust-rls-project/test.rs') + + AssertLSPProject ale#path#Simplify(g:dir . '/rust-rls-project') + +Execute(Should accept configuration settings): + AssertLSPConfig {} + let b:ale_rust_analyzer_config = {'rust': {'clippy_preference': 'on'}} + AssertLSPConfig {'rust': {'clippy_preference': 'on'}} diff --git a/test/command_callback/test_terraform_lsp_command_callback.vader b/test/command_callback/test_terraform_lsp_command_callback.vader new file mode 100644 index 00000000..7a491d54 --- /dev/null +++ b/test/command_callback/test_terraform_lsp_command_callback.vader @@ -0,0 +1,48 @@ +Before: + call ale#assert#SetUpLinterTest('terraform', 'terraform_lsp') + +After: + if isdirectory(g:dir . '/.terraform') + call delete(g:dir . '/.terraform', 'd') + endif + + unlet! b:ale_terraform_langserver_executable + unlet! b:ale_terraform_langserver_options + + call ale#assert#TearDownLinterTest() + +Execute(Should send correct LSP language): + AssertLSPLanguage 'terraform' + +Execute(Should load default executable): + AssertLinter 'terraform-lsp', ale#Escape('terraform-lsp') + +Execute(Should configure custom executable): + let b:ale_terraform_langserver_executable = 'foo' + AssertLinter 'foo', ale#Escape('foo') + +Execute(Should set custom options): + let b:ale_terraform_langserver_options = '--bar' + + AssertLinter 'terraform-lsp', + \ ale#Escape('terraform-lsp') . ' --bar' + +Execute(Should return current directory if it contains .terraform directory): + call mkdir(g:dir . '/.terraform') + AssertLSPProject g:dir + +Execute(Should return nearest directory with .terraform if found in parent directory): + call ale#test#SetFilename('../terraform_files/main.tf') + + let b:parent_dir = ale#path#Simplify(g:dir . '/..') + let b:tf_dir = b:parent_dir . '/.terraform' + + if !isdirectory(b:tf_dir) + call mkdir(b:tf_dir) + endif + + AssertLSPProject b:parent_dir + + call delete(b:tf_dir, 'd') + unlet!b:parent_dir + unlet!b:tf_dir diff --git a/test/command_callback/test_vim_vimls.vader b/test/command_callback/test_vim_vimls.vader new file mode 100644 index 00000000..ab12b637 --- /dev/null +++ b/test/command_callback/test_vim_vimls.vader @@ -0,0 +1,76 @@ +" Author: Jeffrey Lau https://github.com/zoonfafer +" Description: Tests for the Vim vimls linter + +Before: + call ale#assert#SetUpLinterTest('vim', 'vimls') + +After: + if isdirectory(g:dir . '/.git') + call delete(g:dir . '/.git', 'd') + endif + + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults): + AssertLinter 'vim-language-server', ale#Escape('vim-language-server') . ' --stdio' + +Execute(should set correct LSP values): + call ale#test#SetFilename('vim_fixtures/path_with_autoload/test.vim') + AssertLSPLanguage 'vim' + AssertLSPOptions {} + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_autoload') + +Execute(should set correct project for .git/): + let b:parent_dir = ale#path#Simplify(g:dir . '/..') + let b:git_dir = b:parent_dir . '/.git' + + call ale#test#SetFilename('vim_fixtures/test.vim') + + if !isdirectory(b:git_dir) + call mkdir(b:git_dir) + endif + + AssertLSPProject ale#path#Simplify(b:parent_dir) + + call delete(b:git_dir, 'd') + unlet! b:git_dir + +Execute(should set correct project for plugin/): + call ale#test#SetFilename('vim_fixtures/path_with_plugin/test.vim') + + AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_plugin') + +Execute(should accept configuration settings): + AssertLSPConfig {} + + let b:ale_vim_vimls_config = {'vim': {'foobar': v:true}} + AssertLSPConfig {'vim': {'foobar': v:true}} + +Execute(should set correct project for .vimrc): + call ale#test#SetFilename('vim_fixtures/path_with_vimrc/.vimrc') + + AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_vimrc') + +Execute(should set correct project for init.vim): + call ale#test#SetFilename('vim_fixtures/path_with_initvim/init.vim') + + AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_initvim') + +Execute(should use the local executable when available): + call ale#test#SetFilename('vim_fixtures/file.vim') + + AssertLinter ale#path#Simplify(g:dir . '/vim_fixtures/node_modules/.bin/vim-language-server'), + \ ale#Escape(ale#path#Simplify(g:dir . '/vim_fixtures/node_modules/.bin/vim-language-server')) . ' --stdio' + +Execute(should let the global executable to be used): + let g:ale_vim_vimls_use_global = 1 + call ale#test#SetFilename('vim_fixtures/file.vim') + + AssertLinter 'vim-language-server', + \ ale#Escape('vim-language-server') . ' --stdio' + +Execute(should let the executable to be configured): + let g:ale_vim_vimls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') . ' --stdio' diff --git a/test/command_callback/test_zig_zls_callbacks.vader b/test/command_callback/test_zig_zls_callbacks.vader new file mode 100644 index 00000000..6e42cc4b --- /dev/null +++ b/test/command_callback/test_zig_zls_callbacks.vader @@ -0,0 +1,15 @@ +Before: + call ale#assert#SetUpLinterTest('zig', 'zls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'zls', ale#Escape('zls') + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('zig-zls-project/main.zig') + + AssertLSPProject ale#path#Simplify(g:dir . '/zig-zls-project') diff --git a/test/command_callback/vim_fixtures/invalid_vim_project/test.vim b/test/command_callback/vim_fixtures/invalid_vim_project/test.vim new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/vim_fixtures/invalid_vim_project/test.vim diff --git a/test/command_callback/vim_fixtures/node_modules/.bin/vim-language-server b/test/command_callback/vim_fixtures/node_modules/.bin/vim-language-server new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/vim_fixtures/node_modules/.bin/vim-language-server diff --git a/test/command_callback/vim_fixtures/path_with_autoload/autoload/test.vim b/test/command_callback/vim_fixtures/path_with_autoload/autoload/test.vim new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/vim_fixtures/path_with_autoload/autoload/test.vim diff --git a/test/command_callback/vim_fixtures/path_with_autoload/test.vim b/test/command_callback/vim_fixtures/path_with_autoload/test.vim new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/vim_fixtures/path_with_autoload/test.vim diff --git a/test/command_callback/vim_fixtures/path_with_initvim/init.vim b/test/command_callback/vim_fixtures/path_with_initvim/init.vim new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/vim_fixtures/path_with_initvim/init.vim diff --git a/test/command_callback/vim_fixtures/path_with_plugin/plugin/test.vim b/test/command_callback/vim_fixtures/path_with_plugin/plugin/test.vim new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/vim_fixtures/path_with_plugin/plugin/test.vim diff --git a/test/command_callback/vim_fixtures/path_with_plugin/test.vim b/test/command_callback/vim_fixtures/path_with_plugin/test.vim new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/vim_fixtures/path_with_plugin/test.vim diff --git a/test/command_callback/vim_fixtures/path_with_vimrc/.vimrc b/test/command_callback/vim_fixtures/path_with_vimrc/.vimrc new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/vim_fixtures/path_with_vimrc/.vimrc diff --git a/test/command_callback/zig-zls-project/build.zig b/test/command_callback/zig-zls-project/build.zig new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/zig-zls-project/build.zig diff --git a/test/eslint-test-files/react-app/subdir-with-package-json/node_modules/.gitkeep b/test/eslint-test-files/react-app/subdir-with-package-json/node_modules/.gitkeep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/eslint-test-files/react-app/subdir-with-package-json/node_modules/.gitkeep diff --git a/test/fixers/test_eslint_fixer_callback.vader b/test/fixers/test_eslint_fixer_callback.vader index ad80bdd5..400267ac 100644 --- a/test/fixers/test_eslint_fixer_callback.vader +++ b/test/fixers/test_eslint_fixer_callback.vader @@ -13,7 +13,9 @@ Execute(The executable path should be correct): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' --fix %t', @@ -150,7 +152,9 @@ Execute(The lower priority configuration file in a nested directory should be pr AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/subdir-with-config/.eslintrc')) \ . ' --fix %t', @@ -164,7 +168,9 @@ Execute(--config in options should override configuration file detection for old AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --config /foo.cfg' \ . ' --fix %t', @@ -175,7 +181,9 @@ Execute(--config in options should override configuration file detection for old AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c /foo.cfg' \ . ' --fix %t', @@ -187,7 +195,9 @@ Execute(package.json should be used as a last resort): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' --fix %t', @@ -199,7 +209,8 @@ Execute(package.json should be used as a last resort): \ { \ 'read_temporary_file': 1, \ 'command': - \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')) + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' --fix %t', \ } @@ -214,7 +225,9 @@ Execute(The version check should be correct): \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --version', \ { - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -223,7 +236,9 @@ Execute(The version check should be correct): AssertFixer [ \ { - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -236,7 +251,9 @@ Execute(--fix-dry-run should be used for 4.9.0 and up): GivenCommandOutput ['4.9.0'] AssertFixer \ { - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -249,7 +266,8 @@ Execute(--fix-to-stdout should be used for eslint_d): \ { \ 'read_temporary_file': 1, \ 'command': - \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' --fix %t', \ } @@ -260,7 +278,8 @@ Execute(--fix-to-stdout should be used for eslint_d): AssertFixer \ { \ 'command': - \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ } @@ -270,7 +289,8 @@ Execute(--fix-to-stdout should be used for eslint_d): AssertFixer \ { \ 'command': - \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ } diff --git a/test/handler/test_dockerfile_lint_handler.vader b/test/handler/test_dockerfile_lint_handler.vader index 619b7bde..a73db8cd 100644 --- a/test/handler/test_dockerfile_lint_handler.vader +++ b/test/handler/test_dockerfile_lint_handler.vader @@ -26,21 +26,25 @@ Execute(The dockerfile_lint handler should handle a normal example): \ 'lnum': -1, \ 'type': 'E', \ 'text': "Required LABEL name/key 'Name' is not defined", + \ 'detail': "Required LABEL name/key 'Name' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project", \ }, \ { \ 'lnum': -1, \ 'type': 'E', \ 'text': "Required LABEL name/key 'Version' is not defined", + \ 'detail': "Required LABEL name/key 'Version' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project", \ }, \ { \ 'lnum': 3, \ 'type': 'I', - \ 'text': "the MAINTAINER command is deprecated. MAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0", + \ 'text': "the MAINTAINER command is deprecated", + \ 'detail': "the MAINTAINER command is deprecated\n\nMAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0\n\nhttps://github.com/docker/cli/blob/master/docs/deprecated.md#maintainer-in-dockerfile", \ }, \ { \ 'lnum': -1, \ 'type': 'I', \ 'text': "There is no 'CMD' instruction", + \ 'detail': "There is no 'CMD' instruction\n\nhttps://docs.docker.com/engine/reference/builder/#cmd", \ }, \ ], \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), [ diff --git a/test/handler/test_puppet_handler.vader b/test/handler/test_puppet_handler.vader index e73c9dc7..03adc9f0 100644 --- a/test/handler/test_puppet_handler.vader +++ b/test/handler/test_puppet_handler.vader @@ -49,3 +49,29 @@ Execute(The puppet handler should parse lines and column correctly): \ "Error: Could not parse for environment production: Syntax error at ':' at C:/puppet/modules/nginx/manifests/init.pp:54:9", \ "Error: Could not parse for environment production: Syntax error at 'parameter1' (file: /tmp/modules/mariadb/manifests/slave.pp, line: 45, column: 12)", \ ]) + +Execute(The puppet handler should correctly parse errors that are reported before even trying to parse for an environment): + " Line Error + AssertEqual + \ [ + \ { + \ 'lnum': 5, + \ 'col': 11, + \ 'text': "Illegal attempt to assign to 'a Name'. Not an assignable reference" + \ }, + \ ], + \ ale_linters#puppet#puppet#Handle(255, [ + \ "Error: Illegal attempt to assign to 'a Name'. Not an assignable reference (file: /tmp/modules/waffles/manifests/syrup.pp, line: 5, column: 11)", + \ ]) +Execute(The puppet handler should parse lines when end of input is the location): + AssertEqual + \ [ + \ { + \ 'lnum': 0, + \ 'col': 0, + \ 'text': "Syntax error at end of input" + \ }, + \ ], + \ ale_linters#puppet#puppet#Handle(255, [ + \ "Error: Could not parse for environment production: Syntax error at end of input (file: /tmp//modules/test/manifests/init.pp)", + \ ]) diff --git a/test/handler/test_shellcheck_handler.vader b/test/handler/test_shellcheck_handler.vader index bfb73ffa..33f12989 100644 --- a/test/handler/test_shellcheck_handler.vader +++ b/test/handler/test_shellcheck_handler.vader @@ -22,7 +22,7 @@ Execute(The shellcheck handler should handle basic errors or warnings): \ 'code': 'SC1068', \ }, \ ], - \ ale_linters#sh#shellcheck#Handle(bufnr(''), [ + \ ale#handlers#shellcheck#Handle(bufnr(''), [ \ '-:2:1: warning: In POSIX sh, ''let'' is not supported. [SC2039]', \ '-:2:3: error: Don''t put spaces around the = in assignments. [SC1068]', \ ]) @@ -38,6 +38,6 @@ Execute(The shellcheck handler should handle notes): \ 'code': 'SC2086', \ }, \ ], - \ ale_linters#sh#shellcheck#Handle(bufnr(''), [ + \ ale#handlers#shellcheck#Handle(bufnr(''), [ \ '-:3:3: note: Double quote to prevent globbing and word splitting. [SC2086]', \ ]) diff --git a/test/handler/test_verilator_handler.vader b/test/handler/test_verilator_handler.vader new file mode 100644 index 00000000..5e51b5c9 --- /dev/null +++ b/test/handler/test_verilator_handler.vader @@ -0,0 +1,48 @@ +Before: + runtime ale_linters/verilog/verilator.vim + +After: + call ale#linter#Reset() + + +Execute (The verilator handler should parse legacy messages with only line numbers): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected IDENTIFIER' + \ }, + \ { + \ 'lnum': 10, + \ 'type': 'W', + \ 'text': 'Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).' + \ }, + \ ], + \ ale_linters#verilog#verilator#Handle(bufnr(''), [ + \ '%Error: foo_verilator_linted.v:3: syntax error, unexpected IDENTIFIER', + \ '%Warning-BLKSEQ: bar_verilator_linted.v:10: Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).', + \ ]) + + +Execute (The verilator handler should parse new format messages with line and column numbers): + AssertEqual + \ [ + \ { + \ 'lnum': 3, + \ 'col' : 1, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected endmodule, expecting ;' + \ }, + \ { + \ 'lnum': 4, + \ 'col' : 6, + \ 'type': 'W', + \ 'text': 'Signal is not used: r' + \ }, + \ ], + \ ale_linters#verilog#verilator#Handle(bufnr(''), [ + \ '%Error: bar_verilator_linted.v:3:1: syntax error, unexpected endmodule, expecting ;', + \ '%Warning-UNUSED: foo_verilator_linted.v:4:6: Signal is not used: r', + \ ]) + diff --git a/test/terraform_files/main.tf b/test/terraform_files/main.tf new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/terraform_files/main.tf diff --git a/test/test_ale_has.vader b/test/test_ale_has.vader index b8a99103..633c7186 100644 --- a/test/test_ale_has.vader +++ b/test/test_ale_has.vader @@ -1,4 +1,5 @@ Execute(Checks for versions below the current version should succeed): + AssertEqual 1, ale#Has('ale-2.7.0') AssertEqual 1, ale#Has('ale-2.6.0') AssertEqual 1, ale#Has('ale-2.5.0') AssertEqual 1, ale#Has('ale-2.4.0') diff --git a/test/test_cursor_warnings.vader b/test/test_cursor_warnings.vader index 2a6156f0..339cd71e 100644 --- a/test/test_cursor_warnings.vader +++ b/test/test_cursor_warnings.vader @@ -15,7 +15,7 @@ Before: \ 'col': 10, \ 'bufnr': bufnr('%'), \ 'vcol': 0, - \ 'linter_name': 'eslint', + \ 'linter_name': 'bettercode', \ 'nr': -1, \ 'type': 'W', \ 'code': 'semi', @@ -26,7 +26,7 @@ Before: \ 'col': 10, \ 'bufnr': bufnr('%'), \ 'vcol': 0, - \ 'linter_name': 'eslint', + \ 'linter_name': 'bettercode', \ 'nr': -1, \ 'type': 'E', \ 'code': 'semi', @@ -38,7 +38,7 @@ Before: \ 'col': 14, \ 'bufnr': bufnr('%'), \ 'vcol': 0, - \ 'linter_name': 'eslint', + \ 'linter_name': 'bettercode', \ 'nr': -1, \ 'type': 'I', \ 'text': 'Some information', @@ -48,7 +48,7 @@ Before: \ 'col': 10, \ 'bufnr': bufnr('%'), \ 'vcol': 0, - \ 'linter_name': 'eslint', + \ 'linter_name': 'bettercode', \ 'nr': -1, \ 'type': 'W', \ 'code': 'space-infix-ops', @@ -59,7 +59,7 @@ Before: \ 'col': 15, \ 'bufnr': bufnr('%'), \ 'vcol': 0, - \ 'linter_name': 'eslint', + \ 'linter_name': 'bettercode', \ 'nr': -1, \ 'type': 'E', \ 'code': 'radix', @@ -70,7 +70,7 @@ Before: \ 'col': 1, \ 'bufnr': bufnr('%'), \ 'vcol': 0, - \ 'linter_name': 'eslint', + \ 'linter_name': 'bettercode', \ 'nr': -1, \ 'type': 'E', \ 'text': 'lowercase error', @@ -196,7 +196,7 @@ Execute(The linter name should be formatted into the message correctly): call ale#cursor#EchoCursorWarning() AssertEqual - \ 'eslint: Infix operators must be spaced.', + \ 'bettercode: Infix operators must be spaced.', \ GetLastMessage() Execute(The severity should be formatted into the message correctly): diff --git a/test/test_eslint_executable_detection.vader b/test/test_eslint_executable_detection.vader index c2071131..3fed63da 100644 --- a/test/test_eslint_executable_detection.vader +++ b/test/test_eslint_executable_detection.vader @@ -70,6 +70,25 @@ Execute(eslint.js executables should be run with node on Windows): \ ale#handlers#eslint#GetCommand(bufnr('')) endif +Execute(eslint.js should be run from containing project with eslint): + call ale#test#SetFilename('eslint-test-files/react-app/subdir-with-package-json/testfile.js') + + " We have to execute the file with node. + if has('win32') + AssertEqual + \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app')) + \ . ale#Escape('node.exe') . ' ' + \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' -f json --stdin --stdin-filename %s', + \ ale#handlers#eslint#GetCommand(bufnr('')) + else + AssertEqual + \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) + \ . ' -f json --stdin --stdin-filename %s', + \ ale#handlers#eslint#GetCommand(bufnr('')) + endif + Execute(eslint.js executables can be run outside project dir): " Set filename above eslint-test-files (which contains node_modules) call ale#test#SetFilename('testfile.js') diff --git a/test/test_shell_detection.vader b/test/test_shell_detection.vader index 88ee462d..6452287f 100644 --- a/test/test_shell_detection.vader +++ b/test/test_shell_detection.vader @@ -15,7 +15,7 @@ Given(A file with a Bash hashbang): Execute(/bin/bash should be detected appropriately): AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with /bin/sh): #!/usr/bin/env sh -eu --foobar @@ -23,7 +23,7 @@ Given(A file with /bin/sh): Execute(/bin/sh should be detected appropriately): AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with bash as an argument to env): #!/usr/bin/env bash @@ -31,7 +31,7 @@ Given(A file with bash as an argument to env): Execute(/usr/bin/env bash should be detected appropriately): AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with a tcsh hash bang and arguments): #!/usr/bin/env tcsh -eu --foobar @@ -39,7 +39,7 @@ Given(A file with a tcsh hash bang and arguments): Execute(tcsh should be detected appropriately): AssertEqual 'tcsh', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'tcsh', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'tcsh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'tcsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with a zsh hash bang and arguments): #!/usr/bin/env zsh -eu --foobar @@ -47,7 +47,7 @@ Given(A file with a zsh hash bang and arguments): Execute(zsh should be detected appropriately): AssertEqual 'zsh', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'zsh', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'zsh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'zsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with a csh hash bang and arguments): #!/usr/bin/env csh -eu --foobar @@ -55,7 +55,7 @@ Given(A file with a csh hash bang and arguments): Execute(csh should be detected appropriately): AssertEqual 'csh', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'csh', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'csh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'csh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with a ksh hashbang): #!/bin/ksh @@ -63,7 +63,7 @@ Given(A file with a ksh hashbang): Execute(/bin/ksh should be detected appropriately): AssertEqual 'ksh', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'ksh', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with a ksh as an argument to env): #!/usr/bin/env ksh @@ -71,7 +71,7 @@ Given(A file with a ksh as an argument to env): Execute(ksh should be detected appropriately): AssertEqual 'ksh', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'ksh', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with a sh hash bang and arguments): #!/usr/bin/env sh -eu --foobar @@ -79,24 +79,24 @@ Given(A file with a sh hash bang and arguments): Execute(sh should be detected appropriately): AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr('')) AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr('')) - AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file without a hashbang): Execute(The bash dialect should be used for shellcheck if b:is_bash is 1): let b:is_bash = 1 - AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Execute(The sh dialect should be used for shellcheck if b:is_sh is 1): let b:is_sh = 1 - AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Execute(The ksh dialect should be used for shellcheck if b:is_kornshell is 1): let b:is_kornshell = 1 - AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with /bin/ash): #!/bin/ash @@ -106,7 +106,7 @@ Execute(The ash dialect should be used for the shell and the base function): AssertEqual 'ash', ale_linters#sh#shell#GetExecutable(bufnr('')) Execute(dash should be used for shellcheck, which has no ash dialect): - AssertEqual 'dash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) Given(A file with /bin/dash): #!/bin/dash @@ -116,4 +116,4 @@ Execute(The dash dialect should be used for the shell and the base function): AssertEqual 'dash', ale_linters#sh#shell#GetExecutable(bufnr('')) Execute(dash should be used for shellcheck): - AssertEqual 'dash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr('')) + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) |