diff options
38 files changed, 749 insertions, 92 deletions
@@ -1,13 +1,13 @@ # Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.com/w0rp/ale.svg?branch=master)](https://travis-ci.com/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) [![Join the chat at https://gitter.im/vim-ale/Lobby](https://badges.gitter.im/vim-ale/Lobby.svg)](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true) +![ALE Logo by Mark Grealish - https://www.bhalash.com/](https://user-images.githubusercontent.com/3518142/59195920-2c339500-8b85-11e9-9c22-f6b7f69637b8.jpg) ALE (Asynchronous Lint Engine) is a plugin providing linting (syntax checking and semantic errors) in NeoVim 0.2.0+ and Vim 8 while you edit your text files, and acts as a Vim [Language Server Protocol](https://langserver.org/) client. -<img src="img/example.gif?raw=true" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim."> +<img src="https://user-images.githubusercontent.com/3518142/59195938-3a81b100-8b85-11e9-8e8d-6a601b1db908.gif" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim."> ALE makes use of NeoVim and Vim 8 job control functions and timers to run linters on the contents of text buffers and return errors as @@ -258,14 +258,14 @@ any other tools. Simply clone the plugin into your `pack` directory. ```bash mkdir -p ~/.vim/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale +git clone --depth 1 https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale ``` #### NeoVim on Unix ```bash mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale +git clone --depth 1 https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale ``` #### Vim 8 on Windows @@ -273,7 +273,7 @@ git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plug ```bash # Run these commands in the "Git for Windows" Bash terminal mkdir -p ~/vimfiles/pack/git-plugins/start -git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale +git clone --depth 1 https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale ``` #### Generating Vim help files @@ -541,7 +541,7 @@ let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' Will give you: -![Echoed message](img/echo.png) +![Echoed message](https://user-images.githubusercontent.com/3518142/59195927-348bd000-8b85-11e9-88b6-508a094f1548.png) See `:help g:ale_echo_msg_format` for more information. diff --git a/ale_linters/c/clangtidy.vim b/ale_linters/c/clangtidy.vim index 6484f8af..f998866a 100644 --- a/ale_linters/c/clangtidy.vim +++ b/ale_linters/c/clangtidy.vim @@ -11,9 +11,12 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy') " http://clang.llvm.org/extra/clang-tidy/checks/list.html call ale#Set('c_clangtidy_checks', []) -" Set this option to manually set some options for clang-tidy. +" Set this option to manually set some options for clang-tidy to use as compile +" flags. " This will disable compile_commands.json detection. call ale#Set('c_clangtidy_options', '') +" Set this option to manually set options for clang-tidy directly. +call ale#Set('c_clangtidy_extra_options', '') call ale#Set('c_build_dir', '') function! ale_linters#c#clangtidy#GetCommand(buffer) abort @@ -25,8 +28,12 @@ function! ale_linters#c#clangtidy#GetCommand(buffer) abort \ ? ale#Var(a:buffer, 'c_clangtidy_options') \ : '' + " Get the options to pass directly to clang-tidy + let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options') + return '%e' \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') + \ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '') \ . ' %s' \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') \ . (!empty(l:options) ? ' -- ' . l:options : '') diff --git a/ale_linters/cpp/clangtidy.vim b/ale_linters/cpp/clangtidy.vim index 841b795f..085bc332 100644 --- a/ale_linters/cpp/clangtidy.vim +++ b/ale_linters/cpp/clangtidy.vim @@ -5,9 +5,12 @@ call ale#Set('cpp_clangtidy_executable', 'clang-tidy') " Set this option to check the checks clang-tidy will apply. call ale#Set('cpp_clangtidy_checks', []) -" Set this option to manually set some options for clang-tidy. +" Set this option to manually set some options for clang-tidy to use as compile +" flags. " This will disable compile_commands.json detection. call ale#Set('cpp_clangtidy_options', '') +" Set this option to manually set options for clang-tidy directly. +call ale#Set('cpp_clangtidy_extra_options', '') call ale#Set('c_build_dir', '') function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort @@ -19,8 +22,12 @@ function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort \ ? ale#Var(a:buffer, 'cpp_clangtidy_options') \ : '' + " Get the options to pass directly to clang-tidy + let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options') + return '%e' \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') + \ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '') \ . ' %s' \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') \ . (!empty(l:options) ? ' -- ' . l:options : '') diff --git a/ale_linters/java/javalsp.vim b/ale_linters/java/javalsp.vim index a327363d..f56675d6 100644 --- a/ale_linters/java/javalsp.vim +++ b/ale_linters/java/javalsp.vim @@ -1,7 +1,7 @@ " Author: Horacio Sanson <https://github.com/hsanson> " Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac -call ale#Set('java_javalsp_executable', 'java') +call ale#Set('java_javalsp_executable', '') function! ale_linters#java#javalsp#Executable(buffer) abort return ale#Var(a:buffer, 'java_javalsp_executable') @@ -10,7 +10,25 @@ endfunction function! ale_linters#java#javalsp#Command(buffer) abort let l:executable = ale_linters#java#javalsp#Executable(a:buffer) - return ale#Escape(l:executable) . ' -Xverify:none -m javacs/org.javacs.Main' + if fnamemodify(l:executable, ':t') is# 'java' + " For backward compatibility. + let l:cmd = [ + \ ale#Escape(l:executable), + \ '--add-exports jdk.compiler/com.sun.tools.javac.api=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.code=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.comp=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.main=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.tree=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.model=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.util=javacs', + \ '--add-opens jdk.compiler/com.sun.tools.javac.api=javacs', + \ '-m javacs/org.javacs.Main', + \] + + return join(l:cmd, ' ') + else + return ale#Escape(l:executable) + endif endfunction call ale#linter#Define('java', { diff --git a/ale_linters/javascript/eslint.vim b/ale_linters/javascript/eslint.vim index 8aeac2d8..31fb413f 100644 --- a/ale_linters/javascript/eslint.vim +++ b/ale_linters/javascript/eslint.vim @@ -6,5 +6,5 @@ call ale#linter#Define('javascript', { \ 'output_stream': 'both', \ 'executable': function('ale#handlers#eslint#GetExecutable'), \ 'command': function('ale#handlers#eslint#GetCommand'), -\ 'callback': 'ale#handlers#eslint#Handle', +\ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/ale_linters/javascript/xo.vim b/ale_linters/javascript/xo.vim index 4ba39101..e24f4a82 100644 --- a/ale_linters/javascript/xo.vim +++ b/ale_linters/javascript/xo.vim @@ -14,7 +14,7 @@ endfunction function! ale_linters#javascript#xo#GetCommand(buffer) abort return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer)) \ . ' ' . ale#Var(a:buffer, 'javascript_xo_options') - \ . ' --reporter unix --stdin --stdin-filename %s' + \ . ' --reporter json --stdin --stdin-filename %s' endfunction " xo uses eslint and the output format is the same @@ -22,5 +22,5 @@ call ale#linter#Define('javascript', { \ 'name': 'xo', \ 'executable': function('ale_linters#javascript#xo#GetExecutable'), \ 'command': function('ale_linters#javascript#xo#GetCommand'), -\ 'callback': 'ale#handlers#eslint#Handle', +\ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/ale_linters/reason/ls.vim b/ale_linters/reason/ls.vim new file mode 100644 index 00000000..fb1114ae --- /dev/null +++ b/ale_linters/reason/ls.vim @@ -0,0 +1,23 @@ +" Author: David Buchan-Swanson <github@deecewan.com> +" Description: Integrate ALE with reason-language-server. + +call ale#Set('reason_ls_executable', '') + +function! ale_linters#reason#ls#FindProjectRoot(buffer) abort + let l:reason_config = ale#path#FindNearestFile(a:buffer, 'bsconfig.json') + + if !empty(l:reason_config) + return fnamemodify(l:reason_config, ':h') + endif + + return '' +endfunction + +call ale#linter#Define('reason', { +\ 'name': 'reason-language-server', +\ 'lsp': 'stdio', +\ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#reason#ls#FindProjectRoot'), +\ 'language': 'reason', +\}) diff --git a/ale_linters/typescript/eslint.vim b/ale_linters/typescript/eslint.vim index bf849337..33a21440 100644 --- a/ale_linters/typescript/eslint.vim +++ b/ale_linters/typescript/eslint.vim @@ -5,5 +5,5 @@ call ale#linter#Define('typescript', { \ 'name': 'eslint', \ 'executable': function('ale#handlers#eslint#GetExecutable'), \ 'command': function('ale#handlers#eslint#GetCommand'), -\ 'callback': 'ale#handlers#eslint#Handle', +\ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/ale_linters/typescript/xo.vim b/ale_linters/typescript/xo.vim index 8b015efd..0a3a717b 100644 --- a/ale_linters/typescript/xo.vim +++ b/ale_linters/typescript/xo.vim @@ -11,7 +11,7 @@ endfunction function! ale_linters#typescript#xo#GetCommand(buffer) abort return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer)) \ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options')) - \ . ' --reporter unix --stdin --stdin-filename %s' + \ . ' --reporter json --stdin --stdin-filename %s' endfunction " xo uses eslint and the output format is the same @@ -19,5 +19,5 @@ call ale#linter#Define('typescript', { \ 'name': 'xo', \ 'executable': function('ale_linters#typescript#xo#GetExecutable'), \ 'command': function('ale_linters#typescript#xo#GetCommand'), -\ 'callback': 'ale#handlers#eslint#Handle', +\ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index f7bd3af6..1a8d02ef 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -297,7 +297,7 @@ let s:default_registry = { \ }, \ 'styler': { \ 'function': 'ale#fixers#styler#Fix', -\ 'suggested_filetypes': ['r'], +\ 'suggested_filetypes': ['r', 'rmarkdown'], \ 'description': 'Fix R files with styler.', \ }, \ 'latexindent': { diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim index 5183f4cd..4d533ff2 100644 --- a/autoload/ale/handlers/eslint.vim +++ b/autoload/ale/handlers/eslint.vim @@ -44,16 +44,9 @@ function! ale#handlers#eslint#GetCommand(buffer) abort return ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' -f unix --stdin --stdin-filename %s' + \ . ' -f json --stdin --stdin-filename %s' endfunction -let s:col_end_patterns = [ -\ '\vParsing error: Unexpected token (.+) ?', -\ '\v''(.+)'' is not defined.', -\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]', -\ '\vUnexpected (console) statement', -\] - function! s:AddHintsForTypeScriptParsingErrors(output) abort for l:item in a:output let l:item.text = substitute( @@ -90,22 +83,71 @@ function! s:CheckForBadConfig(buffer, lines) abort return 0 endfunction -function! ale#handlers#eslint#Handle(buffer, lines) abort - if s:CheckForBadConfig(a:buffer, a:lines) - return [{ - \ 'lnum': 1, - \ 'text': 'eslint configuration error (type :ALEDetail for more information)', - \ 'detail': join(a:lines, "\n"), - \}] +function! s:parseJSON(buffer, lines) abort + try + let l:parsed = json_decode(a:lines[-1]) + catch + return [] + endtry + + if type(l:parsed) != v:t_list || empty(l:parsed) + return [] endif - if a:lines == ['Could not connect'] - return [{ - \ 'lnum': 1, - \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', - \}] + let l:errors = l:parsed[0]['messages'] + + if empty(l:errors) + return [] endif + let l:output = [] + + for l:error in l:errors + let l:obj = ({ + \ 'lnum': get(l:error, 'line', 0), + \ 'text': get(l:error, 'message', ''), + \ 'type': 'E', + \}) + + if get(l:error, 'severity', 0) is# 1 + let l:obj.type = 'W' + endif + + if has_key(l:error, 'ruleId') + let l:code = l:error['ruleId'] + + " Sometimes ESLint returns null here + if !empty(l:code) + let l:obj.code = l:code + endif + endif + + if has_key(l:error, 'column') + let l:obj.col = l:error['column'] + endif + + if has_key(l:error, 'endColumn') + let l:obj.end_col = l:error['endColumn'] - 1 + endif + + if has_key(l:error, 'endLine') + let l:obj.end_lnum = l:error['endLine'] + endif + + call add(l:output, l:obj) + endfor + + return l:output +endfunction + +let s:col_end_patterns = [ +\ '\vParsing error: Unexpected token (.+) ?', +\ '\v''(.+)'' is not defined.', +\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]', +\ '\vUnexpected (console) statement', +\] + +function! s:parseLines(buffer, lines) abort " Matches patterns line the following: " " /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle] @@ -120,12 +162,6 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern]) let l:text = l:match[3] - if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore') - if l:text =~# '^File ignored' - continue - endif - endif - let l:obj = { \ 'lnum': l:match[1] + 0, \ 'col': l:match[2] + 0, @@ -143,11 +179,6 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort " The code can be something like 'Error/foo/bar', or just 'Error' if !empty(get(l:split_code, 1)) let l:obj.code = join(l:split_code[1:], '/') - - if l:obj.code is# 'no-trailing-spaces' - \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') - continue - endif endif for l:col_match in ale#util#GetMatches(l:text, s:col_end_patterns) @@ -157,9 +188,59 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort call add(l:output, l:obj) endfor + return l:output +endfunction + +function! s:FilterResult(buffer, obj) abort + if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore') + if a:obj.text =~# '^File ignored' + return 0 + endif + endif + + if has_key(a:obj, 'code') && a:obj.code is# 'no-trailing-spaces' + \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + return 0 + endif + + return 1 +endfunction + +function! s:HandleESLintOutput(buffer, lines, type) abort + if s:CheckForBadConfig(a:buffer, a:lines) + return [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(a:lines, "\n"), + \}] + endif + + if a:lines == ['Could not connect'] + return [{ + \ 'lnum': 1, + \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', + \}] + endif + + if a:type is# 'json' + let l:output = s:parseJSON(a:buffer, a:lines) + else + let l:output = s:parseLines(a:buffer, a:lines) + endif + + call filter(l:output, {idx, obj -> s:FilterResult(a:buffer, obj)}) + if expand('#' . a:buffer . ':t') =~? '\.tsx\?$' call s:AddHintsForTypeScriptParsingErrors(l:output) endif return l:output endfunction + +function! ale#handlers#eslint#HandleJSON(buffer, lines) abort + return s:HandleESLintOutput(a:buffer, a:lines, 'json') +endfunction + +function! ale#handlers#eslint#Handle(buffer, lines) abort + return s:HandleESLintOutput(a:buffer, a:lines, 'lines') +endfunction diff --git a/autoload/ale/handlers/rust.vim b/autoload/ale/handlers/rust.vim index dda6466e..a7fac464 100644 --- a/autoload/ale/handlers/rust.vim +++ b/autoload/ale/handlers/rust.vim @@ -56,14 +56,20 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort endif if !empty(l:span) - call add(l:output, { + let l:output_line = { \ 'lnum': l:span.line_start, \ 'end_lnum': l:span.line_end, \ 'col': l:span.column_start, \ 'end_col': l:span.column_end-1, \ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label), \ 'type': toupper(l:error.level[0]), - \}) + \} + + if has_key(l:error, 'rendered') && !empty(l:error.rendered) + let l:output_line.detail = l:error.rendered + endif + + call add(l:output, l:output_line) endif endfor endfor diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index 8c657675..6a714d6a 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -13,10 +13,13 @@ let s:default_ale_linter_aliases = { \ 'Dockerfile': 'dockerfile', \ 'csh': 'sh', \ 'plaintex': 'tex', +\ 'rmarkdown': 'r', \ 'systemverilog': 'verilog', \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'vimwiki': 'markdown', \ 'vue': ['vue', 'javascript'], +\ 'xsd': ['xsd', 'xml'], +\ 'xslt': ['xslt', 'xml'], \ 'zsh': 'sh', \} diff --git a/autoload/ale/list.vim b/autoload/ale/list.vim index 63d97f35..80a30216 100644 --- a/autoload/ale/list.vim +++ b/autoload/ale/list.vim @@ -71,8 +71,8 @@ function! s:FixList(buffer, list) abort return l:new_list endfunction -function! s:BufWinId(buffer) abort - return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0 +function! s:WinFindBuf(buffer) abort + return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0] endfunction function! s:SetListsImpl(timer_id, buffer, loclist) abort @@ -88,17 +88,19 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort call setqflist([], 'r', {'title': l:title}) endif elseif g:ale_set_loclist - " If windows support is off, bufwinid() may not exist. + " If windows support is off, win_findbuf() may not exist. " We'll set result in the current window, which might not be correct, " but it's better than nothing. - let l:id = s:BufWinId(a:buffer) - - if has('nvim') - call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title) - else - call setloclist(l:id, s:FixList(a:buffer, a:loclist)) - call setloclist(l:id, [], 'r', {'title': l:title}) - endif + let l:ids = s:WinFindBuf(a:buffer) + + for l:id in l:ids + if has('nvim') + call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title) + else + call setloclist(l:id, s:FixList(a:buffer, a:loclist)) + call setloclist(l:id, [], 'r', {'title': l:title}) + endif + endfor endif " Open a window to show the problems if we need to. @@ -181,11 +183,13 @@ function! s:CloseWindowIfNeeded(buffer) abort cclose endif else - let l:win_id = s:BufWinId(a:buffer) + let l:win_ids = s:WinFindBuf(a:buffer) - if g:ale_set_loclist && empty(getloclist(l:win_id)) - lclose - endif + for l:win_id in l:win_ids + if g:ale_set_loclist && empty(getloclist(l:win_id)) + lclose + endif + endfor endif " Ignore 'Cannot close last window' errors. catch /E444/ diff --git a/autoload/ale/lsp/response.vim b/autoload/ale/lsp/response.vim index 9ce05260..30da77e1 100644 --- a/autoload/ale/lsp/response.vim +++ b/autoload/ale/lsp/response.vim @@ -90,7 +90,7 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort \ 'lnum': l:diagnostic.start.line, \ 'col': l:diagnostic.start.offset, \ 'end_lnum': l:diagnostic.end.line, - \ 'end_col': l:diagnostic.end.offset, + \ 'end_col': l:diagnostic.end.offset - 1, \} if has_key(l:diagnostic, 'code') diff --git a/doc/ale-c.txt b/doc/ale-c.txt index be0a3d77..ec7304f4 100644 --- a/doc/ale-c.txt +++ b/doc/ale-c.txt @@ -156,7 +156,7 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options* Type: |String| Default: `''` - This variable can be changed to modify flags given to clang-tidy. + This variable can be changed to modify compiler flags given to clang-tidy. - Setting this variable to a non-empty string, - and working in a buffer where no compilation database is found using @@ -169,6 +169,14 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options* of the |g:ale_c_build_dir_names| directories of the project tree. +g:ale_c_clangtidy_extra_options *g:ale_c_clangtidy_extra_options* + *b:ale_c_clangtidy_extra_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clang-tidy. + + =============================================================================== cppcheck *ale-c-cppcheck* diff --git a/doc/ale-cpp.txt b/doc/ale-cpp.txt index e1f64ab5..50855c10 100644 --- a/doc/ale-cpp.txt +++ b/doc/ale-cpp.txt @@ -125,7 +125,7 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options* Type: |String| Default: `''` - This variable can be changed to modify flags given to clang-tidy. + This variable can be changed to modify compiler flags given to clang-tidy. - Setting this variable to a non-empty string, - and working in a buffer where no compilation database is found using @@ -138,6 +138,14 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options* of the |g:ale_c_build_dir_names| directories of the project tree. +g:ale_cpp_clangtidy_extra_options *g:ale_cpp_clangtidy_extra_options* + *b:ale_cpp_clangtidy_extra_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clang-tidy. + + =============================================================================== clazy *ale-cpp-clazy* diff --git a/doc/ale-java.txt b/doc/ale-java.txt index 65d2299b..a563f1fb 100644 --- a/doc/ale-java.txt +++ b/doc/ale-java.txt @@ -117,16 +117,19 @@ or This generates a dist/mac or dist/windows directory that contains the language server. To let ALE use this language server you need to set the -g:ale_java_javalsp_executable variable to the absolute path of the java +g:ale_java_javalsp_executable variable to the absolute path of the launcher executable in this directory. g:ale_java_javalsp_executable *g:ale_java_javalsp_executable* *b:ale_java_javalsp_executable* Type: |String| - Default: `'java'` - -This variable can be changed to use a different executable for java. + Default: `'launcher'` +This variable must be set to the absolute path of the language server launcher +executable. For example: +> + let g:ale_java_javalsp_executable=/java-language-server/dist/mac/bin/launcher +< =============================================================================== eclipselsp *ale-java-eclipselsp* diff --git a/doc/ale-reasonml.txt b/doc/ale-reasonml.txt index 426d4c46..b8729a55 100644 --- a/doc/ale-reasonml.txt +++ b/doc/ale-reasonml.txt @@ -5,18 +5,19 @@ ALE ReasonML Integration *ale-reasonml-options* =============================================================================== merlin *ale-reasonml-merlin* - To use merlin linter for ReasonML source code you need to make sure Merlin - for Vim is correctly configured. See the corresponding Merlin wiki page for - detailed instructions - (https://github.com/the-lambda-church/merlin/wiki/vim-from-scratch). +To use merlin linter for ReasonML source code you need to make sure Merlin for +Vim is correctly configured. See the corresponding Merlin wiki page for +detailed instructions: +https://github.com/the-lambda-church/merlin/wiki/vim-from-scratch =============================================================================== ols *ale-reasonml-ols* - The `ocaml-language-server` is the engine that powers OCaml and ReasonML - editor support using the Language Server Protocol. See the installation - instructions: - https://github.com/freebroccolo/ocaml-language-server#installation +The `ocaml-language-server` is the engine that powers OCaml and ReasonML +editor support using the Language Server Protocol. See the installation +instructions: +https://github.com/freebroccolo/ocaml-language-server#installation + g:ale_reason_ols_executable *g:ale_reason_ols_executable* *b:ale_reason_ols_executable* @@ -25,6 +26,7 @@ g:ale_reason_ols_executable *g:ale_reason_ols_executable* This variable can be set to change the executable path for `ols`. + g:ale_reason_ols_use_global *g:ale_reason_ols_use_global* *b:ale_reason_ols_use_global* Type: |String| @@ -33,6 +35,24 @@ g:ale_reason_ols_use_global *g:ale_reason_ols_use_global* This variable can be set to `1` to always use the globally installed executable. See also |ale-integrations-local-executables|. + +=============================================================================== +reason-language-server *ale-reasonml-language-server* + +Note: You must set an executable - there is no 'default' install location. +Go to https://github.com/jaredly/reason-language-server and download the +latest release. You can place it anywhere, but ensure you set the executable +path. + + +g:ale_reason_ls_executable *g:ale_reason_ls_executable* + *b:ale_reason_ls_executable* + Type: |String| + + This variable defines the standard location of the language server + executable. This must be set. + + =============================================================================== refmt *ale-reasonml-refmt* @@ -43,6 +63,7 @@ g:ale_reasonml_refmt_executable *g:ale_reasonml_refmt_executable* This variable can be set to pass the path of the refmt fixer. + g:ale_reasonml_refmt_options *g:ale_reasonml_refmt_options* *b:ale_reasonml_refmt_options* Type: |String| @@ -50,5 +71,6 @@ g:ale_reasonml_refmt_options *g:ale_reasonml_refmt_options* This variable can be set to pass additional options to the refmt fixer. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 4d851201..f1087c2d 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -367,6 +367,7 @@ Notes: * ReasonML * `merlin` * `ols` + * `reason-language-server` * `refmt` * reStructuredText * `alex`!! diff --git a/doc/ale.txt b/doc/ale.txt index 23cbacf5..736d8e05 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1012,10 +1012,13 @@ g:ale_linter_aliases *g:ale_linter_aliases* \ 'Dockerfile': 'dockerfile', \ 'csh': 'sh', \ 'plaintex': 'tex', + \ 'rmarkdown': 'r', \ 'systemverilog': 'verilog', \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'vimwiki': 'markdown', \ 'vue': ['vue', 'javascript'], + \ 'xsd': ['xsd', 'xml'], + \ 'xslt': ['xslt', 'xml'], \ 'zsh': 'sh', \} < @@ -2195,6 +2198,7 @@ documented in additional help files. reasonml................................|ale-reasonml-options| merlin................................|ale-reasonml-merlin| ols...................................|ale-reasonml-ols| + reason-language-server................|ale-reasonml-language-server| refmt.................................|ale-reasonml-refmt| restructuredtext........................|ale-restructuredtext-options| textlint..............................|ale-restructuredtext-textlint| diff --git a/img/echo.png b/img/echo.png Binary files differdeleted file mode 100644 index 671a66b2..00000000 --- a/img/echo.png +++ /dev/null diff --git a/img/example.gif b/img/example.gif Binary files differdeleted file mode 100644 index 1e443bf6..00000000 --- a/img/example.gif +++ /dev/null diff --git a/img/issues.png b/img/issues.png Binary files differdeleted file mode 100644 index 7415d039..00000000 --- a/img/issues.png +++ /dev/null diff --git a/img/logo.jpg b/img/logo.jpg Binary files differdeleted file mode 100644 index 1d8468db..00000000 --- a/img/logo.jpg +++ /dev/null diff --git a/img/no_issues.png b/img/no_issues.png Binary files differdeleted file mode 100644 index 397804ea..00000000 --- a/img/no_issues.png +++ /dev/null diff --git a/supported-tools.md b/supported-tools.md index 7d21de8b..8af79f7f 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -376,6 +376,7 @@ formatting. * ReasonML * [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions * [ols](https://github.com/freebroccolo/ocaml-language-server) + * [reason-language-server](https://github.com/jaredly/reason-language-server) * [refmt](https://github.com/reasonml/reason-cli) * reStructuredText * [alex](https://github.com/wooorm/alex) :floppy_disk: diff --git a/test/command_callback/reason_ls_paths/bsconfig.json b/test/command_callback/reason_ls_paths/bsconfig.json new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/reason_ls_paths/bsconfig.json diff --git a/test/command_callback/test_c_clang_tidy_command_callback.vader b/test/command_callback/test_c_clang_tidy_command_callback.vader index f78d0ea7..fa76c66c 100644 --- a/test/command_callback/test_c_clang_tidy_command_callback.vader +++ b/test/command_callback/test_c_clang_tidy_command_callback.vader @@ -29,6 +29,12 @@ Execute(You should be able to manually set compiler flags for clang-tidy): AssertLinter 'clang-tidy', \ ale#Escape('clang-tidy') . ' -checks=' . ale#Escape('*') . ' %s -- -Wall' +Execute(You should be able to manually set flags for clang-tidy): + let b:ale_c_clangtidy_extra_options = '-config=' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' ' . ale#Escape('-config=') . ' %s' + Execute(The build directory should be configurable): let b:ale_c_clangtidy_checks = ['*'] let b:ale_c_build_dir = '/foo/bar' diff --git a/test/command_callback/test_clang_tidy_command_callback.vader b/test/command_callback/test_clang_tidy_command_callback.vader index 3297a4cb..53ae311b 100644 --- a/test/command_callback/test_clang_tidy_command_callback.vader +++ b/test/command_callback/test_clang_tidy_command_callback.vader @@ -29,6 +29,12 @@ Execute(You should be able to manually set compiler flags for clang-tidy): AssertLinter 'clang-tidy', \ ale#Escape('clang-tidy') . ' -checks=' . ale#Escape('*') . ' %s -- -Wall' +Execute(You should be able to manually set flags for clang-tidy): + let b:ale_cpp_clangtidy_extra_options = '-config=' + + AssertLinter 'clang-tidy', + \ ale#Escape('clang-tidy') . ' ' . ale#Escape('-config=') . ' %s' + Execute(The build directory should be configurable): let b:ale_cpp_clangtidy_checks = ['*'] let b:ale_c_build_dir = '/foo/bar' diff --git a/test/command_callback/test_javalsp_command_callback.vader b/test/command_callback/test_javalsp_command_callback.vader index 8bfaa8ee..ca7388c0 100644 --- a/test/command_callback/test_javalsp_command_callback.vader +++ b/test/command_callback/test_javalsp_command_callback.vader @@ -6,9 +6,26 @@ After: call ale#assert#TearDownLinterTest() Execute(The javalsp callback should return the correct default value): - AssertLinter 'java', ale#Escape('java') . ' -Xverify:none -m javacs/org.javacs.Main' + AssertLinter '', ale#Escape('') Execute(The javalsp java executable should be configurable): let b:ale_java_javalsp_executable = '/bin/foobar' - AssertLinter '/bin/foobar', ale#Escape('/bin/foobar') . ' -Xverify:none -m javacs/org.javacs.Main' + AssertLinter '/bin/foobar', ale#Escape('/bin/foobar') + +Execute(The javalsp callback should return backward compatible value): + let b:ale_java_javalsp_executable = '/bin/java' + let cmd = [ + \ ale#Escape('/bin/java'), + \ '--add-exports jdk.compiler/com.sun.tools.javac.api=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.code=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.comp=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.main=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.tree=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.model=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.util=javacs', + \ '--add-opens jdk.compiler/com.sun.tools.javac.api=javacs', + \ '-m javacs/org.javacs.Main', + \] + AssertLinter '/bin/java', join(cmd, ' ') + diff --git a/test/command_callback/test_reason_ls_command_callback.vader b/test/command_callback/test_reason_ls_command_callback.vader new file mode 100644 index 00000000..64f672d7 --- /dev/null +++ b/test/command_callback/test_reason_ls_command_callback.vader @@ -0,0 +1,21 @@ +Before: + call ale#assert#SetUpLinterTest('reason', 'ls') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The linter should not be run by default): + AssertLinterNotExecuted + +Execute(The executable should be configurable): + let b:ale_reason_ls_executable = 'foobar' + + AssertLinter 'foobar', ale#Escape('foobar') + +Execute(There should be no default project root): + AssertLSPProject '' + +Execute(The project root should be detected using bsconfig.json): + call ale#test#SetFilename('reason_ls_paths/test.ml') + + AssertLSPProject ale#path#Simplify(g:dir . '/reason_ls_paths') diff --git a/test/command_callback/test_xo_command_callback.vader b/test/command_callback/test_xo_command_callback.vader index 12de595d..65cb4f8a 100644 --- a/test/command_callback/test_xo_command_callback.vader +++ b/test/command_callback/test_xo_command_callback.vader @@ -7,14 +7,14 @@ After: call ale#assert#TearDownLinterTest() Execute(The XO executable should be called): - AssertLinter 'xo', ale#Escape('xo') . ' --reporter unix --stdin --stdin-filename %s' + AssertLinter 'xo', ale#Escape('xo') . ' --reporter json --stdin --stdin-filename %s' Execute(The XO executable should be configurable): let b:ale_typescript_xo_executable = 'foobar' - AssertLinter 'foobar', ale#Escape('foobar') . ' --reporter unix --stdin --stdin-filename %s' + AssertLinter 'foobar', ale#Escape('foobar') . ' --reporter json --stdin --stdin-filename %s' Execute(The XO options should be configurable): let b:ale_typescript_xo_options = '--wat' - AssertLinter 'xo', ale#Escape('xo') . ' --wat --reporter unix --stdin --stdin-filename %s' + AssertLinter 'xo', ale#Escape('xo') . ' --wat --reporter json --stdin --stdin-filename %s' diff --git a/test/handler/test_eslint_json_handler.vader b/test/handler/test_eslint_json_handler.vader new file mode 100644 index 00000000..8e07bd80 --- /dev/null +++ b/test/handler/test_eslint_json_handler.vader @@ -0,0 +1,360 @@ +Before: + Save g:ale_javascript_eslint_suppress_eslintignore + Save g:ale_javascript_eslint_suppress_missing_config + Save g:ale_warn_about_trailing_whitespace + Save g:ale_warn_about_trailing_blank_lines + + let g:ale_javascript_eslint_suppress_eslintignore = 0 + let g:ale_javascript_eslint_suppress_missing_config = 0 + let g:ale_warn_about_trailing_whitespace = 1 + let g:ale_warn_about_trailing_blank_lines = 1 + unlet! b:ale_warn_about_trailing_whitespace + unlet! b:ale_warn_about_trailing_blank_lines + +After: + Restore + + unlet! b:ale_javascript_eslint_suppress_eslintignore + unlet! b:ale_javascript_eslint_suppress_missing_config + unlet! b:ale_warn_about_trailing_whitespace + unlet! b:ale_warn_about_trailing_blank_lines + unlet! g:config_error_lines + +Execute(The eslint handler should parse json correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'end_lnum': 1, + \ 'col': 7, + \ 'end_col': 14, + \ 'text': '''variable'' is assigned a value but never used.', + \ 'code': 'no-unused-vars', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 15, + \ 'text': 'Missing semicolon.', + \ 'code': 'semi', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 7, + \ 'end_lnum': 7, + \ 'col': 7, + \ 'end_col': 14, + \ 'text': '''variable'' is already defined.', + \ 'code': 'no-redeclare', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":"no-unused-vars","severity":1,"message":"''variable'' is assigned a value but never used.","line":1,"column":7,"nodeType":"Identifier","endLine":1,"endColumn":15},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":15,"nodeType":"ExpressionStatement","fix":{"range":[46,46],"text":";"}},{"ruleId":"no-redeclare","severity":2,"message":"''variable'' is already defined.","line":7,"column":7,"nodeType":"Identifier","endLine":7,"endColumn":15}],"errorCount":1,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":1,"source":"const variable = {\n a: 3\n};\n\nconsole.log(1)\n\nclass variable {\n}\n"}]' + \ ]) + +Execute(The eslint handler should print a message about a missing configuration file): + let g:config_error_lines = [ + \ '', + \ 'Oops! Something went wrong! :(', + \ '', + \ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:', + \ ' eslint --init', + \ '', + \ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.', + \ '', + \ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint', + \ '', + \ ] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should allow the missing config error to be suppressed): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ '', + \ 'Oops! Something went wrong! :(', + \ '', + \ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:', + \ ' eslint --init', + \ '', + \ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.', + \ '', + \ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint', + \ '', + \ ] + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message for config parsing errors): + let g:config_error_lines = [ + \ 'Cannot read config file: /some/path/or/other/.eslintrc.js', + \ 'Error: Unexpected token <<', + \ '/some/path/or/other/.eslintrc.js:1', + \ '(function (exports, require, module, __filename, __dirname) { <<<>>>', + \ ' ^^', + \ 'SyntaxError: Unexpected token <<', + \ ' at Object.exports.runInThisContext (vm.js:76:16)', + \ ' at Module._compile (module.js:528:28)', + \ ' at Object.Module._extensions..js (module.js:565:10)', + \ ' at Module.load (module.js:473:32)', + \ ' at tryModuleLoad (module.js:432:12)', + \ ' at Function.Module._load (module.js:424:3)', + \ ' at Module.require (module.js:483:17)', + \ ' at require (internal/module.js:20:19)', + \ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)', + \ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress parsing errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ 'Cannot read config file: /some/path/or/other/.eslintrc.js', + \ 'Error: Unexpected token <<', + \ '/some/path/or/other/.eslintrc.js:1', + \ '(function (exports, require, module, __filename, __dirname) { <<<>>>', + \ ' ^^', + \ 'SyntaxError: Unexpected token <<', + \ ' at Object.exports.runInThisContext (vm.js:76:16)', + \ ' at Module._compile (module.js:528:28)', + \ ' at Object.Module._extensions..js (module.js:565:10)', + \ ' at Module.load (module.js:473:32)', + \ ' at tryModuleLoad (module.js:432:12)', + \ ' at Function.Module._load (module.js:424:3)', + \ ' at Module.require (module.js:483:17)', + \ ' at require (internal/module.js:20:19)', + \ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)', + \ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message for invalid configuration settings): + let g:config_error_lines = [ + \ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)', + \ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13', + \ ' at Array.forEach (native)', + \ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)', + \ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)', + \ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)', + \ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)', + \ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)', + \ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)', + \ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress invalid config errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:', + \ ' Configuration for rule "indent" is invalid:', + \ ' Value "off" is the wrong type.', + \ '', + \ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)', + \ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13', + \ ' at Array.forEach (native)', + \ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)', + \ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)', + \ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)', + \ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)', + \ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)', + \ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)', + \ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should print a message when import is not used in a module): + let g:config_error_lines = [ + \ 'ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)', + \ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)', + \ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)', + \ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)', + \ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)', + \ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(Suppressing missing configs shouldn't suppress module import errors): + let b:ale_javascript_eslint_suppress_missing_config = 1 + let g:config_error_lines = [ + \ 'ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.', + \ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)', + \ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)', + \ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)', + \ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)', + \ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)', + \ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)', + \ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)', + \ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ', + \] + + AssertEqual + \ [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(g:config_error_lines, "\n"), + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:]) + +Execute(The eslint handler should hint about using typescript-eslint-parser): + silent! noautocmd file foo.ts + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'Parsing error (You may need configure typescript-eslint-parser): The keyword ''interface'' is reserved', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.ts","messages":[{"ruleId":null,"fatal":true,"severity":2,"message":"Parsing error: The keyword ''interface'' is reserved","line":2,"column":1}],"errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"\ninterface test {}\n"}]', + \ ]) + +Execute(eslint should warn about ignored files by default): + AssertEqual + \ [{ + \ 'lnum': 0, + \ 'type': 'W', + \ 'text': 'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.' + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]', + \ ]) + + AssertEqual + \ [{ + \ 'lnum': 0, + \ 'type': 'W', + \ 'text': 'File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override.', + \ }], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored by default. Use \"--ignore-pattern ''!node_modules/*''\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]', + \ ]) + +Execute(eslint should not warn about ignored files when explicitly disabled): + let g:ale_javascript_eslint_suppress_eslintignore = 1 + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]', + \ ]) + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored by default. Use \"--ignore-pattern ''!node_modules/*''\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]', + \ ]) + +Execute(Failing to connect to eslint_d should be handled correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', + \ }, + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ 'Could not connect', + \ ]) + +Execute(Disabling warnings about trailing spaces should work): + silent! noautocmd file foo.ts + + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 16, + \ 'code': 'no-trailing-spaces', + \ 'type': 'W', + \ 'text': 'Trailing spaces not allowed.', + \ }, + \ ], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]' + \ ]) + + let g:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]' + \ ]) + + let g:ale_warn_about_trailing_whitespace = 1 + let b:ale_warn_about_trailing_whitespace = 0 + + AssertEqual + \ [], + \ ale#handlers#eslint#HandleJSON(bufnr(''), [ + \ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]' + \ ]) diff --git a/test/handler/test_rust_handler.vader b/test/handler/test_rust_handler.vader index 56db9b36..845df2b5 100644 --- a/test/handler/test_rust_handler.vader +++ b/test/handler/test_rust_handler.vader @@ -247,6 +247,57 @@ Execute(The Rust handler should show detailed errors): \ }), \ ]) +Execute(The Rust handler should show detailed clippy errors with rendered field if it's available): + call ale#test#SetFilename('src/playpen.rs') + + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'end_lnum': 4, + \ 'type': 'E', + \ 'col': 21, + \ 'end_col': 22, + \ 'text': 'mismatched types: expected bool, found integral variable', + \ 'detail': 'this is a detailed description', + \ }, + \ ], + \ ale#handlers#rust#HandleRustErrors(bufnr(''), [ + \ '', + \ 'ignore this', + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'mismatched types', + \ 'rendered': 'this is a detailed description', + \ 'spans': [ + \ { + \ 'byte_end': 54, + \ 'byte_start': 52, + \ 'column_end': 23, + \ 'column_start': 21, + \ 'expansion': v:null, + \ 'file_name': ale#path#Simplify('src/playpen.rs'), + \ 'is_primary': v:true, + \ 'label': 'expected bool, found integral variable', + \ 'line_end': 4, + \ 'line_start': 4, + \ } + \ ] + \ }, + \ }), + \ json_encode({ + \ 'message': { + \ 'code': v:null, + \ 'level': 'error', + \ 'message': 'aborting due to previous error(s)', + \ 'spans': [ + \ ] + \ }, + \ }), + \ ]) + Execute(The Rust handler should find correct files): call ale#test#SetFilename('src/noerrors/mod.rs') diff --git a/test/lsp/test_read_lsp_diagnostics.vader b/test/lsp/test_read_lsp_diagnostics.vader index 377e73d9..61ffc73f 100644 --- a/test/lsp/test_read_lsp_diagnostics.vader +++ b/test/lsp/test_read_lsp_diagnostics.vader @@ -219,7 +219,7 @@ Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle tsserver respon \ 'lnum': 1, \ 'col': 11, \ 'end_lnum': 1, - \ 'end_col': 17, + \ 'end_col': 16, \ }, \ ], \ ale#lsp#response#ReadTSServerDiagnostics({"seq":0,"type":"event","event":"semanticDiag","body":{"file":"/bar/foo.ts","diagnostics":[{"start":{"line":1,"offset":11},"end":{"line":1,"offset":17},"text":"Operator ''+'' cannot be applied to types ''3'' and ''{}''.","code":2365}]}}) @@ -234,7 +234,7 @@ Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle warnings from t \ 'code': '2515', \ 'end_lnum': 27, \ 'type': 'W', - \ 'end_col': 14, + \ 'end_col': 13, \ 'text': 'Calls to ''console.log'' are not allowed. (no-console)', \ } \ ], @@ -250,7 +250,7 @@ Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle suggestions fro \ 'code': '2515', \ 'end_lnum': 27, \ 'type': 'I', - \ 'end_col': 14, + \ 'end_col': 13, \ 'text': 'Some info', \ } \ ], diff --git a/test/test_eslint_executable_detection.vader b/test/test_eslint_executable_detection.vader index 5599576e..64383dcb 100644 --- a/test/test_eslint_executable_detection.vader +++ b/test/test_eslint_executable_detection.vader @@ -59,11 +59,11 @@ Execute(eslint.js executables should be run with node on Windows): AssertEqual \ ale#Escape('node.exe') . ' ' \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) - \ . ' -f unix --stdin --stdin-filename %s', + \ . ' -f json --stdin --stdin-filename %s', \ ale#handlers#eslint#GetCommand(bufnr('')) else AssertEqual \ ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) - \ . ' -f unix --stdin --stdin-filename %s', + \ . ' -f json --stdin --stdin-filename %s', \ ale#handlers#eslint#GetCommand(bufnr('')) endif diff --git a/test/test_ignoring_linters.vader b/test/test_ignoring_linters.vader index d758af5c..19f45add 100644 --- a/test/test_ignoring_linters.vader +++ b/test/test_ignoring_linters.vader @@ -249,7 +249,7 @@ Execute(Buffer ignore lists should be applied for tsserver): \ 'nr': 1005, \ 'code': '1005', \ 'type': 'E', - \ 'end_col': 15, + \ 'end_col': 14, \ 'end_lnum': 2, \ 'text': ''','' expected.', \ }, @@ -344,7 +344,7 @@ Execute(ale_disable_lsp should be applied for tsserver): \ 'nr': 1005, \ 'code': '1005', \ 'type': 'E', - \ 'end_col': 15, + \ 'end_col': 14, \ 'end_lnum': 2, \ 'text': ''','' expected.', \ }, |