diff options
Diffstat (limited to 'ale_linters')
-rw-r--r-- | ale_linters/d/dmd.vim | 2 | ||||
-rw-r--r-- | ale_linters/elm/make.vim | 170 | ||||
-rw-r--r-- | ale_linters/html/tidy.vim | 8 | ||||
-rw-r--r-- | ale_linters/perl/perlcritic.vim | 19 | ||||
-rw-r--r-- | ale_linters/php/phan.vim | 63 | ||||
-rw-r--r-- | ale_linters/python/flake8.vim | 23 | ||||
-rw-r--r-- | ale_linters/sass/sasslint.vim | 5 | ||||
-rw-r--r-- | ale_linters/scss/sasslint.vim | 14 |
8 files changed, 232 insertions, 72 deletions
diff --git a/ale_linters/d/dmd.vim b/ale_linters/d/dmd.vim index b91238ae..d64b6c3d 100644 --- a/ale_linters/d/dmd.vim +++ b/ale_linters/d/dmd.vim @@ -46,7 +46,7 @@ function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort endif endfor - return 'dmd '. join(l:import_list) . ' -o- -vcolumns -c %t' + return 'dmd '. join(l:import_list) . ' -o- -wi -vcolumns -c %t' endfunction function! ale_linters#d#dmd#Handle(buffer, lines) abort diff --git a/ale_linters/elm/make.vim b/ale_linters/elm/make.vim index a665cef4..cc14fe4e 100644 --- a/ale_linters/elm/make.vim +++ b/ale_linters/elm/make.vim @@ -1,45 +1,26 @@ -" Author: buffalocoder - https://github.com/buffalocoder, soywod - https://github.com/soywod +" Author: buffalocoder - https://github.com/buffalocoder, soywod - https://github.com/soywod, hecrj - https://github.com/hecrj " Description: Elm linting in Ale. Closely follows the Syntastic checker in https://github.com/ElmCast/elm-vim. -call ale#Set('elm_make_executable', 'elm-make') +call ale#Set('elm_make_executable', 'elm') call ale#Set('elm_make_use_global', get(g:, 'ale_use_global_executables', 0)) function! ale_linters#elm#make#GetExecutable(buffer) abort return ale#node#FindExecutable(a:buffer, 'elm_make', [ - \ 'node_modules/.bin/elm-make', + \ 'node_modules/.bin/elm', \]) endfunction function! ale_linters#elm#make#Handle(buffer, lines) abort let l:output = [] - let l:is_windows = has('win32') - let l:temp_dir = l:is_windows ? $TMP : $TMPDIR let l:unparsed_lines = [] - for l:line in a:lines - if l:line[0] is# '[' - let l:errors = json_decode(l:line) - - for l:error in l:errors - " Check if file is from the temp directory. - " Filters out any errors not related to the buffer. - if l:is_windows - let l:file_is_buffer = l:error.file[0:len(l:temp_dir) - 1] is? l:temp_dir - else - let l:file_is_buffer = l:error.file[0:len(l:temp_dir) - 1] is# l:temp_dir - endif - if l:file_is_buffer - call add(l:output, { - \ 'lnum': l:error.region.start.line, - \ 'col': l:error.region.start.column, - \ 'end_lnum': l:error.region.end.line, - \ 'end_col': l:error.region.end.column, - \ 'type': (l:error.type is? 'error') ? 'E' : 'W', - \ 'text': l:error.overview, - \ 'detail': l:error.overview . "\n\n" . l:error.details - \}) - endif - endfor + for l:line in a:lines + if l:line[0] is# '{' + " Elm 0.19 + call ale_linters#elm#make#HandleElm019Line(l:line, l:output) + elseif l:line[0] is# '[' + " Elm 0.18 + call ale_linters#elm#make#HandleElm018Line(l:line, l:output) elseif l:line isnot# 'Successfully generated /dev/null' call add(l:unparsed_lines, l:line) endif @@ -57,23 +38,142 @@ function! ale_linters#elm#make#Handle(buffer, lines) abort return l:output endfunction +function! ale_linters#elm#make#HandleElm019Line(line, output) abort + let l:report = json_decode(a:line) + + if l:report.type is? 'error' + " General problem + let l:details = ale_linters#elm#make#ParseMessage(l:report.message) + + if empty(l:report.path) + let l:report.path = 'Elm' + endif + + if ale_linters#elm#make#FileIsBuffer(l:report.path) + call add(a:output, { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': l:details, + \}) + else + call add(a:output, { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': l:report.path .' - '. l:details, + \ 'detail': l:report.path ." ----------\n\n". l:details, + \}) + endif + else + " Compilation errors + for l:error in l:report.errors + let l:file_is_buffer = ale_linters#elm#make#FileIsBuffer(l:error.path) + + for l:problem in l:error.problems + let l:details = ale_linters#elm#make#ParseMessage(l:problem.message) + + if l:file_is_buffer + " Buffer module has problems + call add(a:output, { + \ 'lnum': l:problem.region.start.line, + \ 'col': l:problem.region.start.column, + \ 'end_lnum': l:problem.region.end.line, + \ 'end_col': l:problem.region.end.column, + \ 'type': 'E', + \ 'text': l:details, + \}) + else + " Imported module has problems + let l:location = l:error.path .':'. l:problem.region.start.line + call add(a:output, { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': l:location .' - '. l:details, + \ 'detail': l:location ." ----------\n\n". l:details, + \}) + endif + endfor + endfor + endif +endfunction + +function! ale_linters#elm#make#HandleElm018Line(line, output) abort + let l:errors = json_decode(a:line) + + for l:error in l:errors + let l:file_is_buffer = ale_linters#elm#make#FileIsBuffer(l:error.file) + + if l:file_is_buffer + " Current buffer has problems + call add(a:output, { + \ 'lnum': l:error.region.start.line, + \ 'col': l:error.region.start.column, + \ 'end_lnum': l:error.region.end.line, + \ 'end_col': l:error.region.end.column, + \ 'type': (l:error.type is? 'error') ? 'E' : 'W', + \ 'text': l:error.overview, + \ 'detail': l:error.overview . "\n\n" . l:error.details + \}) + elseif l:error.type is? 'error' + " Imported module has errors + let l:location = l:error.file .':'. l:error.region.start.line + + call add(a:output, { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': l:location .' - '. l:error.overview, + \ 'detail': l:location ." ----------\n\n". l:error.overview . "\n\n" . l:error.details + \}) + endif + endfor +endfunction + +function! ale_linters#elm#make#FileIsBuffer(path) abort + let l:is_windows = has('win32') + let l:temp_dir = l:is_windows ? $TMP : $TMPDIR + + if has('win32') + return a:path[0:len(l:temp_dir) - 1] is? l:temp_dir + else + return a:path[0:len(l:temp_dir) - 1] is# l:temp_dir + endif +endfunction + +function! ale_linters#elm#make#ParseMessage(message) abort + return join(map(copy(a:message), 'ale_linters#elm#make#ParseMessageItem(v:val)'), '') +endfunction + +function! ale_linters#elm#make#ParseMessageItem(item) abort + if type(a:item) == type('') + return a:item + else + return a:item.string + endif +endfunction + " Return the command to execute the linter in the projects directory. " If it doesn't, then this will fail when imports are needed. function! ale_linters#elm#make#GetCommand(buffer) abort - let l:elm_package = ale#path#FindNearestFile(a:buffer, 'elm-package.json') + let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json') let l:elm_exe = ale_linters#elm#make#GetExecutable(a:buffer) - if empty(l:elm_package) + + if empty(l:elm_json) + " Fallback to Elm 0.18 + let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm-package.json') + endif + + if empty(l:elm_json) let l:dir_set_cmd = '' else - let l:root_dir = fnamemodify(l:elm_package, ':p:h') + let l:root_dir = fnamemodify(l:elm_json, ':p:h') let l:dir_set_cmd = 'cd ' . ale#Escape(l:root_dir) . ' && ' endif - " The elm-make compiler, at the time of this writing, uses '/dev/null' as + " The elm compiler, at the time of this writing, uses '/dev/null' as " a sort of flag to tell the compiler not to generate an output file, - " which is why this is hard coded here. It does not use NUL on Windows. - " Source: https://github.com/elm-lang/elm-make/blob/master/src/Flags.hs + " which is why this is hard coded here. + " Source: https://github.com/elm-lang/elm-compiler/blob/19d5a769b30ec0b2fc4475985abb4cd94cd1d6c3/builder/src/Generate/Output.hs#L253 let l:elm_cmd = ale#Escape(l:elm_exe) + \ . ' make' \ . ' --report=json' \ . ' --output=/dev/null' diff --git a/ale_linters/html/tidy.vim b/ale_linters/html/tidy.vim index 34152c6b..3af64d74 100644 --- a/ale_linters/html/tidy.vim +++ b/ale_linters/html/tidy.vim @@ -3,11 +3,19 @@ " CLI options let g:ale_html_tidy_executable = get(g:, 'ale_html_tidy_executable', 'tidy') +" remove in 2.0 " Look for the old _args variable first. +let s:deprecation_warning_echoed = 0 let s:default_options = get(g:, 'ale_html_tidy_args', '-q -e -language en') let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', s:default_options) function! ale_linters#html#tidy#GetCommand(buffer) abort + " remove in 2.0 + if exists('g:ale_html_tidy_args') && !s:deprecation_warning_echoed + execute 'echom ''Rename your g:ale_html_tidy_args setting to g:ale_html_tidy_options instead. Support for this will removed in ALE 2.0.''' + let s:deprecation_warning_echoed = 1 + endif + " Specify file encoding in options " (Idea taken from https://github.com/scrooloose/syntastic/blob/master/syntax_checkers/html/tidy.vim) let l:file_encoding = get({ diff --git a/ale_linters/perl/perlcritic.vim b/ale_linters/perl/perlcritic.vim index 24f7eb86..e91c8a03 100644 --- a/ale_linters/perl/perlcritic.vim +++ b/ale_linters/perl/perlcritic.vim @@ -18,9 +18,9 @@ function! ale_linters#perl#perlcritic#GetExecutable(buffer) abort endfunction function! ale_linters#perl#perlcritic#GetProfile(buffer) abort - " first see if we've been overridden let l:profile = ale#Var(a:buffer, 'perl_perlcritic_profile') + if l:profile is? '' return '' endif @@ -31,6 +31,7 @@ endfunction function! ale_linters#perl#perlcritic#GetCommand(buffer) abort let l:critic_verbosity = '%l:%c %m\n' + if ale#Var(a:buffer, 'perl_perlcritic_showrules') let l:critic_verbosity = '%l:%c %m [%p]\n' endif @@ -38,17 +39,11 @@ function! ale_linters#perl#perlcritic#GetCommand(buffer) abort let l:profile = ale_linters#perl#perlcritic#GetProfile(a:buffer) let l:options = ale#Var(a:buffer, 'perl_perlcritic_options') - let l:command = ale#Escape(ale_linters#perl#perlcritic#GetExecutable(a:buffer)) - \ . " --verbose '". l:critic_verbosity . "' --nocolor" - - if l:profile isnot? '' - let l:command .= ' --profile ' . ale#Escape(l:profile) - endif - if l:options isnot? '' - let l:command .= ' ' . l:options - endif - - return l:command + return ale#Escape(ale_linters#perl#perlcritic#GetExecutable(a:buffer)) + \ . ' --verbose ' . ale#Escape(l:critic_verbosity) + \ . ' --nocolor' + \ . (!empty(l:profile) ? ' --profile ' . ale#Escape(l:profile) : '') + \ . (!empty(l:options) ? ' ' . l:options : '') endfunction diff --git a/ale_linters/php/phan.vim b/ale_linters/php/phan.vim index f3b3d48f..c6f16356 100644 --- a/ale_linters/php/phan.vim +++ b/ale_linters/php/phan.vim @@ -1,28 +1,65 @@ -" Author: diegoholiveira <https://github.com/diegoholiveira> +" Author: diegoholiveira <https://github.com/diegoholiveira>, haginaga <https://github.com/haginaga> " Description: static analyzer for PHP " Define the minimum severity let g:ale_php_phan_minimum_severity = get(g:, 'ale_php_phan_minimum_severity', 0) +let g:ale_php_phan_executable = get(g:, 'ale_php_phan_executable', 'phan') +let g:ale_php_phan_use_client = get(g:, 'ale_php_phan_use_client', 0) + +function! ale_linters#php#phan#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'php_phan_executable') + + if ale#Var(a:buffer, 'php_phan_use_client') == 1 && l:executable is# 'phan' + let l:executable = 'phan_client' + endif + + return l:executable +endfunction + function! ale_linters#php#phan#GetCommand(buffer) abort - return 'phan -y ' - \ . ale#Var(a:buffer, 'php_phan_minimum_severity') - \ . ' %s' + if ale#Var(a:buffer, 'php_phan_use_client') == 1 + let l:args = '-l ' + \ . ' %s' + else + let l:args = '-y ' + \ . ale#Var(a:buffer, 'php_phan_minimum_severity') + \ . ' %s' + endif + + let l:executable = ale_linters#php#phan#GetExecutable(a:buffer) + + return ale#Escape(l:executable) . ' ' . l:args endfunction function! ale_linters#php#phan#Handle(buffer, lines) abort " Matches against lines like the following: - " - " /path/to/some-filename.php:18 ERRORTYPE message - let l:pattern = '^.*:\(\d\+\)\s\(\w\+\)\s\(.\+\)$' + if ale#Var(a:buffer, 'php_phan_use_client') == 1 + " Phan error: ERRORTYPE: message in /path/to/some-filename.php on line nnn + let l:pattern = '^Phan error: \(\w\+\): \(.\+\) in \(.\+\) on line \(\d\+\)$' + else + " /path/to/some-filename.php:18 ERRORTYPE message + let l:pattern = '^.*:\(\d\+\)\s\(\w\+\)\s\(.\+\)$' + endif + let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) - call add(l:output, { - \ 'lnum': l:match[1] + 0, - \ 'text': l:match[3], - \ 'type': 'W', - \}) + if ale#Var(a:buffer, 'php_phan_use_client') == 1 + let l:dict = { + \ 'lnum': l:match[4] + 0, + \ 'text': l:match[2], + \ 'type': 'W', + \} + else + let l:dict = { + \ 'lnum': l:match[1] + 0, + \ 'text': l:match[3], + \ 'type': 'W', + \} + endif + + call add(l:output, l:dict) endfor return l:output @@ -30,7 +67,7 @@ endfunction call ale#linter#Define('php', { \ 'name': 'phan', -\ 'executable': 'phan', +\ 'executable_callback': 'ale_linters#php#phan#GetExecutable', \ 'command_callback': 'ale_linters#php#phan#GetCommand', \ 'callback': 'ale_linters#php#phan#Handle', \}) diff --git a/ale_linters/python/flake8.vim b/ale_linters/python/flake8.vim index 4ed41935..7398b1dc 100644 --- a/ale_linters/python/flake8.vim +++ b/ale_linters/python/flake8.vim @@ -1,14 +1,15 @@ " Author: w0rp <devw0rp@gmail.com> " Description: flake8 for python files -let g:ale_python_flake8_executable = -\ get(g:, 'ale_python_flake8_executable', 'flake8') - +" remove in 2.0 " Support an old setting as a fallback. +let s:deprecation_warning_echoed = 0 let s:default_options = get(g:, 'ale_python_flake8_args', '') -let g:ale_python_flake8_options = -\ get(g:, 'ale_python_flake8_options', s:default_options) -let g:ale_python_flake8_use_global = get(g:, 'ale_python_flake8_use_global', get(g:, 'ale_use_global_executables', 0)) + +call ale#Set('python_flake8_executable', 'flake8') +call ale#Set('python_flake8_options', s:default_options) +call ale#Set('python_flake8_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_flake8_change_directory', 1) function! s:UsingModule(buffer) abort return ale#Var(a:buffer, 'python_flake8_options') =~# ' *-m flake8' @@ -39,7 +40,15 @@ function! ale_linters#python#flake8#VersionCheck(buffer) abort endfunction function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort - let l:cd_string = ale#path#BufferCdString(a:buffer) + " remove in 2.0 + if exists('g:ale_python_flake8_args') && !s:deprecation_warning_echoed + execute 'echom ''Rename your g:ale_python_flake8_args setting to g:ale_python_flake8_options instead. Support for this will removed in ALE 2.0.''' + let s:deprecation_warning_echoed = 1 + endif + + let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory') + \ ? ale#path#BufferCdString(a:buffer) + \ : '' let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) let l:version = ale#semver#GetVersion(l:executable, a:version_output) diff --git a/ale_linters/sass/sasslint.vim b/ale_linters/sass/sasslint.vim index bbe71255..4df56dfd 100644 --- a/ale_linters/sass/sasslint.vim +++ b/ale_linters/sass/sasslint.vim @@ -1,8 +1,9 @@ -" Author: KabbAmine - https://github.com/KabbAmine +" Author: KabbAmine - https://github.com/KabbAmine, +" Ben Falconer <ben@falconers.me.uk> call ale#linter#Define('sass', { \ 'name': 'sasslint', \ 'executable': 'sass-lint', -\ 'command': 'sass-lint -v -q -f compact %t', +\ 'command_callback': 'ale#handlers#sasslint#GetCommand', \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) diff --git a/ale_linters/scss/sasslint.vim b/ale_linters/scss/sasslint.vim index bd016465..f6075001 100644 --- a/ale_linters/scss/sasslint.vim +++ b/ale_linters/scss/sasslint.vim @@ -1,8 +1,18 @@ -" Author: KabbAmine - https://github.com/KabbAmine +" Author: KabbAmine - https://github.com/KabbAmine, Ben Falconer +" <ben@falconers.me.uk> + +function! ale_linters#scss#sasslint#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) + \ . ale#Escape('sass-lint') + \ . ' -v' + \ . ' -q' + \ . ' -f compact' + \ . ' %t' +endfunction call ale#linter#Define('scss', { \ 'name': 'sasslint', \ 'executable': 'sass-lint', -\ 'command': 'sass-lint -v -q -f compact %t', +\ 'command_callback': 'ale_linters#scss#sasslint#GetCommand', \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) |