diff --git a/README.md b/README.md index 806ada62..7cfbf62e 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ formatting. | Python | [autopep8](https://github.com/hhatto/autopep8), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) | | R | [lintr](https://github.com/jimhester/lintr) | | ReasonML | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-integration-reason-merlin` for configuration instructions, [refmt](https://github.com/reasonml/reason-cli) | -| reStructuredText | [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) | +| reStructuredText | [proselint](http://proselint.com/), [rstcheck](https://github.com/myint/rstcheck), [write-good](https://github.com/btford/write-good) | | RPM spec | [rpmlint](https://github.com/rpm-software-management/rpmlint) (disabled by default; see `:help ale-integration-spec`) | | Ruby | [brakeman](http://brakemanscanner.org/) !!, [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) !!, [reek](https://github.com/troessner/reek), [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org) | | Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) | diff --git a/ale_linters/rst/rstcheck.vim b/ale_linters/rst/rstcheck.vim new file mode 100644 index 00000000..b660627f --- /dev/null +++ b/ale_linters/rst/rstcheck.vim @@ -0,0 +1,37 @@ +" Author: John Nduli https://github.com/jnduli +" Description: Rstcheck for reStructuredText files +" + +function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort + " matches: 'bad_rst.rst:1: (SEVERE/4) Title overline & underline + " mismatch.' + let l:pattern = '\v^(.+):(\d*): \(([a-zA-Z]*)/\d*\) (.+)$' + let l:dir = expand('#' . a:buffer . ':p:h') + let l:output = [] + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'col': 0, + \ 'type': l:match[3] is# 'SEVERE' ? 'E' : 'W', + \ 'text': l:match[4], + \}) + endfor + + return l:output +endfunction + +function! ale_linters#rst#rstcheck#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) + \ . 'rstcheck' + \ . ' %t' +endfunction + + +call ale#linter#Define('rst', { +\ 'name': 'rstcheck', +\ 'executable': 'rstcheck', +\ 'command_callback': 'ale_linters#rst#rstcheck#GetCommand', +\ 'callback': 'ale_linters#rst#rstcheck#Handle', +\ 'output_stream': 'both', +\}) diff --git a/doc/ale.txt b/doc/ale.txt index 76df66d3..83646c57 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -316,7 +316,7 @@ Notes: * Python: `autopep8`, `flake8`, `isort`, `mypy`, `pycodestyle`, `pyls`, `pylint`!!, `yapf` * R: `lintr` * ReasonML: `merlin`, `refmt` -* reStructuredText: `proselint`, `write-good` +* reStructuredText: `proselint`, `rstcheck`, `write-good` * RPM spec: `rpmlint` * Ruby: `brakeman`, `rails_best_practices`!!, `reek`, `rubocop`, `ruby` * Rust: `cargo`!!, `rls`, `rustc` (see |ale-integration-rust|), `rustfmt` diff --git a/test/handler/test_rstcheck_lint_handler.vader b/test/handler/test_rstcheck_lint_handler.vader new file mode 100644 index 00000000..64cb5875 --- /dev/null +++ b/test/handler/test_rstcheck_lint_handler.vader @@ -0,0 +1,33 @@ +Before: + runtime ale_linters/rstcheck/rstcheck.vim + +Execute(Warning and error messages should be handled correctly): + AssertEqual + \ [ + \ { + \ 'filename': ale#path#Winify(expand('%:p:h') . '/bad_python.rst'), + \ 'lnum': 7, + \ 'col': 0, + \ 'type': 'W', + \ 'text': '(python) unexpected EOF while parsing', + \ }, + \ { + \ 'filename': ale#path#Winify(expand('%:p:h') . '/bad_cpp.rst'), + \ 'lnum': 9, + \ 'col': 0, + \ 'type': 'W', + \ 'text': '(cpp) error: ''x'' was not declared in this scope', + \ }, + \ { + \ 'filename': ale#path#Winify(expand('%:p:h') . '/bad_rst.rst'), + \ 'lnum': 1, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Title overline & underline mismatch.', + \ }, + \ ], + \ ale_linters#rst#rstcheck#Handle(1, [ + \ 'bad_python.rst:7: (ERROR/3) (python) unexpected EOF while parsing', + \ 'bad_cpp.rst:9: (ERROR/3) (cpp) error: ''x'' was not declared in this scope', + \ 'bad_rst.rst:1: (SEVERE/4) Title overline & underline mismatch.', + \])