From 9e97a6914e1f7f5ab4ac80c33150c42f733d3a1b Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Wed, 7 Nov 2018 17:33:14 +0900 Subject: [PATCH 01/12] Add bibclen fixer support Closes #1910 --- README.md | 1 + ale_linters/bib/bibclean.vim | 74 +++++++++++++++++++ autoload/ale/fix/registry.vim | 5 ++ autoload/ale/fixers/bibclean.vim | 15 ++++ doc/ale-bib.txt | 19 +++++ doc/ale.txt | 3 + test/command_callback/bib_paths/dummy.bib | 0 .../test_bib_bibclean_command_callback.vader | 24 ++++++ .../fixers/test_bibclean_fixer_callback.vader | 30 ++++++++ test/fixers/test_rufo_fixer_callback.vader | 4 +- test/handler/test_bibclean_handler.vader | 35 +++++++++ test/script/check-toc | 1 + 12 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 ale_linters/bib/bibclean.vim create mode 100644 autoload/ale/fixers/bibclean.vim create mode 100644 doc/ale-bib.txt create mode 100644 test/command_callback/bib_paths/dummy.bib create mode 100644 test/command_callback/test_bib_bibclean_command_callback.vader create mode 100644 test/fixers/test_bibclean_fixer_callback.vader create mode 100644 test/handler/test_bibclean_handler.vader diff --git a/README.md b/README.md index ad55e255..7a8196f3 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,7 @@ formatting. | AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good), [vale](https://github.com/ValeLint/vale) | | Awk | [gawk](https://www.gnu.org/software/gawk/)| | Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | +| BibTeX | [bibclean](http://ftp.math.utah.edu/pub/bibclean/) | | Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | | C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangd](https://clang.llvm.org/extra/clangd.html), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/), [uncrustify](https://github.com/uncrustify/uncrustify), [ccls](https://github.com/MaskRay/ccls) | | C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangd](https://clang.llvm.org/extra/clangd.html), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [clazy](https://github.com/KDE/clazy) !!, [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/), [uncrustify](https://github.com/uncrustify/uncrustify), [ccls](https://github.com/MaskRay/ccls) | diff --git a/ale_linters/bib/bibclean.vim b/ale_linters/bib/bibclean.vim new file mode 100644 index 00000000..6750f22f --- /dev/null +++ b/ale_linters/bib/bibclean.vim @@ -0,0 +1,74 @@ +" Author: Horacio Sanson - https://github.com/hsanson +" Description: Support for bibclean linter for BibTeX files. + +call ale#Set('bib_bibclean_executable', 'bibclean') + +function! ale_linters#bib#bibclean#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'bib_bibclean_executable') + + return ale#Escape(l:executable) . ' -file-position ' +endfunction + +function! ale_linters#bib#bibclean#get_type(str) abort + if a:str is# '??' + return 'E' + else + return 'W' + endif +endfunction + +function! ale_linters#bib#bibclean#match_msg(line) abort + return matchlist(a:line, '^\(.*\) "stdin", line \(.*\): \(.*\)$') +endfunction + +function! ale_linters#bib#bibclean#match_entry(line) abort + return matchlist(a:line, 'Entry input byte=.* line=\(.*\) column=\(.*\) output .*$') +endfunction + +function! ale_linters#bib#bibclean#match_value(line) abort + return matchlist(a:line, 'Value input byte=.* line=\(.*\) column=\(.*\) output .*$') +endfunction + +function! ale_linters#bib#bibclean#Handle(buffer, lines) abort + let l:output = [] + + let l:type = 'E' + let l:msg = '' + + for l:line in a:lines + if empty(l:msg) + let l:mlist = ale_linters#bib#bibclean#match_msg(l:line) + + if !empty(l:mlist) + let l:msg = l:mlist[3] + let l:type = ale_linters#bib#bibclean#get_type(l:mlist[1]) + endif + else + if l:type is# 'E' + let l:mlist = ale_linters#bib#bibclean#match_entry(l:line) + else + let l:mlist = ale_linters#bib#bibclean#match_value(l:line) + endif + + if !empty(l:mlist) + call add(l:output, { + \ 'lnum': l:mlist[1], + \ 'col': l:mlist[2], + \ 'text': l:msg, + \ 'type': l:type + \}) + let l:msg = '' + endif + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('bib', { +\ 'name': 'bibclean', +\ 'executable_callback': ale#VarFunc('bib_bibclean_executable'), +\ 'command_callback': 'ale_linters#bib#bibclean#GetCommand', +\ 'output_stream': 'stderr', +\ 'callback': 'ale_linters#bib#bibclean#Handle', +\}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index a54be420..75fd1508 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -17,6 +17,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['python'], \ 'description': 'Fix PEP8 issues with autopep8.', \ }, +\ 'bibclean': { +\ 'function': 'ale#fixers#bibclean#Fix', +\ 'suggested_filetypes': ['bib'], +\ 'description': 'Format bib files using bibclean.', +\ }, \ 'black': { \ 'function': 'ale#fixers#black#Fix', \ 'suggested_filetypes': ['python'], diff --git a/autoload/ale/fixers/bibclean.vim b/autoload/ale/fixers/bibclean.vim new file mode 100644 index 00000000..89cb97ab --- /dev/null +++ b/autoload/ale/fixers/bibclean.vim @@ -0,0 +1,15 @@ +" Author: Horacio Sanson - https://github.com/hsanson +" Description: Support for bibclean fixer for BibTeX files. + +call ale#Set('bib_bibclean_executable', 'bibclean') +call ale#Set('bib_bibclean_options', '-align-equals') + +function! ale#fixers#bibclean#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'bib_bibclean_options') + let l:executable = ale#Var(a:buffer, 'bib_bibclean_executable') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' ' . (empty(l:options) ? '' : l:options), + \} +endfunction diff --git a/doc/ale-bib.txt b/doc/ale-bib.txt new file mode 100644 index 00000000..35998c30 --- /dev/null +++ b/doc/ale-bib.txt @@ -0,0 +1,19 @@ +=============================================================================== +ALE BibTeX Integration *ale-bib-options* + + +=============================================================================== +bibclean *ale-bib-bibclean* + +g:ale_bib_bibclean_executable *g:ale_bib_bibclean_executable* + + Type: |String| + Default: `'bibclean'` + +g:ale_bib_bibclean_options *g:ale_bib_bibclean_options* + + Type: |String| + Default: `'-align-equals'` + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index 1a37f73f..48d7bc13 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -31,6 +31,8 @@ CONTENTS *ale-contents* gcc.................................|ale-asm-gcc| awk...................................|ale-awk-options| gawk................................|ale-awk-gawk| + bib...................................|ale-bib-options| + bibclean............................|ale-bib-bibclean| c.....................................|ale-c-options| clang...............................|ale-c-clang| clangd..............................|ale-c-clangd| @@ -403,6 +405,7 @@ Notes: * AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good`, `vale` * Awk: `gawk` * Bash: `language-server`, `shell` (-n flag), `shellcheck`, `shfmt` +* BibTeX: `bibclean` * Bourne Shell: `shell` (-n flag), `shellcheck`, `shfmt` * C: `cppcheck`, `cpplint`!!, `clang`, `clangd`, `clangtidy`!!, `clang-format`, `cquery`, `flawfinder`, `gcc`, `uncrustify`, `ccls` * C++ (filetype cpp): `clang`, `clangd`, `clangcheck`!!, `clangtidy`!!, `clang-format`, `clazy`!!, `cppcheck`, `cpplint`!!, `cquery`, `flawfinder`, `gcc`, `uncrustify`, `ccls` diff --git a/test/command_callback/bib_paths/dummy.bib b/test/command_callback/bib_paths/dummy.bib new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/test_bib_bibclean_command_callback.vader b/test/command_callback/test_bib_bibclean_command_callback.vader new file mode 100644 index 00000000..fa6f7d33 --- /dev/null +++ b/test/command_callback/test_bib_bibclean_command_callback.vader @@ -0,0 +1,24 @@ +Before: + call ale#assert#SetUpLinterTest('bib', 'bibclean') + + let g:ale_ruby_rubocop_executable = 'bibclean' + let g:ale_ruby_rubocop_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to bibclean): + AssertLinter 'bibclean', ale#Escape('bibclean') + \ . ' -file-position ' + +Execute(Should be able to set a custom executable): + let g:ale_bib_bibclean_executable = 'bin/bibclean' + + AssertLinter 'bin/bibclean' , ale#Escape('bin/bibclean') + \ . ' -file-position ' + +Execute(Should not include custom options): + let g:ale_bib_bibclean_options = '-no-prettryprint' + + AssertLinter 'bibclean' , ale#Escape('bibclean') + \ . ' -file-position ' diff --git a/test/fixers/test_bibclean_fixer_callback.vader b/test/fixers/test_bibclean_fixer_callback.vader new file mode 100644 index 00000000..8d3081e3 --- /dev/null +++ b/test/fixers/test_bibclean_fixer_callback.vader @@ -0,0 +1,30 @@ +Before: + Save g:ale_bib_bibclean_executable + Save g:ale_bib_bibclean_options + + let g:ale_bib_bibclean_executable = 'xxxinvalid' + let g:ale_bib_bibclean_options = '-align-equals' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + call ale#test#RestoreDirectory() + +Execute(The bibclean callback should return the correct default values): + call ale#test#SetFilename('../command_callback/bib_paths/dummy.bib') + + AssertEqual + \ {'command': ale#Escape(g:ale_bib_bibclean_executable) . ' -align-equals'}, + \ ale#fixers#bibclean#Fix(bufnr('')) + +Execute(The bibclean callback should include custom bibclean options): + let g:ale_bib_bibclean_options = '-author -check-values' + call ale#test#SetFilename('../command_callback/bib_paths/dummy.bib') + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_bib_bibclean_executable) . ' -author -check-values' + \ }, + \ ale#fixers#bibclean#Fix(bufnr('')) + diff --git a/test/fixers/test_rufo_fixer_callback.vader b/test/fixers/test_rufo_fixer_callback.vader index a0828406..98108efc 100644 --- a/test/fixers/test_rufo_fixer_callback.vader +++ b/test/fixers/test_rufo_fixer_callback.vader @@ -4,9 +4,7 @@ Before: " Use an invalid global executable, so we don't match it. let g:ale_ruby_rufo_executable = 'xxxinvalid' - call ale#test#SetDirectory('/testplugin/test/fixers') - silent cd .. - silent cd command_callback + call ale#test#SetDirectory('/testplugin/test/command_callback') let g:dir = getcwd() After: diff --git a/test/handler/test_bibclean_handler.vader b/test/handler/test_bibclean_handler.vader new file mode 100644 index 00000000..6179d7f5 --- /dev/null +++ b/test/handler/test_bibclean_handler.vader @@ -0,0 +1,35 @@ +Before: + runtime ale_linters/bib/bibclean.vim + +After: + call ale#linter#Reset() + +Execute(The bibclean handler should parse lines correctly): + + AssertEqual + \ [ + \ { + \ 'lnum': '60', + \ 'type': 'W', + \ 'text': 'Unexpected value in ``month = "09"''''.', + \ 'col': '17' + \ }, + \ { + \ 'lnum': '63', + \ 'type': 'E', + \ 'text': 'Expected comma after last field ``keywords''''.', + \ 'col': ' 1' + \ } + \ ], + \ ale_linters#bib#bibclean#Handle(255, [ + \ "%% \"stdin\", line 60: Unexpected value in ``month = \"09\"''.", + \ "%% File positions: input [main.bib] output [stdout]", + \ "%% Entry input byte=1681 line=50 column= 1 output byte=1680 line=50 column= 0", + \ "%% Value input byte=2137 line=60 column=17 output byte=2137 line=60 column=17", + \ "%% Current input byte=2139 line=60 column=19 output byte=2137 line=60 column=17", + \ "?? \"stdin\", line 71: Expected comma after last field ``keywords''.", + \ "?? File positions: input [main.bib] output [stdout]", + \ "?? Entry input byte=2145 line=63 column= 1 output byte=2146 line=63 column= 0", + \ "?? Value input byte=2528 line=71 column= 2 output byte=2527 line=70 column=49", + \ "?? Current input byte=2529 line=71 column= 3 output byte=2528 line=70 column=50" + \ ]) diff --git a/test/script/check-toc b/test/script/check-toc index 8e411589..09d794ee 100755 --- a/test/script/check-toc +++ b/test/script/check-toc @@ -36,6 +36,7 @@ doc_files="$(/bin/ls -1v doc | grep ^ale- | sed 's/^/doc\//' | paste -sd ' ' -)" grep -h '\*ale-.*-options\|^[a-z].*\*ale-.*\*$' $doc_files \ | sed 's/^/ /' \ | sed 's/ALE Shell Integration/ALE sh Integration/' \ + | sed 's/ALE BibTeX Integration/ALE bib Integration/' \ | sed 's/ ALE \(.*\) Integration/\1/' \ | sed 's/ *\*\(..*\)\*$/, \1/' \ | tr '[:upper:]' '[:lower:]' \ From 146769c61671ebfb25cc7efd7acdc35a6a1d33da Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 3 Dec 2018 20:29:26 +0000 Subject: [PATCH 02/12] Tell people to ask for tech support outside of GitHub issues --- .github/ISSUE_TEMPLATE/report-a-bug.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index e617893f..86c62650 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -30,6 +30,11 @@ Operating System: Something went wrong in specifically this place, and I also searched through both open and closed issues for the same problem before reporting a bug here. +Are you having trouble configuring ALE? You should ask tech support style +questions for ALE on [https://vi.stackexchange.com/](Stack Overflow) or perhaps +on [Reddit](https://www.reddit.com/r/vim/) instead. GitHub issues are for +reporting problems with software, not for tech support. + ## Reproducing the bug From 9eda079e021a97d790fa7caef458888ce4a86196 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 3 Dec 2018 20:30:24 +0000 Subject: [PATCH 03/12] Typo --- .github/ISSUE_TEMPLATE/report-a-bug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index 86c62650..3cf02a74 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -31,7 +31,7 @@ Something went wrong in specifically this place, and I also searched through both open and closed issues for the same problem before reporting a bug here. Are you having trouble configuring ALE? You should ask tech support style -questions for ALE on [https://vi.stackexchange.com/](Stack Overflow) or perhaps +questions for ALE on [https://vi.stackexchange.com/](Stack Exchange) or perhaps on [Reddit](https://www.reddit.com/r/vim/) instead. GitHub issues are for reporting problems with software, not for tech support. From 6f32f002e7ae19cecbca4d6eecd618c5a7a722da Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 3 Dec 2018 20:39:10 +0000 Subject: [PATCH 04/12] Revert "Merge pull request #2083 from zackhsi/scalac-until-jvm" This reverts commit 1c89495d771ec6518599bea83dd11a7c1d66ba73, reversing changes made to 4b4b09593b2b090282981d69a9647a3c91d1f8b9. --- ale_linters/scala/scalac.vim | 2 +- test/command_callback/test_scalac_command_callback.vader | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ale_linters/scala/scalac.vim b/ale_linters/scala/scalac.vim index ba105927..3dbdd925 100644 --- a/ale_linters/scala/scalac.vim +++ b/ale_linters/scala/scalac.vim @@ -9,7 +9,7 @@ endfunction call ale#linter#Define('scala', { \ 'name': 'scalac', \ 'executable_callback': {buf -> s:IsSbt(buf) ? '' : 'scalac'}, -\ 'command': '%e -Ystop-before:jvm %t', +\ 'command': '%e -Ystop-after:parser %t', \ 'callback': 'ale#handlers#scala#HandleScalacLintFormat', \ 'output_stream': 'stderr', \}) diff --git a/test/command_callback/test_scalac_command_callback.vader b/test/command_callback/test_scalac_command_callback.vader index 5184aa0b..ea5ae109 100644 --- a/test/command_callback/test_scalac_command_callback.vader +++ b/test/command_callback/test_scalac_command_callback.vader @@ -6,7 +6,7 @@ After: Given scala(An empty Scala file): Execute(The default executable and command should be correct): - AssertLinter 'scalac', ale#Escape('scalac') . ' -Ystop-before:jvm %t' + AssertLinter 'scalac', ale#Escape('scalac') . ' -Ystop-after:parser %t' Given scala.sbt(An empty SBT file): Execute(scalac should not be run for sbt files): From f2b353fa09f5618615acfc1aaf8d075a2555604f Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 4 Dec 2018 09:33:24 +0000 Subject: [PATCH 05/12] Fix a mistake with a link --- .github/ISSUE_TEMPLATE/report-a-bug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index 3cf02a74..73c5fbe7 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -31,7 +31,7 @@ Something went wrong in specifically this place, and I also searched through both open and closed issues for the same problem before reporting a bug here. Are you having trouble configuring ALE? You should ask tech support style -questions for ALE on [https://vi.stackexchange.com/](Stack Exchange) or perhaps +questions for ALE on [Stack Exchange](https://vi.stackexchange.com/) or perhaps on [Reddit](https://www.reddit.com/r/vim/) instead. GitHub issues are for reporting problems with software, not for tech support. From 0d14380d8a246ac749ef15e9b5c481e3639588ac Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 4 Dec 2018 09:42:37 +0000 Subject: [PATCH 06/12] Do not wrap bug report lines --- .github/ISSUE_TEMPLATE/report-a-bug.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index 73c5fbe7..3e6a7e40 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -27,13 +27,9 @@ Operating System: -Something went wrong in specifically this place, and I also searched through -both open and closed issues for the same problem before reporting a bug here. +Something went wrong in specifically this place, and I also searched through both open and closed issues for the same problem before reporting a bug here. -Are you having trouble configuring ALE? You should ask tech support style -questions for ALE on [Stack Exchange](https://vi.stackexchange.com/) or perhaps -on [Reddit](https://www.reddit.com/r/vim/) instead. GitHub issues are for -reporting problems with software, not for tech support. +Are you having trouble configuring ALE? You should ask tech support style questions for ALE on [Stack Exchange](https://vi.stackexchange.com/) or perhaps on [Reddit](https://www.reddit.com/r/vim/) instead. GitHub issues are for reporting problems with software, not for tech support. ## Reproducing the bug From f4af9157e1f19fba1f570df5440bea36f43db5ea Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 4 Dec 2018 19:07:55 +0000 Subject: [PATCH 07/12] Make the suggestion about asking for help friendlier --- .github/ISSUE_TEMPLATE/report-a-bug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index 3e6a7e40..6d345c4a 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -29,7 +29,7 @@ Operating System: Something went wrong in specifically this place, and I also searched through both open and closed issues for the same problem before reporting a bug here. -Are you having trouble configuring ALE? You should ask tech support style questions for ALE on [Stack Exchange](https://vi.stackexchange.com/) or perhaps on [Reddit](https://www.reddit.com/r/vim/) instead. GitHub issues are for reporting problems with software, not for tech support. +Are you having trouble configuring ALE? Try asking for help on [Stack Exchange](https://vi.stackexchange.com/) or perhaps on [Reddit](https://www.reddit.com/r/vim/) instead. The GitHub issue tracker should be used for reporting bugs or asking for new features. ## Reproducing the bug From b4bcbfcc3b26182ce78ac42746c9e6858d5ababf Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Tue, 4 Dec 2018 19:26:17 +0000 Subject: [PATCH 08/12] Add Gitter badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad55e255..defd3df9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) +# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/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) From 3346b200bf6c3cb06359f3f0100d97559e707ddb Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Wed, 5 Dec 2018 21:27:02 +0900 Subject: [PATCH 09/12] Fix javalsp command. The command used to invoke the LSP process was being escaped wrong. Also added a new option to set a different java executable and fixed the documentation. --- ale_linters/java/javalsp.vim | 6 ++++-- doc/ale-java.txt | 12 +++++++++--- .../test_javalsp_command_callback.vader | 6 +++++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ale_linters/java/javalsp.vim b/ale_linters/java/javalsp.vim index 5d1a0c63..1436a52c 100644 --- a/ale_linters/java/javalsp.vim +++ b/ale_linters/java/javalsp.vim @@ -2,15 +2,17 @@ " Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac call ale#Set('java_javalsp_jar', 'javacs.jar') +call ale#Set('java_javalsp_executable', 'java') function! ale_linters#java#javalsp#Executable(buffer) abort - return 'java' + return ale#Var(a:buffer, 'java_javalsp_executable') endfunction function! ale_linters#java#javalsp#Command(buffer) abort let l:jar = ale#Var(a:buffer, 'java_javalsp_jar') + let l:executable = ale_linters#java#javalsp#Executable(a:buffer) - return ale#Escape('java -cp ' . l:jar . ' -Xverify:none org.javacs.Main') + return ale#Escape(l:executable) . ' -cp ' . l:jar . ' -Xverify:none org.javacs.Main' endfunction call ale#linter#Define('java', { diff --git a/doc/ale-java.txt b/doc/ale-java.txt index 7bba12a3..8e40aea0 100644 --- a/doc/ale-java.txt +++ b/doc/ale-java.txt @@ -88,14 +88,20 @@ This generates a out/fat-jar.jar file that contains the language server. To let ALE use this language server you need to set the g:ale_java_javalsp_jar variable to the absolute path of this jar file. +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. + g:ale_java_javalsp_jar *g:ale_java_javalsp_jar* *b:ale_java_javalsp_jar* - Type: String - Default: 'fat-jar.jar + Type: |String| + Default: `'fat-jar.jar'` Path to the location of the vscode-javac language server plugin. - and -d. They are added automatically. =============================================================================== diff --git a/test/command_callback/test_javalsp_command_callback.vader b/test/command_callback/test_javalsp_command_callback.vader index 1fbfddfb..aedb4a4b 100644 --- a/test/command_callback/test_javalsp_command_callback.vader +++ b/test/command_callback/test_javalsp_command_callback.vader @@ -6,5 +6,9 @@ After: call ale#assert#TearDownLinterTest() Execute(The javalsp callback should return the correct default value): - AssertLinter 'java', ale#Escape('java -cp javacs.jar -Xverify:none org.javacs.Main') + AssertLinter 'java', ale#Escape('java') . ' -cp javacs.jar -Xverify:none org.javacs.Main' +Execute(The javalsp java executable should be configurable): + let b:ale_java_javalsp_executable = '/bin/foobar' + + AssertLinter '/bin/foobar', ale#Escape('/bin/foobar') . ' -cp javacs.jar -Xverify:none org.javacs.Main' From 2760cf7018893b42c4ae5c750a7f1d38669aa821 Mon Sep 17 00:00:00 2001 From: Oskar Grunning Date: Thu, 6 Dec 2018 19:23:31 +0100 Subject: [PATCH 10/12] refactor sasslint linter (#2077) Previous implementation required one to have sass-lint globally. This allows you to have it locally, override the executable and add options. --- ale_linters/sass/sasslint.vim | 27 ++++++++++-- ale_linters/scss/sasslint.vim | 28 ++++++++---- autoload/ale/handlers/sasslint.vim | 8 ---- doc/ale-sass.txt | 6 +++ doc/ale-scss.txt | 27 ++++++++++++ doc/ale.txt | 2 + .../with-bin/node_modules/.bin/sass-lint | 0 .../node_modules/sass-lint/bin/sass-lint.js | 0 .../test_sass_sasslint_command_callback.vader | 43 +++++++++++++++++++ .../test_sasslint_command_callback.vader | 11 ----- .../test_scss_sasslint_command_callback.vader | 43 +++++++++++++++++++ 11 files changed, 163 insertions(+), 32 deletions(-) delete mode 100644 autoload/ale/handlers/sasslint.vim create mode 100755 test/command_callback/sasslint-test-files/with-bin/node_modules/.bin/sass-lint create mode 100755 test/command_callback/sasslint-test-files/with-source/node_modules/sass-lint/bin/sass-lint.js create mode 100644 test/command_callback/test_sass_sasslint_command_callback.vader delete mode 100644 test/command_callback/test_sasslint_command_callback.vader create mode 100644 test/command_callback/test_scss_sasslint_command_callback.vader diff --git a/ale_linters/sass/sasslint.vim b/ale_linters/sass/sasslint.vim index 4df56dfd..8d24185d 100644 --- a/ale_linters/sass/sasslint.vim +++ b/ale_linters/sass/sasslint.vim @@ -1,9 +1,28 @@ -" Author: KabbAmine - https://github.com/KabbAmine, -" Ben Falconer +" Author: sQVe - https://github.com/sQVe + +call ale#Set('sass_sasslint_executable', 'sass-lint') +call ale#Set('sass_sasslint_options', '') +call ale#Set('sass_sasslint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#sass#sasslint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'sass_sasslint', [ + \ 'node_modules/sass-lint/bin/sass-lint.js', + \ 'node_modules/.bin/sass-lint', + \]) +endfunction + +function! ale_linters#sass#sasslint#GetCommand(buffer) abort + let l:executable = ale_linters#sass#sasslint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'sass_sasslint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -v -q -f compact %t' +endfunction call ale#linter#Define('sass', { \ 'name': 'sasslint', -\ 'executable': 'sass-lint', -\ 'command_callback': 'ale#handlers#sasslint#GetCommand', +\ 'executable_callback': 'ale_linters#sass#sasslint#GetExecutable', +\ 'command_callback': 'ale_linters#sass#sasslint#GetCommand', \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) diff --git a/ale_linters/scss/sasslint.vim b/ale_linters/scss/sasslint.vim index f6075001..8b725ba6 100644 --- a/ale_linters/scss/sasslint.vim +++ b/ale_linters/scss/sasslint.vim @@ -1,18 +1,28 @@ -" Author: KabbAmine - https://github.com/KabbAmine, Ben Falconer -" +" Author: sQVe - https://github.com/sQVe + +call ale#Set('scss_sasslint_executable', 'sass-lint') +call ale#Set('scss_sasslint_options', '') +call ale#Set('scss_sasslint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#scss#sasslint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'scss_sasslint', [ + \ 'node_modules/sass-lint/bin/sass-lint.js', + \ 'node_modules/.bin/sass-lint', + \]) +endfunction function! ale_linters#scss#sasslint#GetCommand(buffer) abort - return ale#path#BufferCdString(a:buffer) - \ . ale#Escape('sass-lint') - \ . ' -v' - \ . ' -q' - \ . ' -f compact' - \ . ' %t' + let l:executable = ale_linters#scss#sasslint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'scss_sasslint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -v -q -f compact %t' endfunction call ale#linter#Define('scss', { \ 'name': 'sasslint', -\ 'executable': 'sass-lint', +\ 'executable_callback': 'ale_linters#scss#sasslint#GetExecutable', \ 'command_callback': 'ale_linters#scss#sasslint#GetCommand', \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) diff --git a/autoload/ale/handlers/sasslint.vim b/autoload/ale/handlers/sasslint.vim deleted file mode 100644 index 399bf47c..00000000 --- a/autoload/ale/handlers/sasslint.vim +++ /dev/null @@ -1,8 +0,0 @@ -" Author: KabbAmine - https://github.com/KabbAmine, -" Ben Falconer - -function! ale#handlers#sasslint#GetCommand(buffer) abort - return ale#path#BufferCdString(a:buffer) - \ . ale#Escape('sass-lint') - \ . ' -v -q -f compact %t' -endfunction diff --git a/doc/ale-sass.txt b/doc/ale-sass.txt index 08e9a381..735f44b2 100644 --- a/doc/ale-sass.txt +++ b/doc/ale-sass.txt @@ -2,6 +2,12 @@ ALE SASS Integration *ale-sass-options* +=============================================================================== +sasslint *ale-sass-sasslint* + +See |ale-scss-sasslint| for information about the available options. + + =============================================================================== stylelint *ale-sass-stylelint* diff --git a/doc/ale-scss.txt b/doc/ale-scss.txt index 3ad84fc1..07a94fe1 100644 --- a/doc/ale-scss.txt +++ b/doc/ale-scss.txt @@ -8,6 +8,33 @@ prettier *ale-scss-prettier* See |ale-javascript-prettier| for information about the available options. +=============================================================================== +sasslint *ale-scss-sasslint* + +g:ale_scss_sasslint_executable *g:ale_scss_sasslint_executable* + *b:ale_scss_sasslint_executable* + Type: |String| + Default: `'sass-lint'` + + See |ale-integrations-local-executables| + + +g:ale_scss_sasslint_options *g:ale_scss_sasslint_options* + *b:ale_scss_sasslint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to sass-lint. + + +g:ale_scss_sasslint_use_global *g:ale_scss_sasslint_use_global* + *b:ale_scss_sasslint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== stylelint *ale-scss-stylelint* diff --git a/doc/ale.txt b/doc/ale.txt index 1a37f73f..92a100f9 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -288,6 +288,7 @@ CONTENTS *ale-contents* rustc...............................|ale-rust-rustc| rustfmt.............................|ale-rust-rustfmt| sass..................................|ale-sass-options| + sasslint............................|ale-sass-sasslint| stylelint...........................|ale-sass-stylelint| scala.................................|ale-scala-options| sbtserver...........................|ale-scala-sbtserver| @@ -295,6 +296,7 @@ CONTENTS *ale-contents* scalastyle..........................|ale-scala-scalastyle| scss..................................|ale-scss-options| prettier............................|ale-scss-prettier| + sasslint............................|ale-scss-sasslint| stylelint...........................|ale-scss-stylelint| sh....................................|ale-sh-options| sh-language-server..................|ale-sh-language-server| diff --git a/test/command_callback/sasslint-test-files/with-bin/node_modules/.bin/sass-lint b/test/command_callback/sasslint-test-files/with-bin/node_modules/.bin/sass-lint new file mode 100755 index 00000000..e69de29b diff --git a/test/command_callback/sasslint-test-files/with-source/node_modules/sass-lint/bin/sass-lint.js b/test/command_callback/sasslint-test-files/with-source/node_modules/sass-lint/bin/sass-lint.js new file mode 100755 index 00000000..e69de29b diff --git a/test/command_callback/test_sass_sasslint_command_callback.vader b/test/command_callback/test_sass_sasslint_command_callback.vader new file mode 100644 index 00000000..9b9bf906 --- /dev/null +++ b/test/command_callback/test_sass_sasslint_command_callback.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('sass', 'sasslint') + call ale#test#SetFilename('test.sass') + unlet! b:executable + +After: + call ale#assert#TearDownLinterTest() + +Execute(should default to source, bin/sass-lint.js): + call ale#test#SetFilename('sasslint-test-files/with-source/test.sass') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/sasslint-test-files/with-source/node_modules/sass-lint/bin/sass-lint.js' + \) + + AssertLinter b:executable, + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(b:executable) + \ . ' -v -q -f compact %t' + +Execute(should fallback to bin, .bin/sass-lint): + call ale#test#SetFilename('sasslint-test-files/with-bin/test.sass') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/sasslint-test-files/with-bin/node_modules/.bin/sass-lint' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' -v -q -f compact %t' + +Execute(should fallback to global bin): + AssertLinter 'sass-lint', ale#Escape('sass-lint') . ' -v -q -f compact %t' + +Execute(The global executable should be configurable): + let b:ale_sass_sasslint_executable = 'foo' + + AssertLinter 'foo', ale#Escape('foo') . ' -v -q -f compact %t' + +Execute(The options should be configurable): + let b:ale_sass_sasslint_options = '--bar' + + AssertLinter 'sass-lint', ale#Escape('sass-lint') . ' --bar -v -q -f compact %t' diff --git a/test/command_callback/test_sasslint_command_callback.vader b/test/command_callback/test_sasslint_command_callback.vader deleted file mode 100644 index 9142c441..00000000 --- a/test/command_callback/test_sasslint_command_callback.vader +++ /dev/null @@ -1,11 +0,0 @@ -Before: - call ale#assert#SetUpLinterTest('sass', 'sasslint') - call ale#test#SetFilename('test.sass') - -After: - call ale#assert#TearDownLinterTest() - -Execute(The default sasslint command should be correct): - AssertLinter 'sass-lint', - \ ale#path#CdString(expand('%:p:h')) - \ . ale#Escape('sass-lint') . ' -v -q -f compact %t' diff --git a/test/command_callback/test_scss_sasslint_command_callback.vader b/test/command_callback/test_scss_sasslint_command_callback.vader new file mode 100644 index 00000000..1695190a --- /dev/null +++ b/test/command_callback/test_scss_sasslint_command_callback.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('scss', 'sasslint') + call ale#test#SetFilename('test.scss') + unlet! b:executable + +After: + call ale#assert#TearDownLinterTest() + +Execute(should default to source, bin/sass-lint.js): + call ale#test#SetFilename('sasslint-test-files/with-source/test.scss') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/sasslint-test-files/with-source/node_modules/sass-lint/bin/sass-lint.js' + \) + + AssertLinter b:executable, + \ (has('win32') ? 'node.exe ' : '') + \ . ale#Escape(b:executable) + \ . ' -v -q -f compact %t' + +Execute(should fallback to bin, .bin/sass-lint): + call ale#test#SetFilename('sasslint-test-files/with-bin/test.scss') + + let b:executable = ale#path#Simplify( + \ g:dir + \ . '/sasslint-test-files/with-bin/node_modules/.bin/sass-lint' + \) + + AssertLinter b:executable, ale#Escape(b:executable) . ' -v -q -f compact %t' + +Execute(should fallback to global bin): + AssertLinter 'sass-lint', ale#Escape('sass-lint') . ' -v -q -f compact %t' + +Execute(The global executable should be configurable): + let b:ale_scss_sasslint_executable = 'foo' + + AssertLinter 'foo', ale#Escape('foo') . ' -v -q -f compact %t' + +Execute(The options should be configurable): + let b:ale_scss_sasslint_options = '--bar' + + AssertLinter 'sass-lint', ale#Escape('sass-lint') . ' --bar -v -q -f compact %t' From fdd37acc1f381230fc2ed87303e98c7a4daafaad Mon Sep 17 00:00:00 2001 From: pmacosta Date: Thu, 6 Dec 2018 13:27:03 -0500 Subject: [PATCH 11/12] Add support for pydocstyle linter (#2085) The linter can correctly parse pydocstyle output with any of the following command-line options enabled: --explain, --source, --debug, and/or --verbose --- README.md | 2 +- ale_linters/python/pydocstyle.vim | 74 +++++++++++ doc/ale-python.txt | 40 ++++++ doc/ale.txt | 3 +- .../test_pydocstyle_command_callback.vader | 39 ++++++ test/handler/test_pydocstyle_handler.vader | 116 ++++++++++++++++++ 6 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 ale_linters/python/pydocstyle.vim create mode 100644 test/command_callback/test_pydocstyle_command_callback.vader create mode 100644 test/handler/test_pydocstyle_handler.vader diff --git a/README.md b/README.md index defd3df9..6fbd3aa3 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ formatting. | proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) | | Pug | [pug-lint](https://github.com/pugjs/pug-lint) | | Puppet | [languageserver](https://github.com/lingua-pupuli/puppet-editor-services), [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) | -| Python | [autopep8](https://github.com/hhatto/autopep8), [black](https://github.com/ambv/black), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](https://github.com/PyCQA/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pyre](https://github.com/facebook/pyre-check), [pylint](https://www.pylint.org/) !!, [vulture](https://github.com/jendrikseipp/vulture) !!, [yapf](https://github.com/google/yapf) | +| Python | [autopep8](https://github.com/hhatto/autopep8), [black](https://github.com/ambv/black), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](https://github.com/PyCQA/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pydocstyle](https://www.pydocstyle.org/), [pyls](https://github.com/palantir/python-language-server), [pyre](https://github.com/facebook/pyre-check), [pylint](https://www.pylint.org/) !!, [vulture](https://github.com/jendrikseipp/vulture) !!, [yapf](https://github.com/google/yapf) | | QML | [qmlfmt](https://github.com/jesperhh/qmlfmt), [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) | | R | [lintr](https://github.com/jimhester/lintr) | | 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), [refmt](https://github.com/reasonml/reason-cli) | diff --git a/ale_linters/python/pydocstyle.vim b/ale_linters/python/pydocstyle.vim new file mode 100644 index 00000000..ebf92bf1 --- /dev/null +++ b/ale_linters/python/pydocstyle.vim @@ -0,0 +1,74 @@ +" Author: Pablo Acosta +" Description: pydocstyle for python files + +call ale#Set('python_pydocstyle_executable', 'pydocstyle') +call ale#Set('python_pydocstyle_options', '') +call ale#Set('python_pydocstyle_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pydocstyle_auto_pipenv', 0) + +function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pydocstyle_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pydocstyle', ['pydocstyle']) +endfunction + +function! ale_linters#python#pydocstyle#GetCommand(buffer) abort + let l:dir = fnamemodify(bufname(a:buffer), ':p:h') + let l:executable = ale_linters#python#pydocstyle#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pydocstyle' + \ : '' + + return ale#path#CdString(l:dir) + \ . ale#Escape(l:executable) . l:exec_args + \ . ' ' . ale#Var(a:buffer, 'python_pydocstyle_options') + \ . ' ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:t')) +endfunction + +function! ale_linters#python#pydocstyle#Handle(buffer, lines) abort + " Matches patterns like the following: + " mydir/myfile.py:33 in public function `myfunction`: + " DXXX: Error description + let l:fname = ale#Escape(fnamemodify(bufname(a:buffer), ':p:t')) + let l:line1_pattern = '\v^' . l:fname . ':\s*(\d+)\s+.*$' + let l:line2_pattern = '\v^.*([a-zA-Z]\d+):\s*(.*)$' + let l:output = [] + + let l:num_lines = len(a:lines) + let l:index = 0 + + while l:index < l:num_lines + let l:lnum = matchlist(a:lines[l:index], l:line1_pattern) + + if !empty(l:lnum) && (l:index + 1 < l:num_lines) + let l:desc = matchlist(a:lines[l:index + 1], l:line2_pattern) + + if !empty(l:desc) + call add(l:output, { + \ 'lnum': l:lnum[1] + 0, + \ 'col': 1, + \ 'type': 'W', + \ 'text': l:desc[2], + \ 'code': l:desc[1], + \}) + endif + + let l:index = l:index + 2 + else + let l:index = l:index + 1 + endif + endwhile + + return l:output +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pydocstyle', +\ 'executable_callback': 'ale_linters#python#pydocstyle#GetExecutable', +\ 'command_callback': 'ale_linters#python#pydocstyle#GetCommand', +\ 'callback': 'ale_linters#python#pydocstyle#Handle', +\}) diff --git a/doc/ale-python.txt b/doc/ale-python.txt index 0b8e1746..f3f2801a 100644 --- a/doc/ale-python.txt +++ b/doc/ale-python.txt @@ -328,6 +328,46 @@ g:ale_python_pycodestyle_auto_pipenv *g:ale_python_pycodestyle_auto_pipenv* if true. This is overridden by a manually-set executable. +=============================================================================== +pydocstyle *ale-python-pydocstyle* + + +g:ale_python_pydocstyle_executable *g:ale_python_pydocstyle_executable* + *b:ale_python_pydocstyle_executable* + Type: |String| + Default: `'pydocstyle'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `pydocstyle'`. + + +g:ale_python_pydocstyle_options *g:ale_python_pydocstyle_options* + *b:ale_python_pydocstyle_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the + pydocstyle invocation. + + +g:ale_python_pydocstyle_use_global *g:ale_python_pydocstyle_use_global* + *b:ale_python_pydocstyle_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_pydocstyle_auto_pipenv *g:ale_python_pydocstyle_auto_pipenv* + *b:ale_python_pydocstyle_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + =============================================================================== pyflakes *ale-python-pyflakes* diff --git a/doc/ale.txt b/doc/ale.txt index 92a100f9..370e0455 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -258,6 +258,7 @@ CONTENTS *ale-contents* mypy................................|ale-python-mypy| prospector..........................|ale-python-prospector| pycodestyle.........................|ale-python-pycodestyle| + pydocstyle..........................|ale-python-pydocstyle| pyflakes............................|ale-python-pyflakes| pylint..............................|ale-python-pylint| pyls................................|ale-python-pyls| @@ -475,7 +476,7 @@ Notes: * proto: `protoc-gen-lint` * Pug: `pug-lint` * Puppet: `languageserver`, `puppet`, `puppet-lint` -* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pyls`, `pyre`, `pylint`!!, `vulture`!!, `yapf` +* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pydocstyle`, `pyls`, `pyre`, `pylint`!!, `vulture`!!, `yapf` * QML: `qmlfmt`, `qmllint` * R: `lintr` * ReasonML: `merlin`, `ols`, `refmt` diff --git a/test/command_callback/test_pydocstyle_command_callback.vader b/test/command_callback/test_pydocstyle_command_callback.vader new file mode 100644 index 00000000..7e0df9ca --- /dev/null +++ b/test/command_callback/test_pydocstyle_command_callback.vader @@ -0,0 +1,39 @@ +Before: + call ale#assert#SetUpLinterTest('python', 'pydocstyle') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The pydocstyle command callback should return default string): + AssertLinter 'pydocstyle', + \ ale#path#BufferCdString(bufnr('')) + \ . ale#Escape('pydocstyle') . ' ' . ale#Escape('dummy.txt') + +Execute(The pydocstyle command callback should allow options): + let g:ale_python_pydocstyle_options = '--verbose' + + AssertLinter 'pydocstyle', + \ ale#path#BufferCdString(bufnr('')) + \ . ale#Escape('pydocstyle') . ' --verbose ' . ale#Escape('dummy.txt') + +Execute(The pydocstyle executable should be configurable): + let g:ale_python_pydocstyle_executable = '~/.local/bin/pydocstyle' + + AssertLinter '~/.local/bin/pydocstyle', + \ ale#path#BufferCdString(bufnr('')) + \ . ale#Escape('~/.local/bin/pydocstyle') . ' ' . ale#Escape('dummy.txt') + +Execute(Setting executable to 'pipenv' appends 'run pydocstyle'): + let g:ale_python_pydocstyle_executable = 'path/to/pipenv' + + AssertLinter 'path/to/pipenv', + \ ale#path#BufferCdString(bufnr('')) + \ . ale#Escape('path/to/pipenv') . ' run pydocstyle ' . ale#Escape('dummy.txt') + +Execute(Pipenv is detected when python_pydocstyle_auto_pipenv is set): + let g:ale_python_pydocstyle_auto_pipenv = 1 + call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py') + + AssertLinter 'pipenv', + \ ale#path#BufferCdString(bufnr('')) + \ . ale#Escape('pipenv') . ' run pydocstyle ' . ale#Escape('whatever.py') diff --git a/test/handler/test_pydocstyle_handler.vader b/test/handler/test_pydocstyle_handler.vader new file mode 100644 index 00000000..d155dc9a --- /dev/null +++ b/test/handler/test_pydocstyle_handler.vader @@ -0,0 +1,116 @@ +Before: + Save g:ale_warn_about_trailing_whitespace + + let g:ale_warn_about_trailing_whitespace = 1 + + runtime ale_linters/python/pydocstyle.vim + +After: + Restore + + call ale#linter#Reset() + + silent file something_else.py + +" File sample.py +" # sample.py file +" +" def main(): +" """ +" This is a multi-line description that should produce multiple errors to be +" tested by the handler +" """ +" return Fales +" +" +" if __name__ == '__main__': +" main() +" +" The command to generate the handler input is: +" +" $ python -m pydocstyle --verbose --source --explain sample.py +" [...] +" $ + +Execute(Basic pydocstyle warnings should be handled): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Missing docstring in public module', + \ 'code': 'D100', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'text': '1 blank line required between summary line and description (found 0)', + \ 'code': 'D205', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'text': 'First line should end with a period (not ''e'')', + \ 'code': 'D400', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'text': 'First line should be in imperative mood; try rephrasing (found ''This'')', + \ 'code': 'D401', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#python#pydocstyle#Handle(bufnr(''), [ + \ 'Checking file ' . fnamemodify(bufname(bufnr('')), ':p') . '.', + \ ale#Escape(fnamemodify(bufname(bufnr('')), ':t')) . ':1 at module level:', + \ ' D100: Missing docstring in public module', + \ '', + \ ' All modules should normally have docstrings. [...] all functions and', + \ ' classes exported by a module should also have docstrings. Public', + \ ' methods (including the __init__ constructor) should also have', + \ ' docstrings.', + \ ' Note: Public (exported) definitions are either those with names listed', + \ ' in __all__ variable (if present), or those that do not start', + \ ' with a single underscore.', + \ '', + \ ' 1: # 2: 3: s 4: a 5: m 6: p 7: l ...', + \ '', + \ '', + \ ale#Escape(fnamemodify(bufname(bufnr('')), ':t')) . ':4 in public function `main`:', + \ ' D205: 1 blank line required between summary line and description (found 0)', + \ '', + \ ' Multi-line docstrings consist of a summary line just like a one-line', + \ ' docstring, followed by a blank line, followed by a more elaborate', + \ ' description. The summary line may be used by automatic indexing tools;', + \ ' it is important that it fits on one line and is separated from the', + \ ' rest of the docstring by a blank line.', + \ '', + \ ' 3: d 4: e 5: f 6: 7: m 8: a 9: i ...', + \ '', + \ '', + \ ale#Escape(fnamemodify(bufname(bufnr('')), ':t')) . ':4 in public function `main`:', + \ ' D400: First line should end with a period (not ''e'')', + \ '', + \ ' The [first line of a] docstring is a phrase ending in a period.', + \ '', + \ ' 3: d 4: e 5: f 6: 7: m 8: a 9: i ...', + \ '', + \ '', + \ ale#Escape(fnamemodify(bufname(bufnr('')), ':t')) . ':4 in public function `main`:', + \ ' D401: First line should be in imperative mood; try rephrasing (found ''This'')', + \ '', + \ ' [Docstring] prescribes the function or method''s effect as a command:', + \ ' ("Do this", "Return that"), not as a description; e.g. don''t write', + \ ' "Returns the pathname ...".', + \ '', + \ ' 3: d 4: e 5: f 6: 7: m 8: a 9: i ...', + \ ]) + +Execute(Handler should handle empty output): + AssertEqual + \ [], + \ ale_linters#python#pydocstyle#Handle(bufnr(''), []) From 9226e13b31474ac17d0c25cd27aa55bff21d55c2 Mon Sep 17 00:00:00 2001 From: Gordon Fontenot Date: Fri, 7 Dec 2018 17:20:58 -0500 Subject: [PATCH 12/12] Add support for Pod based SwiftLint (#2122) It's common to add SwiftLint as a CocoaPod dependency, instead of as a global binary. In this case we should use that version of SwiftLint before looking for any others. Note that I'm also adding support for SwiftLint in ReactNative projects here as well, where the Pods directory would be nested inside an ios directory. --- ale_linters/swift/swiftlint.vim | 32 +++++++++--- .../Pods/SwiftLint/swiftlint | 0 .../ios/Pods/SwiftLint/swiftlint | 0 .../cocoapods/Pods/SwiftLint/swiftlint | 0 .../react-native/ios/Pods/SwiftLint/swiftlint | 0 .../test_swiftlint_executable_detection.vader | 50 +++++++++++++++++++ 6 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 test/swiftlint-test-files/cocoapods-and-react-native/Pods/SwiftLint/swiftlint create mode 100644 test/swiftlint-test-files/cocoapods-and-react-native/ios/Pods/SwiftLint/swiftlint create mode 100644 test/swiftlint-test-files/cocoapods/Pods/SwiftLint/swiftlint create mode 100644 test/swiftlint-test-files/react-native/ios/Pods/SwiftLint/swiftlint create mode 100644 test/test_swiftlint_executable_detection.vader diff --git a/ale_linters/swift/swiftlint.vim b/ale_linters/swift/swiftlint.vim index 697d246b..a1150658 100644 --- a/ale_linters/swift/swiftlint.vim +++ b/ale_linters/swift/swiftlint.vim @@ -1,6 +1,24 @@ -" Author: David Mohundro +" Author: David Mohundro , Gordon Fontenot " Description: swiftlint for swift files +call ale#Set('swift_swiftlint_executable', 'swiftlint') +call ale#Set('swift_swiftlint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#swift#swiftlint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'swift_swiftlint', [ + \ 'Pods/SwiftLint/swiftlint', + \ 'ios/Pods/SwiftLint/swiftlint', + \ 'swiftlint', + \]) +endfunction + +function! ale_linters#swift#swiftlint#GetCommand(buffer) abort + let l:executable = ale_linters#swift#swiftlint#GetExecutable(a:buffer) + let l:args = 'lint --use-stdin' + + return ale#Escape(l:executable) + \ . ' ' .l:args +endfunction function! ale_linters#swift#swiftlint#Handle(buffer, lines) abort let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$' @@ -8,10 +26,10 @@ function! ale_linters#swift#swiftlint#Handle(buffer, lines) abort for l:match in ale#util#GetMatches(a:lines, l:pattern) let l:item = { - \ 'lnum': str2nr(l:match[2]), - \ 'type': l:match[4] is# 'error' ? 'E' : 'W', - \ 'text': l:match[5], - \} + \ 'lnum': str2nr(l:match[2]), + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \ 'text': l:match[5], + \} if l:match[4] is# 'error' let l:item.type = 'E' @@ -45,7 +63,7 @@ endfunction call ale#linter#Define('swift', { \ 'name': 'swiftlint', -\ 'executable': 'swiftlint', -\ 'command': 'swiftlint lint --use-stdin', +\ 'executable_callback': 'ale_linters#swift#swiftlint#GetExecutable', +\ 'command_callback': 'ale_linters#swift#swiftlint#GetCommand', \ 'callback': 'ale_linters#swift#swiftlint#Handle', \}) diff --git a/test/swiftlint-test-files/cocoapods-and-react-native/Pods/SwiftLint/swiftlint b/test/swiftlint-test-files/cocoapods-and-react-native/Pods/SwiftLint/swiftlint new file mode 100644 index 00000000..e69de29b diff --git a/test/swiftlint-test-files/cocoapods-and-react-native/ios/Pods/SwiftLint/swiftlint b/test/swiftlint-test-files/cocoapods-and-react-native/ios/Pods/SwiftLint/swiftlint new file mode 100644 index 00000000..e69de29b diff --git a/test/swiftlint-test-files/cocoapods/Pods/SwiftLint/swiftlint b/test/swiftlint-test-files/cocoapods/Pods/SwiftLint/swiftlint new file mode 100644 index 00000000..e69de29b diff --git a/test/swiftlint-test-files/react-native/ios/Pods/SwiftLint/swiftlint b/test/swiftlint-test-files/react-native/ios/Pods/SwiftLint/swiftlint new file mode 100644 index 00000000..e69de29b diff --git a/test/test_swiftlint_executable_detection.vader b/test/test_swiftlint_executable_detection.vader new file mode 100644 index 00000000..a8e14c84 --- /dev/null +++ b/test/test_swiftlint_executable_detection.vader @@ -0,0 +1,50 @@ +Before: + let g:ale_swift_swiftlint_executable = 'swiftlint_d' + + call ale#test#SetDirectory('/testplugin/test') + + runtime ale_linters/swift/swiftlint.vim + +After: + let g:ale_has_override = {} + let g:ale_swift_swiftlint_executable = 'swiftlint' + let g:ale_swift_swiftlint_use_global = 0 + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(Global installation should be the default executable): + call ale#test#SetFilename('swiftlint-test-files/global/testfile.swift') + + AssertEqual + \ 'swiftlint_d', + \ ale_linters#swift#swiftlint#GetExecutable(bufnr('')) + +Execute(React Native apps using CocoaPods should take precedence over the default executable): + call ale#test#SetFilename('swiftlint-test-files/react-native/testfile.swift') + + AssertEqual + \ ale#path#Simplify(g:dir . '/swiftlint-test-files/react-native/ios/Pods/SwiftLint/swiftlint'), + \ ale_linters#swift#swiftlint#GetExecutable(bufnr('')) + +Execute(CocoaPods installation should take precedence over the default executable): + call ale#test#SetFilename('swiftlint-test-files/cocoapods/testfile.swift') + + AssertEqual + \ ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods/Pods/SwiftLint/swiftlint'), + \ ale_linters#swift#swiftlint#GetExecutable(bufnr('')) + +Execute(Top level CocoaPods installation should take precedence over React Native installation): + call ale#test#SetFilename('swiftlint-test-files/cocoapods-and-react-native/testfile.swift') + + AssertEqual + \ ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods-and-react-native/Pods/SwiftLint/swiftlint'), + \ ale_linters#swift#swiftlint#GetExecutable(bufnr('')) + +Execute(use-global should override other versions): + let g:ale_swift_swiftlint_use_global = 1 + call ale#test#SetFilename('swiftlint-test-files/cocoapods-and-react-native/testfile.swift') + + AssertEqual + \ 'swiftlint_d', + \ ale_linters#swift#swiftlint#GetExecutable(bufnr(''))