diff options
Diffstat (limited to 'ale_linters')
29 files changed, 326 insertions, 51 deletions
diff --git a/ale_linters/c/clangd.vim b/ale_linters/c/clangd.vim index 79b600fa..ab8a0259 100644 --- a/ale_linters/c/clangd.vim +++ b/ale_linters/c/clangd.vim @@ -3,9 +3,14 @@ call ale#Set('c_clangd_executable', 'clangd') call ale#Set('c_clangd_options', '') +call ale#Set('c_build_dir', '') function! ale_linters#c#clangd#GetCommand(buffer) abort - return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options')) + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + + return '%e -x c' + \ . ale#Pad(ale#Var(a:buffer, 'c_clangd_options')) + \ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '') endfunction call ale#linter#Define('c', { diff --git a/ale_linters/c/clangtidy.vim b/ale_linters/c/clangtidy.vim index f998866a..553cc23b 100644 --- a/ale_linters/c/clangtidy.vim +++ b/ale_linters/c/clangtidy.vim @@ -19,14 +19,17 @@ call ale#Set('c_clangtidy_options', '') call ale#Set('c_clangtidy_extra_options', '') call ale#Set('c_build_dir', '') -function! ale_linters#c#clangtidy#GetCommand(buffer) abort +function! ale_linters#c#clangtidy#GetCommand(buffer, output) abort let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',') let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + let l:options = '' " Get the extra options if we couldn't find a build directory. - let l:options = empty(l:build_dir) - \ ? ale#Var(a:buffer, 'c_clangtidy_options') - \ : '' + if empty(l:build_dir) + let l:options = ale#Var(a:buffer, 'c_clangtidy_options') + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags + endif " Get the options to pass directly to clang-tidy let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options') @@ -43,7 +46,7 @@ call ale#linter#Define('c', { \ 'name': 'clangtidy', \ 'output_stream': 'stdout', \ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')}, -\ 'command': function('ale_linters#c#clangtidy#GetCommand'), +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clangtidy#GetCommand'))}, \ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'lint_file': 1, \}) diff --git a/ale_linters/cpp/clangd.vim b/ale_linters/cpp/clangd.vim index fab605f4..14f3fe55 100644 --- a/ale_linters/cpp/clangd.vim +++ b/ale_linters/cpp/clangd.vim @@ -3,9 +3,14 @@ call ale#Set('cpp_clangd_executable', 'clangd') call ale#Set('cpp_clangd_options', '') +call ale#Set('c_build_dir', '') function! ale_linters#cpp#clangd#GetCommand(buffer) abort - return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options')) + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options')) + \ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '') endfunction call ale#linter#Define('cpp', { diff --git a/ale_linters/cpp/clangtidy.vim b/ale_linters/cpp/clangtidy.vim index 085bc332..191b7b07 100644 --- a/ale_linters/cpp/clangtidy.vim +++ b/ale_linters/cpp/clangtidy.vim @@ -13,14 +13,17 @@ call ale#Set('cpp_clangtidy_options', '') call ale#Set('cpp_clangtidy_extra_options', '') call ale#Set('c_build_dir', '') -function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort +function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',') let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + let l:options = '' " Get the extra options if we couldn't find a build directory. - let l:options = empty(l:build_dir) - \ ? ale#Var(a:buffer, 'cpp_clangtidy_options') - \ : '' + if empty(l:build_dir) + let l:options = ale#Var(a:buffer, 'cpp_clangtidy_options') + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags + endif " Get the options to pass directly to clang-tidy let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options') @@ -37,7 +40,7 @@ call ale#linter#Define('cpp', { \ 'name': 'clangtidy', \ 'output_stream': 'stdout', \ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')}, -\ 'command': function('ale_linters#cpp#clangtidy#GetCommand'), +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clangtidy#GetCommand'))}, \ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'lint_file': 1, \}) diff --git a/ale_linters/elm/elm_ls.vim b/ale_linters/elm/elm_ls.vim index 374ef8de..2fa71adb 100644 --- a/ale_linters/elm/elm_ls.vim +++ b/ale_linters/elm/elm_ls.vim @@ -3,9 +3,12 @@ call ale#Set('elm_ls_executable', 'elm-language-server') call ale#Set('elm_ls_use_global', get(g:, 'ale_use_global_executables', 1)) -call ale#Set('elm_ls_elm_path', 'elm') -call ale#Set('elm_ls_elm_format_path', 'elm-format') -call ale#Set('elm_ls_elm_test_path', 'elm-test') + +" elm-language-server will search for local and global binaries, if empty +call ale#Set('elm_ls_elm_path', '') +call ale#Set('elm_ls_elm_format_path', '') +call ale#Set('elm_ls_elm_test_path', '') +call ale#Set('elm_ls_elm_analyse_trigger', 'change') function! elm_ls#GetRootDir(buffer) abort let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json') @@ -15,10 +18,10 @@ endfunction function! elm_ls#GetOptions(buffer) abort return { - \ 'runtime': 'node', \ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'), \ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'), \ 'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'), + \ 'elmAnalyseTrigger': ale#Var(a:buffer, 'elm_ls_elm_analyse_trigger'), \} endfunction diff --git a/ale_linters/erlang/dialyzer.vim b/ale_linters/erlang/dialyzer.vim index 7af64c4f..395647a0 100644 --- a/ale_linters/erlang/dialyzer.vim +++ b/ale_linters/erlang/dialyzer.vim @@ -15,10 +15,10 @@ endfunction function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort let l:plt_file = '' let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer) - let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile) + let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build/' . l:rebar3_profile) if !empty(l:plt_file_directory) - let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n') + let l:plt_file = globpath(l:plt_file_directory, '*_plt', 0, 1) endif if !empty(l:plt_file) diff --git a/ale_linters/eruby/ruumba.vim b/ale_linters/eruby/ruumba.vim index e68bb51d..2e84acf7 100644 --- a/ale_linters/eruby/ruumba.vim +++ b/ale_linters/eruby/ruumba.vim @@ -8,7 +8,7 @@ call ale#Set('eruby_ruumba_options', '') function! ale_linters#eruby#ruumba#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'eruby_ruumba_executable') - return ale#handlers#ruby#EscapeExecutable(l:executable, 'ruumba') + return ale#ruby#EscapeExecutable(l:executable, 'ruumba') \ . ' --format json --force-exclusion ' \ . ale#Var(a:buffer, 'eruby_ruumba_options') \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) diff --git a/ale_linters/ink/ls.vim b/ale_linters/ink/ls.vim new file mode 100644 index 00000000..1cc93583 --- /dev/null +++ b/ale_linters/ink/ls.vim @@ -0,0 +1,35 @@ +" Author: Andreww Hayworth <ahayworth@gmail.com> +" Description: Integrate ALE with ink-language-server + +call ale#Set('ink_ls_executable', 'ink-language-server') +call ale#Set('ink_ls_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('ink_ls_initialization_options', {}) + +function! ale_linters#ink#ls#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'ink_ls', [ + \ 'ink-language-server', + \ 'node_modules/.bin/ink-language-server', + \]) +endfunction + +function! ale_linters#ink#ls#GetCommand(buffer) abort + let l:executable = ale_linters#ink#ls#GetExecutable(a:buffer) + + return ale#Escape(l:executable) . ' --stdio' +endfunction + +function! ale_linters#ink#ls#FindProjectRoot(buffer) abort + let l:main_file = get(ale#Var(a:buffer, 'ink_ls_initialization_options'), 'mainStoryPath', 'main.ink') + let l:config = ale#path#ResolveLocalPath(a:buffer, l:main_file, expand('#' . a:buffer . ':p')) + + return ale#path#Dirname(l:config) +endfunction + +call ale#linter#Define('ink', { +\ 'name': 'ink-language-server', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#ink#ls#GetExecutable'), +\ 'command': function('ale_linters#ink#ls#GetCommand'), +\ 'project_root': function('ale_linters#ink#ls#FindProjectRoot'), +\ 'initialization_options': {b -> ale#Var(b, 'ink_ls_initialization_options')}, +\}) diff --git a/ale_linters/javascript/flow.vim b/ale_linters/javascript/flow.vim index 3135e2e9..3135e2e9 100755..100644 --- a/ale_linters/javascript/flow.vim +++ b/ale_linters/javascript/flow.vim diff --git a/ale_linters/javascript/standard.vim b/ale_linters/javascript/standard.vim index 4cd2c303..203a803e 100644 --- a/ale_linters/javascript/standard.vim +++ b/ale_linters/javascript/standard.vim @@ -8,6 +8,7 @@ call ale#Set('javascript_standard_options', '') function! ale_linters#javascript#standard#GetExecutable(buffer) abort return ale#node#FindExecutable(a:buffer, 'javascript_standard', [ \ 'node_modules/standard/bin/cmd.js', + \ 'node_modules/semistandard/bin/cmd.js', \ 'node_modules/.bin/standard', \]) endfunction diff --git a/ale_linters/less/lessc.vim b/ale_linters/less/lessc.vim index 4ec8b00e..4ec8b00e 100755..100644 --- a/ale_linters/less/lessc.vim +++ b/ale_linters/less/lessc.vim diff --git a/ale_linters/markdown/mdl.vim b/ale_linters/markdown/mdl.vim index 305f5359..fd44de6e 100644 --- a/ale_linters/markdown/mdl.vim +++ b/ale_linters/markdown/mdl.vim @@ -17,18 +17,17 @@ function! ale_linters#markdown#mdl#GetCommand(buffer) abort let l:options = ale#Var(a:buffer, 'markdown_mdl_options') return ale#Escape(l:executable) . l:exec_args - \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -j' . (!empty(l:options) ? ' ' . l:options : '') endfunction function! ale_linters#markdown#mdl#Handle(buffer, lines) abort - " matches: '(stdin):173: MD004 Unordered list style' - let l:pattern = ':\(\d*\): \(.*\)$' let l:output = [] - for l:match in ale#util#GetMatches(a:lines, l:pattern) + for l:error in ale#util#FuzzyJSONDecode(a:lines, []) call add(l:output, { - \ 'lnum': l:match[1] + 0, - \ 'text': l:match[2], + \ 'lnum': l:error['line'], + \ 'code': l:error['rule'] . '/' . join(l:error['aliases'], '/'), + \ 'text': l:error['description'], \ 'type': 'W', \}) endfor diff --git a/ale_linters/nim/nimlsp.vim b/ale_linters/nim/nimlsp.vim new file mode 100644 index 00000000..5d041043 --- /dev/null +++ b/ale_linters/nim/nimlsp.vim @@ -0,0 +1,33 @@ +" Author: jeremija <https://github.com/jeremija> +" Description: Support for nimlsp (language server for nim) + +call ale#Set('nim_nimlsp_nim_sources', '') + +function! ale_linters#nim#nimlsp#GetProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git') + + if !empty(l:project_root) + return fnamemodify(l:project_root, ':h:h') + endif + + return '' +endfunction + +function! ale_linters#nim#nimlsp#GetCommand(buffer) abort + let l:nim_sources = ale#Var(a:buffer, 'nim_nimlsp_nim_sources') + + if !empty(l:nim_sources) + let l:nim_sources = ale#Escape(l:nim_sources) + endif + + return '%e' . ale#Pad(l:nim_sources) +endfunction + +call ale#linter#Define('nim', { +\ 'name': 'nimlsp', +\ 'lsp': 'stdio', +\ 'executable': 'nimlsp', +\ 'command': function('ale_linters#nim#nimlsp#GetCommand'), +\ 'language': 'nim', +\ 'project_root': function('ale_linters#nim#nimlsp#GetProjectRoot'), +\}) diff --git a/ale_linters/php/psalm.vim b/ale_linters/php/psalm.vim index 3cdb026a..834d0993 100644 --- a/ale_linters/php/psalm.vim +++ b/ale_linters/php/psalm.vim @@ -1,7 +1,7 @@ " Author: Matt Brown <https://github.com/muglug> " Description: plugin for Psalm, static analyzer for PHP -call ale#Set('psalm_langserver_executable', 'psalm-language-server') +call ale#Set('psalm_langserver_executable', 'psalm') call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0)) function! ale_linters#php#psalm#GetProjectRoot(buffer) abort @@ -14,8 +14,8 @@ call ale#linter#Define('php', { \ 'name': 'psalm', \ 'lsp': 'stdio', \ 'executable': {b -> ale#node#FindExecutable(b, 'psalm_langserver', [ -\ 'vendor/bin/psalm-language-server', +\ 'vendor/bin/psalm', \ ])}, -\ 'command': '%e', +\ 'command': '%e --language-server', \ 'project_root': function('ale_linters#php#psalm#GetProjectRoot'), \}) diff --git a/ale_linters/powershell/powershell.vim b/ale_linters/powershell/powershell.vim index a63191fd..a63191fd 100755..100644 --- a/ale_linters/powershell/powershell.vim +++ b/ale_linters/powershell/powershell.vim diff --git a/ale_linters/python/mypy.vim b/ale_linters/python/mypy.vim index c4c6507f..dc4044e6 100644 --- a/ale_linters/python/mypy.vim +++ b/ale_linters/python/mypy.vim @@ -78,4 +78,5 @@ call ale#linter#Define('python', { \ 'executable': function('ale_linters#python#mypy#GetExecutable'), \ 'command': function('ale_linters#python#mypy#GetCommand'), \ 'callback': 'ale_linters#python#mypy#Handle', +\ 'output_stream': 'both' \}) diff --git a/ale_linters/ruby/brakeman.vim b/ale_linters/ruby/brakeman.vim index a8088080..2dc48740 100644 --- a/ale_linters/ruby/brakeman.vim +++ b/ale_linters/ruby/brakeman.vim @@ -36,7 +36,7 @@ function! ale_linters#ruby#brakeman#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'ruby_brakeman_executable') - return ale#handlers#ruby#EscapeExecutable(l:executable, 'brakeman') + return ale#ruby#EscapeExecutable(l:executable, 'brakeman') \ . ' -f json -q ' \ . ale#Var(a:buffer, 'ruby_brakeman_options') \ . ' -p ' . ale#Escape(l:rails_root) diff --git a/ale_linters/ruby/debride.vim b/ale_linters/ruby/debride.vim new file mode 100644 index 00000000..3b2cc443 --- /dev/null +++ b/ale_linters/ruby/debride.vim @@ -0,0 +1,42 @@ +" Author: Eddie Lebow https://github.com/elebow +" Description: debride, a dead method detector for Ruby files + +call ale#Set('ruby_debride_executable', 'debride') +call ale#Set('ruby_debride_options', '') + +function! ale_linters#ruby#debride#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_debride_executable') + + return ale#ruby#EscapeExecutable(l:executable, 'debride') + \ . ale#Var(a:buffer, 'ruby_debride_options') + \ . ' %s' +endfunction + +function! ale_linters#ruby#debride#HandleOutput(buffer, lines) abort + let l:output = [] + + for l:line in a:lines + if l:line !~# '^ ' + continue + endif + + let l:elements = split(l:line) + let l:method_name = l:elements[0] + let l:lnum = split(l:elements[1], ':')[1] + + call add(l:output, { + \ 'lnum': 0 + l:lnum, + \ 'text': 'Possible unused method: ' . l:method_name, + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('ruby', { +\ 'name': 'debride', +\ 'executable': {b -> ale#Var(b, 'ruby_debride_executable')}, +\ 'command': function('ale_linters#ruby#debride#GetCommand'), +\ 'callback': 'ale_linters#ruby#debride#HandleOutput', +\}) diff --git a/ale_linters/ruby/rails_best_practices.vim b/ale_linters/ruby/rails_best_practices.vim index a94fb671..36646647 100644 --- a/ale_linters/ruby/rails_best_practices.vim +++ b/ale_linters/ruby/rails_best_practices.vim @@ -33,7 +33,7 @@ function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort 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') + return ale#ruby#EscapeExecutable(l:executable, 'rails_best_practices') \ . ' --silent -f json --output-file ' . l:output_file \ . ale#Var(a:buffer, 'ruby_rails_best_practices_options') \ . ale#Escape(l:rails_root) diff --git a/ale_linters/ruby/reek.vim b/ale_linters/ruby/reek.vim index e39e366f..226b452e 100644 --- a/ale_linters/ruby/reek.vim +++ b/ale_linters/ruby/reek.vim @@ -14,7 +14,7 @@ function! ale_linters#ruby#reek#GetCommand(buffer, version) abort \ ? ' --stdin-filename %s' \ : '' - return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek') + return ale#ruby#EscapeExecutable(l:executable, 'reek') \ . ' -f json --no-progress --no-color --force-exclusion' \ . l:display_name_args endfunction diff --git a/ale_linters/ruby/rubocop.vim b/ale_linters/ruby/rubocop.vim index 8b9e9c84..410ed0ea 100644 --- a/ale_linters/ruby/rubocop.vim +++ b/ale_linters/ruby/rubocop.vim @@ -7,7 +7,7 @@ call ale#Set('ruby_rubocop_options', '') function! ale_linters#ruby#rubocop#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable') - return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop') + return ale#ruby#EscapeExecutable(l:executable, 'rubocop') \ . ' --format json --force-exclusion ' \ . ale#Var(a:buffer, 'ruby_rubocop_options') \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) diff --git a/ale_linters/ruby/sorbet.vim b/ale_linters/ruby/sorbet.vim index ee765a6e..cae0683c 100644 --- a/ale_linters/ruby/sorbet.vim +++ b/ale_linters/ruby/sorbet.vim @@ -5,7 +5,7 @@ function! ale_linters#ruby#sorbet#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable') let l:options = ale#Var(a:buffer, 'ruby_sorbet_options') - return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb') + return ale#ruby#EscapeExecutable(l:executable, 'srb') \ . ' tc' \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --lsp --disable-watchman' diff --git a/ale_linters/ruby/standardrb.vim b/ale_linters/ruby/standardrb.vim index f075a7d5..f751e803 100644 --- a/ale_linters/ruby/standardrb.vim +++ b/ale_linters/ruby/standardrb.vim @@ -8,7 +8,7 @@ call ale#Set('ruby_standardrb_options', '') function! ale_linters#ruby#standardrb#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'ruby_standardrb_executable') - return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb') + return ale#ruby#EscapeExecutable(l:executable, 'standardrb') \ . ' --format json --force-exclusion ' \ . ale#Var(a:buffer, 'ruby_standardrb_options') \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) diff --git a/ale_linters/scala/metals.vim b/ale_linters/scala/metals.vim new file mode 100644 index 00000000..f78c7119 --- /dev/null +++ b/ale_linters/scala/metals.vim @@ -0,0 +1,48 @@ +" Author: Jeffrey Lau - https://github.com/zoonfafer +" Description: Metals Language Server for Scala https://scalameta.org/metals/ + +call ale#Set('scala_metals_executable', 'metals-vim') +call ale#Set('scala_metals_project_root', '') + +function! ale_linters#scala#metals#GetProjectRoot(buffer) abort + let l:project_root = ale#Var(a:buffer, 'scala_metals_project_root') + + if !empty(l:project_root) + return l:project_root + endif + + let l:potential_roots = [ + \ 'build.sc', + \ 'build.sbt', + \ '.bloop', + \ '.metals', + \] + + for l:root in l:potential_roots + let l:project_root = ale#path#ResolveLocalPath( + \ a:buffer, + \ l:root, + \ '' + \) + + if !empty(l:project_root) + return fnamemodify( + \ l:project_root, + \ ':h', + \) + endif + endfor +endfunction + +function! ale_linters#scala#metals#GetCommand(buffer) abort + return '%e' . ale#Pad('stdio') +endfunction + +call ale#linter#Define('scala', { +\ 'name': 'metals', +\ 'lsp': 'stdio', +\ 'language': 'scala', +\ 'executable': {b -> ale#Var(b, 'scala_metals_executable')}, +\ 'command': function('ale_linters#scala#metals#GetCommand'), +\ 'project_root': function('ale_linters#scala#metals#GetProjectRoot'), +\}) diff --git a/ale_linters/sh/shell.vim b/ale_linters/sh/shell.vim index 189dc21d..171fe64e 100644 --- a/ale_linters/sh/shell.vim +++ b/ale_linters/sh/shell.vim @@ -34,8 +34,10 @@ function! ale_linters#sh#shell#Handle(buffer, lines) abort " Matches patterns line the following: " " bash: line 13: syntax error near unexpected token `d' + " bash:行0: 未预期的符号“done”附近有语法错误 + " bash: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符 " sh: 11: Syntax error: "(" unexpected - let l:pattern = '\v(line |: ?)(\d+): (.+)$' + let l:pattern = '\v([^:]+:\D*)(\d+): (.+)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) diff --git a/ale_linters/solidity/solc.vim b/ale_linters/solidity/solc.vim new file mode 100644 index 00000000..e4f220ac --- /dev/null +++ b/ale_linters/solidity/solc.vim @@ -0,0 +1,35 @@ +" Author: Karl Bartel <karl42@gmail.com> - http://karl.berlin/ +" Description: Report solc compiler errors in Solidity code + +call ale#Set('solidity_solc_options', '') + +function! ale_linters#solidity#solc#Handle(buffer, lines) abort + " Matches patterns like the following: + " /path/to/file/file.sol:1:10: Error: Identifier not found or not unique. + let l:pattern = '\v^[^:]+:(\d+):(\d+): (Error|Warning): (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:isError = l:match[3] is? 'error' + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[4], + \ 'type': l:isError ? 'E' : 'W', + \}) + endfor + + return l:output +endfunction + +function! ale_linters#solidity#solc#GetCommand(buffer) abort + return 'solc' . ale#Pad(ale#Var(a:buffer, 'solidity_solc_options')) . ' %s' +endfunction + +call ale#linter#Define('solidity', { +\ 'name': 'solc', +\ 'executable': 'solc', +\ 'command': function('ale_linters#solidity#solc#GetCommand'), +\ 'callback': 'ale_linters#solidity#solc#Handle', +\ 'output_stream': 'stderr', +\}) diff --git a/ale_linters/terraform/terraform.vim b/ale_linters/terraform/terraform.vim index 0429cb7a..0429cb7a 100755..100644 --- a/ale_linters/terraform/terraform.vim +++ b/ale_linters/terraform/terraform.vim diff --git a/ale_linters/terraform/tflint.vim b/ale_linters/terraform/tflint.vim index 6d54a8b1..f57ee6b6 100644 --- a/ale_linters/terraform/tflint.vim +++ b/ale_linters/terraform/tflint.vim @@ -9,23 +9,69 @@ call ale#Set('terraform_tflint_executable', 'tflint') function! ale_linters#terraform#tflint#Handle(buffer, lines) abort let l:output = [] + let l:pattern = '\v^(.*):(\d+),(\d+)-(\d+)?,?(\d+): (.{-1,}); (.+)$' + let l:json = ale#util#FuzzyJSONDecode(a:lines, {}) - for l:error in ale#util#FuzzyJSONDecode(a:lines, []) - if l:error.type is# 'ERROR' - let l:type = 'E' - elseif l:error.type is# 'NOTICE' - let l:type = 'I' - else - let l:type = 'W' - endif - - call add(l:output, { - \ 'lnum': l:error.line, - \ 'text': l:error.message, - \ 'type': l:type, - \ 'code': l:error.detector, - \}) - endfor + " This is a rough test for tflint's output format + " On versions prior to 0.11 it outputs all errors as a single level list + if type(l:json) is v:t_list + for l:error in l:json + if l:error.type is# 'ERROR' + let l:type = 'E' + elseif l:error.type is# 'NOTICE' + let l:type = 'I' + else + let l:type = 'W' + endif + + call add(l:output, { + \ 'lnum': l:error.line, + \ 'text': l:error.message, + \ 'type': l:type, + \ 'code': l:error.detector, + \}) + endfor + else + for l:error in get(l:json, 'errors', []) + for l:match in ale#util#GetMatches(l:error.message, [l:pattern]) + if l:match[4] is# '' + let l:match[4] = l:match[2] + endif + + call add(l:output, { + \ 'filename': l:match[1], + \ 'lnum': str2nr(l:match[2]), + \ 'col': str2nr(l:match[3]), + \ 'end_lnum': str2nr(l:match[4]), + \ 'end_col': str2nr(l:match[5]), + \ 'text': l:match[7], + \ 'code': l:match[6], + \ 'type': 'E', + \}) + endfor + endfor + + for l:error in get(l:json, 'issues', []) + if l:error.rule.severity is# 'ERROR' + let l:type = 'E' + elseif l:error.rule.severity is# 'NOTICE' + let l:type = 'I' + else + let l:type = 'W' + endif + + call add(l:output, { + \ 'filename': l:error.range.filename, + \ 'lnum': l:error.range.start.line, + \ 'col': l:error.range.start.column, + \ 'end_lnum': l:error.range.end.line, + \ 'end_col': l:error.range.end.column, + \ 'text': l:error.message, + \ 'code': l:error.rule.name, + \ 'type': l:type, + \}) + endfor + endif return l:output endfunction diff --git a/ale_linters/verilog/vlog.vim b/ale_linters/verilog/vlog.vim index 37d21c4c..951e2037 100644 --- a/ale_linters/verilog/vlog.vim +++ b/ale_linters/verilog/vlog.vim @@ -24,6 +24,20 @@ function! ale_linters#verilog#vlog#Handle(buffer, lines) abort \}) endfor + "Matches patterns like the following: + "** Warning: (vlog-2623) add.v(7): Undefined variable: C. + "** Error: (vlog-13294) file.v(1): Identifier must be declared with a port mode: C. + " let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)' + let l:pattern = '^**\s\(\w*\):\s\([^)]*)\)[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)' + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[3] + 0, + \ 'type': l:match[1] is? 'Error' ? 'E' : 'W', + \ 'text': l:match[2] . ' ' . l:match[4], + \}) + endfor + return l:output endfunction |