diff options
36 files changed, 532 insertions, 104 deletions
@@ -48,6 +48,7 @@ formatting tools, and some Language Server Protocol and `tsserver` features. 13. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad) 14. [How can I configure my C or C++ project?](#faq-c-configuration) 15. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration) + 16. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height) <a name="supported-languages"></a> @@ -121,7 +122,7 @@ formatting. | Lua | [luac](https://www.lua.org/manual/5.1/luac.html), [luacheck](https://github.com/mpeterv/luacheck) | | Mail | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale) | | Make | [checkmake](https://github.com/mrtazz/checkmake) | -| Markdown | [alex](https://github.com/wooorm/alex) !!, [mdl](https://github.com/mivok/markdownlint), [prettier](https://github.com/prettier/prettier), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [remark-lint](https://github.com/wooorm/remark-lint) !!, [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) , [textlint](https://textlint.github.io/)| +| Markdown | [alex](https://github.com/wooorm/alex) !!, [markdownlint](https://github.com/DavidAnson/markdownlint) !!, [mdl](https://github.com/mivok/markdownlint), [prettier](https://github.com/prettier/prettier), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [remark-lint](https://github.com/wooorm/remark-lint) !!, [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | | MATLAB | [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) | | Nim | [nim check](https://nim-lang.org/docs/nimc.html) !! | | nix | [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) | @@ -138,6 +139,7 @@ formatting. | Pug | [pug-lint](https://github.com/pugjs/pug-lint) | | Puppet | [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) | | 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/), [prospector](http://github.com/landscapeio/prospector), [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) | +| QML | [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) | | reStructuredText | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [rstcheck](https://github.com/myint/rstcheck), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | @@ -157,7 +159,7 @@ formatting. | Tcl | [nagelfar](http://nagelfar.sourceforge.net) !! | | Terraform | [tflint](https://github.com/wata727/tflint) | | Texinfo | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)| -| Text^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good), [redpen](http://redpen.cc/) | +| Text^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | | Thrift | [thrift](http://thrift.apache.org/) | | TypeScript | [eslint](http://eslint.org/), [prettier](https://github.com/prettier/prettier), [tslint](https://github.com/palantir/tslint), tsserver, typecheck | | Verilog | [iverilog](https://github.com/steveicarus/iverilog), [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) | @@ -700,3 +702,14 @@ let g:ale_pattern_options_enabled = 1 ``` Buffer-local variables for settings always override the global settings. + +<a name="faq-list-window-height"></a> + +### 5.xvi. How can I configure the height of the list in which ALE displays errors? + +To set a default height for the error list, use the `g:ale_list_window_size` variable. + +```vim +" Show 5 lines of errors (default: 10) +let g:ale_list_window_size = 5 +``` diff --git a/ale_linters/fish/fish.vim b/ale_linters/fish/fish.vim index 19158cb0..87ede29a 100644 --- a/ale_linters/fish/fish.vim +++ b/ale_linters/fish/fish.vim @@ -7,22 +7,53 @@ function! ale_linters#fish#fish#Handle(buffer, lines) abort " home/.config/fish/functions/foo.fish (line 1): Missing end to balance this function definition " function foo " ^ - " <W> fish: Error while reading file .config/fish/functions/foo.fish - let l:pattern = '^.* (line \(\d\+\)): \(.*\)$' + " + " OR, patterns such as: + " + " Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'. + " /tmp/vLz620o/258/test.fish (line 2): if set -q SSH_CLIENT || set -q SSH_TTY + " ^ + " + " fish -n can return errors in either format. + let l:pattern = '^\(.* (line \(\d\+\)): \)\(.*\)$' + let l:column_pattern = '^ *\^' let l:output = [] + let l:column_offset = 0 + let l:last_line_with_message = '' + + for l:line in a:lines + " Look for error lines first. + let l:match = matchlist(l:line, l:pattern) + + if !empty(l:match) + if !empty(l:last_line_with_message) + let l:text = l:last_line_with_message + else + let l:text = l:match[3] + endif + + let l:column_offset = len(l:match[1]) + + let l:last_line_with_message = '' + call add(l:output, { + \ 'col': 0, + \ 'lnum': str2nr(l:match[2]), + \ 'text': l:text, + \}) + else + " Look for column markers like ' ^' second. + " The column index will be set according to how long the line is. + let l:column_match = matchstr(l:line, l:column_pattern) - let l:i = 0 - while l:i < len(a:lines) - let l:match = matchlist(a:lines[l:i], l:pattern) - if len(l:match) && len(l:match[2]) - call add(l:output, { - \ 'col': len(a:lines[l:i + 2]), - \ 'lnum': str2nr(l:match[1]), - \ 'text': l:match[2], - \}) - endif - let l:i += 1 - endwhile + if !empty(l:column_match) && !empty(l:output) + let l:output[-1].col = len(l:column_match) - l:column_offset + let l:last_line_with_message = '' + else + let l:last_line_with_message = l:line + let l:column_offset = 0 + endif + endif + endfor return l:output endfunction diff --git a/ale_linters/go/gosimple.vim b/ale_linters/go/gosimple.vim index 8a4c01e1..dbdc3fcf 100644 --- a/ale_linters/go/gosimple.vim +++ b/ale_linters/go/gosimple.vim @@ -1,11 +1,15 @@ " Author: Ben Reedy <https://github.com/breed808> " Description: gosimple for Go files +function! ale_linters#go#gosimple#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) . ' gosimple .' +endfunction + call ale#linter#Define('go', { \ 'name': 'gosimple', \ 'executable': 'gosimple', -\ 'command': 'gosimple %s', -\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\ 'command_callback': 'ale_linters#go#gosimple#GetCommand', +\ 'callback': 'ale#handlers#go#Handler', \ 'output_stream': 'both', \ 'lint_file': 1, \}) diff --git a/ale_linters/go/gotype.vim b/ale_linters/go/gotype.vim index 13055a89..f4bb274e 100644 --- a/ale_linters/go/gotype.vim +++ b/ale_linters/go/gotype.vim @@ -6,7 +6,8 @@ function! ale_linters#go#gotype#GetCommand(buffer) abort return endif - return 'gotype %s' + + return ale#path#BufferCdString(a:buffer) . ' gotype .' endfunction call ale#linter#Define('go', { @@ -14,6 +15,6 @@ call ale#linter#Define('go', { \ 'output_stream': 'stderr', \ 'executable': 'gotype', \ 'command_callback': 'ale_linters#go#gotype#GetCommand', -\ 'callback': 'ale#handlers#unix#HandleAsError', +\ 'callback': 'ale#handlers#go#Handler', \ 'lint_file': 1, \}) diff --git a/ale_linters/go/govet.vim b/ale_linters/go/govet.vim index aae5969d..edf9eb66 100644 --- a/ale_linters/go/govet.vim +++ b/ale_linters/go/govet.vim @@ -8,28 +8,11 @@ function! ale_linters#go#govet#GetCommand(buffer) abort return ale#path#BufferCdString(a:buffer) . ' go vet .' endfunction -function! ale_linters#go#govet#Handler(buffer, lines) abort - let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? ?(.+)$' - let l:output = [] - let l:dir = expand('#' . a:buffer . ':p:h') - - 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': l:match[3] + 0, - \ 'text': l:match[4], - \ 'type': 'E', - \}) - endfor - return l:output -endfunction - call ale#linter#Define('go', { \ 'name': 'go vet', \ 'output_stream': 'stderr', \ 'executable': 'go', \ 'command_callback': 'ale_linters#go#govet#GetCommand', -\ 'callback': 'ale_linters#go#govet#Handler', +\ 'callback': 'ale#handlers#go#Handler', \ 'lint_file': 1, \}) diff --git a/ale_linters/go/staticcheck.vim b/ale_linters/go/staticcheck.vim index ce9e6e38..a3464015 100644 --- a/ale_linters/go/staticcheck.vim +++ b/ale_linters/go/staticcheck.vim @@ -27,7 +27,7 @@ call ale#linter#Define('go', { \ 'name': 'staticcheck', \ 'executable': 'staticcheck', \ 'command_callback': 'ale_linters#go#staticcheck#GetCommand', -\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\ 'callback': 'ale#handlers#go#Handler', \ 'output_stream': 'both', \ 'lint_file': 1, \}) diff --git a/ale_linters/markdown/markdownlint.vim b/ale_linters/markdown/markdownlint.vim new file mode 100644 index 00000000..5c8af650 --- /dev/null +++ b/ale_linters/markdown/markdownlint.vim @@ -0,0 +1,11 @@ +" Author: Ty-Lucas Kelley <tylucaskelley@gmail.com> +" Description: Adds support for markdownlint + +call ale#linter#Define('markdown', { + \ 'name': 'markdownlint', + \ 'executable': 'markdownlint', + \ 'lint_file': 1, + \ 'output_stream': 'both', + \ 'command': 'markdownlint %s', + \ 'callback': 'ale#handlers#markdownlint#Handle' +\ }) diff --git a/ale_linters/markdown/remark_lint.vim b/ale_linters/markdown/remark_lint.vim index 5b3b3d47..98dd0d7b 100644 --- a/ale_linters/markdown/remark_lint.vim +++ b/ale_linters/markdown/remark_lint.vim @@ -1,18 +1,24 @@ -" Author rhysd https://rhysd.github.io/ +" Author rhysd https://rhysd.github.io/, Dirk Roorda (dirkroorda), Adrián González Rus (@adrigzr) " Description: remark-lint for Markdown files function! ale_linters#markdown#remark_lint#Handle(buffer, lines) abort " matches: ' 1:4 warning Incorrect list-item indent: add 1 space list-item-indent remark-lint' - let l:pattern = '^ \+\(\d\+\):\(\d\+\) \(warning\|error\) \(.\+\)$' + " matches: ' 18:71-19:1 error Missing new line after list item list-item-spacing remark-lint', + let l:pattern = '^ \+\(\d\+\):\(\d\+\)\(-\(\d\+\):\(\d\+\)\)\? \(warning\|error\) \(.\+\)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) - call add(l:output, { + let l:item = { \ 'lnum': l:match[1] + 0, \ 'col': l:match[2] + 0, - \ 'type': l:match[3] is# 'error' ? 'E' : 'W', - \ 'text': l:match[4], - \}) + \ 'type': l:match[6] is# 'error' ? 'E' : 'W', + \ 'text': l:match[7], + \} + if l:match[3] isnot# '' + let l:item.end_lnum = l:match[4] + 0 + let l:item.end_col = l:match[5] + 0 + endif + call add(l:output, l:item) endfor return l:output diff --git a/ale_linters/markdown/textlint.vim b/ale_linters/markdown/textlint.vim index 4899fb53..26458506 100644 --- a/ale_linters/markdown/textlint.vim +++ b/ale_linters/markdown/textlint.vim @@ -1,23 +1,9 @@ -" Author: tokida https://rouger.info +" Author: tokida https://rouger.info, Yasuhiro Kiyota <yasuhiroki.duck@gmail.com> " Description: textlint, a proofreading tool (https://textlint.github.io/) -function! ale_linters#markdown#textlint#GetCommand(buffer) abort - let l:cmd_path = ale#path#FindNearestFile(a:buffer, '.textlintrc') - - if !empty(l:cmd_path) - return 'textlint' - \ . ' -c ' - \ . l:cmd_path - \ . ' -f json %t' - endif - - return '' -endfunction - - call ale#linter#Define('markdown', { \ 'name': 'textlint', -\ 'executable': 'textlint', -\ 'command_callback': 'ale_linters#markdown#textlint#GetCommand', +\ 'executable_callback': 'ale#handlers#textlint#GetExecutable', +\ 'command_callback': 'ale#handlers#textlint#GetCommand', \ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', \}) diff --git a/ale_linters/po/msgfmt.vim b/ale_linters/po/msgfmt.vim index 60c25d30..578792bf 100644 --- a/ale_linters/po/msgfmt.vim +++ b/ale_linters/po/msgfmt.vim @@ -5,6 +5,6 @@ call ale#linter#Define('po', { \ 'name': 'msgfmt', \ 'executable': 'msgfmt', \ 'output_stream': 'stderr', -\ 'command': 'msgfmt --statistics %t', +\ 'command': 'msgfmt --statistics --output-file=- %t', \ 'callback': 'ale#handlers#unix#HandleAsWarning', \}) diff --git a/ale_linters/qml/qmllint.vim b/ale_linters/qml/qmllint.vim new file mode 100644 index 00000000..c2258a14 --- /dev/null +++ b/ale_linters/qml/qmllint.vim @@ -0,0 +1,29 @@ +" Author: pylipp (www.github.com/pylipp) +" Description: qmllint for QML files + +" Find lines like +" /home/foo_user42/code-base/qml/Screen.qml:11 : Expected token `}' +function! ale_linters#qml#qmllint#Handle(buffer, lines) abort + let l:pattern = '\v^[/_-a-zA-z0-9\. ]+:(\d+) : (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'col': 0, + \ 'text': l:match[2], + \ 'type': 'E', + \} + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('qml', { +\ 'name': 'qmllint', +\ 'output_stream': 'stderr', +\ 'executable': 'qmllint', +\ 'command': 'qmllint %t', +\ 'callback': 'ale_linters#qml#qmllint#Handle', +\}) diff --git a/ale_linters/text/textlint.vim b/ale_linters/text/textlint.vim new file mode 100644 index 00000000..8fafdd7d --- /dev/null +++ b/ale_linters/text/textlint.vim @@ -0,0 +1,9 @@ +" Author: Yasuhiro Kiyota <yasuhiroki.duck@gmail.com> +" Description: textlint, a proofreading tool (https://textlint.github.io/) + +call ale#linter#Define('text', { +\ 'name': 'textlint', +\ 'executable_callback': 'ale#handlers#textlint#GetExecutable', +\ 'command_callback': 'ale#handlers#textlint#GetCommand', +\ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', +\}) diff --git a/autoload/ale/balloon.vim b/autoload/ale/balloon.vim index 41fa95fa..552ced82 100644 --- a/autoload/ale/balloon.vim +++ b/autoload/ale/balloon.vim @@ -2,6 +2,13 @@ " Description: balloonexpr support for ALE. function! ale#balloon#MessageForPos(bufnr, lnum, col) abort + " Don't show balloons if they are disabled, or linting is disabled. + if !ale#Var(a:bufnr, 'set_balloons') + \|| !g:ale_enabled + \|| !getbufvar(a:bufnr, 'ale_enabled', 1) + return '' + endif + let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col) @@ -13,7 +20,7 @@ function! ale#balloon#Expr() abort endfunction function! ale#balloon#Disable() abort - set noballooneval + set noballooneval balloonexpr= endfunction function! ale#balloon#Enable() abort diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 89169874..dd871c36 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -366,9 +366,6 @@ function! s:RemapItemTypes(type_map, loclist) abort endfor endfunction -" Save the temporary directory so we can figure out if files are in it. -let s:temp_dir = fnamemodify(tempname(), ':h') - function! ale#engine#FixLocList(buffer, linter_name, loclist) abort let l:bufnr_map = {} let l:new_loclist = [] diff --git a/autoload/ale/handlers/go.vim b/autoload/ale/handlers/go.vim new file mode 100644 index 00000000..224df664 --- /dev/null +++ b/autoload/ale/handlers/go.vim @@ -0,0 +1,25 @@ +" Author: neersighted <bjorn@neersighted.com> +" Description: go vet for Go files +" +" Author: John Eikenberry <jae@zhar.net> +" Description: updated to work with go1.10 +" +" Author: Ben Paxton <ben@gn32.uk> +" Description: moved to generic Golang file from govet + +function! ale#handlers#go#Handler(buffer, lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? ?(.+)$' + let l:output = [] + let l:dir = expand('#' . a:buffer . ':p:h') + + 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': l:match[3] + 0, + \ 'text': l:match[4], + \ 'type': 'E', + \}) + endfor + return l:output +endfunction diff --git a/autoload/ale/handlers/markdownlint.vim b/autoload/ale/handlers/markdownlint.vim new file mode 100644 index 00000000..12fc501c --- /dev/null +++ b/autoload/ale/handlers/markdownlint.vim @@ -0,0 +1,17 @@ +" Author: Ty-Lucas Kelley <tylucaskelley@gmail.com> +" Description: Adds support for markdownlint + +function! ale#handlers#markdownlint#Handle(buffer, lines) abort + let l:pattern=': \(\d*\): \(MD\d\{3}\)\(\/\)\([A-Za-z0-9-]\+\)\(.*\)$' + 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[2] . l:match[3] . l:match[4] . ')' . l:match[5], + \ 'type': 'W', + \ }) + endfor + + return l:output +endfunction diff --git a/autoload/ale/handlers/textlint.vim b/autoload/ale/handlers/textlint.vim index 0aae57ef..4e56e127 100644 --- a/autoload/ale/handlers/textlint.vim +++ b/autoload/ale/handlers/textlint.vim @@ -1,5 +1,25 @@ -" Author: tokida https://rouger.info -" Description: Redpen, a proofreading tool (http://redpen.cc) +" Author: tokida https://rouger.info, Yasuhiro Kiyota <yasuhiroki.duck@gmail.com> +" Description: textlint, a proofreading tool (https://textlint.github.io/) + +call ale#Set('textlint_executable', 'textlint') +call ale#Set('textlint_use_global', 0) +call ale#Set('textlint_options', '') + +function! ale#handlers#textlint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'textlint', [ + \ 'node_modules/.bin/textlint', + \ 'node_modules/textlint/bin/textlint.js', + \]) +endfunction + +function! ale#handlers#textlint#GetCommand(buffer) abort + let l:executable = ale#handlers#textlint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'textlint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -f json --stdin --stdin-filename %s' +endfunction function! ale#handlers#textlint#HandleTextlintOutput(buffer, lines) abort let l:res = get(ale#util#FuzzyJSONDecode(a:lines, []), 0, {'messages': []}) diff --git a/autoload/ale/path.vim b/autoload/ale/path.vim index 16dabf21..91832b35 100644 --- a/autoload/ale/path.vim +++ b/autoload/ale/path.vim @@ -84,12 +84,12 @@ function! ale#path#IsAbsolute(filename) abort return a:filename[:0] is# '/' || a:filename[1:2] is# ':\' endfunction -let s:temp_dir = fnamemodify(tempname(), ':h') +let s:temp_dir = ale#path#Simplify(fnamemodify(tempname(), ':h')) " Given a filename, return 1 if the file represents some temporary file " created by Vim. function! ale#path#IsTempName(filename) abort - return a:filename[:len(s:temp_dir) - 1] is# s:temp_dir + return ale#path#Simplify(a:filename)[:len(s:temp_dir) - 1] is# s:temp_dir endfunction " Given a base directory, which must not have a trailing slash, and a diff --git a/autoload/ale/toggle.vim b/autoload/ale/toggle.vim index e9cc29b6..2fa98b4a 100644 --- a/autoload/ale/toggle.vim +++ b/autoload/ale/toggle.vim @@ -84,10 +84,6 @@ function! s:EnablePreamble() abort " Lint immediately, including running linters against the file. call ale#Queue(0, 'lint_file') - - if g:ale_set_balloons - call ale#balloon#Enable() - endif endfunction function! s:DisablePostamble() abort @@ -95,10 +91,6 @@ function! s:DisablePostamble() abort if g:ale_set_highlights call ale#highlight#UpdateHighlights() endif - - if g:ale_set_balloons - call ale#balloon#Disable() - endif endfunction function! s:CleanupEveryBuffer() abort @@ -121,9 +113,17 @@ function! ale#toggle#Toggle() abort if g:ale_enabled call s:EnablePreamble() + + if g:ale_set_balloons + call ale#balloon#Enable() + endif else call s:CleanupEveryBuffer() call s:DisablePostamble() + + if has('balloon_eval') + call ale#balloon#Disable() + endif endif call ale#toggle#InitAuGroups() diff --git a/doc/ale-cs.txt b/doc/ale-cs.txt index 3a02df65..f65b9f39 100644 --- a/doc/ale-cs.txt +++ b/doc/ale-cs.txt @@ -38,8 +38,8 @@ mcsc *ale-cs-mcsc* The paths to search for additional assembly files can be specified using the |g:ale_cs_mcsc_assembly_path| or |b:ale_cs_mcsc_assembly_path| variables. - NOTE: ALE will not any errors in files apart from syntax errors if any one - of the source files contains a syntax error. Syntax errors must be fixed + NOTE: ALE will not find any errors in files apart from syntax errors if any + one of the source files contains a syntax error. Syntax errors must be fixed first before other errors will be shown. diff --git a/doc/ale-markdown.txt b/doc/ale-markdown.txt index 9a5290b7..d7e50093 100644 --- a/doc/ale-markdown.txt +++ b/doc/ale-markdown.txt @@ -28,6 +28,12 @@ See |ale-javascript-prettier| for information about the available options. =============================================================================== +textlint *ale-markdown-textlint* + +See |ale-text-textlint| + + +=============================================================================== write-good *ale-markdown-write-good* See |ale-write-good-options| diff --git a/doc/ale-text.txt b/doc/ale-text.txt index a4dfa5e2..844f2ff4 100644 --- a/doc/ale-text.txt +++ b/doc/ale-text.txt @@ -3,6 +3,36 @@ ALE Text Integration *ale-text-options* =============================================================================== +textlint *ale-text-textlint* + +The options for the textlint linter are global because it does not make +sense to have them specified on a per-language basis. + +g:ale_textlint_executable *g:ale_textlint_executable* + *b:ale_textlint_executable* + Type: |String| + Default: `'textlint'` + + See |ale-integrations-local-executables| + + +g:ale_textlint_options *g:ale_textlint_options* + *b:ale_textlint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to textlint. + + +g:ale_textlint_use_global *g:ale_textlint_use_global* + *b:ale_textlint_use_global* + Type: |Number| + Default: `0` + + See |ale-integrations-local-executables| + + +=============================================================================== write-good *ale-text-write-good* See |ale-write-good-options| diff --git a/doc/ale.txt b/doc/ale.txt index bf93abf2..1c8025a4 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -139,6 +139,7 @@ CONTENTS *ale-contents* markdown..............................|ale-markdown-options| mdl.................................|ale-markdown-mdl| prettier............................|ale-markdown-prettier| + textlint............................|ale-markdown-textlint| write-good..........................|ale-markdown-write-good| nroff.................................|ale-nroff-options| write-good..........................|ale-nroff-write-good| @@ -234,6 +235,7 @@ CONTENTS *ale-contents* texinfo...............................|ale-texinfo-options| write-good..........................|ale-texinfo-write-good| text..................................|ale-text-options| + textlint............................|ale-text-textlint| write-good..........................|ale-text-write-good| thrift................................|ale-thrift-options| thrift..............................|ale-thrift-thrift| @@ -269,7 +271,7 @@ CONTENTS *ale-contents* ALE provides the means to run linters asynchronously in Vim in a variety of languages and tools. ALE sends the contents of buffers to linter programs using the |job-control| features available in Vim 8 and NeoVim. For Vim 8, -Vim must be compiled with the |job| and |channel| and |timer| features +Vim must be compiled with the |job| and |channel| and |timers| features as a minimum. ALE supports the following key features for linting: @@ -346,7 +348,7 @@ Notes: * Lua: `luac`, `luacheck` * Mail: `alex`!!, `proselint`, `vale` * Make: `checkmake` -* Markdown: `alex`!!, `mdl`, `prettier`, `proselint`, `redpen`, `remark-lint`, `vale`, `write-good`, `textlint` +* Markdown: `alex`!!, `markdownlint`!!, `mdl`, `prettier`, `proselint`, `redpen`, `remark-lint`, `textlint`, `vale`, `write-good` * MATLAB: `mlint` * Nim: `nim check`!! * nix: `nix-instantiate` @@ -363,6 +365,7 @@ Notes: * Pug: `pug-lint` * Puppet: `puppet`, `puppet-lint` * Python: `autopep8`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pyls`, `pylint`!!, `yapf` +* QML: `qmllint` * R: `lintr` * ReasonML: `merlin`, `ols`, `refmt` * reStructuredText: `alex`!!, `proselint`, `redpen`, `rstcheck`, `vale`, `write-good` @@ -382,7 +385,7 @@ Notes: * Tcl: `nagelfar`!! * Terraform: `tflint` * Texinfo: `alex`!!, `proselint`, `write-good` -* Text^: `alex`!!, `proselint`, `vale`, `write-good`, `redpen` +* Text^: `alex`!!, `proselint`, `redpen`, `textlint`, `vale`, `write-good` * Thrift: `thrift` * TypeScript: `eslint`, `prettier`, `tslint`, `tsserver`, `typecheck` * Verilog: `iverilog`, `verilator` @@ -1260,7 +1263,7 @@ g:ale_pattern_options *g:ale_pattern_options* let g:ale_pattern_options = { \ '\.foo\.js$': { \ 'ale_linters': ['eslint'], - \ 'ale_fixers: ['eslint'], + \ 'ale_fixers': ['eslint'], \ }, \} < @@ -1288,13 +1291,19 @@ g:ale_pattern_options_enabled *g:ale_pattern_options_enabled* g:ale_set_balloons *g:ale_set_balloons* + *b:ale_set_balloons* Type: |Number| Default: `has('balloon_eval')` When this option is set to `1`, balloon messages will be displayed for problems. Problems nearest to the cursor on the line the cursor is over will - be displayed. + be displayed. Balloons will not be shown when either |g:ale_enabled| is `0` + or |b:ale_enabled| is `0`. + + `b:ale_set_balloons` can be set to `0` to disable balloons for a buffer. + Balloons cannot be enabled for a specific buffer when not initially enabled + globally. g:ale_set_highlights *g:ale_set_highlights* diff --git a/test/command_callback/test_gosimple_command_callback.vader b/test/command_callback/test_gosimple_command_callback.vader new file mode 100644 index 00000000..a0b1f468 --- /dev/null +++ b/test/command_callback/test_gosimple_command_callback.vader @@ -0,0 +1,12 @@ +Before: + runtime ale_linters/go/gosimple.vim + call ale#test#SetFilename('../go_files/testfile2.go') + +After: + call ale#linter#Reset() + +Execute(The default gosimple command should be correct): + AssertEqual 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' + \ . ' gosimple .', + \ ale_linters#go#gosimple#GetCommand(bufnr('')) + diff --git a/test/command_callback/test_gotype_command_callback.vader b/test/command_callback/test_gotype_command_callback.vader index ec98627c..4fba3344 100644 --- a/test/command_callback/test_gotype_command_callback.vader +++ b/test/command_callback/test_gotype_command_callback.vader @@ -6,7 +6,9 @@ After: call ale#linter#Reset() Execute(The default gotype command should be correct): - AssertEqual 'gotype %s', ale_linters#go#gotype#GetCommand(bufnr('')) + AssertEqual 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' + \ . ' gotype .', + \ ale_linters#go#gotype#GetCommand(bufnr('')) Execute(The gotype callback should ignore test files): call ale#test#SetFilename('bla_test.go') diff --git a/test/command_callback/test_textlint_command_callbacks.vader b/test/command_callback/test_textlint_command_callbacks.vader new file mode 100644 index 00000000..212f34d3 --- /dev/null +++ b/test/command_callback/test_textlint_command_callbacks.vader @@ -0,0 +1,85 @@ +" Author: januswel, w0rp + +Before: + Save g:ale_textlint_executable + Save g:ale_textlint_use_global + Save g:ale_textlint_options + + unlet! g:ale_textlint_executable + unlet! b:ale_textlint_executable + unlet! g:ale_textlint_use_global + unlet! b:ale_textlint_use_global + unlet! g:ale_textlint_options + unlet! b:ale_textlint_options + + runtime autoload/ale/handlers/textlint.vim + + call ale#test#SetDirectory('/testplugin/test/command_callback') + +After: + Restore + + unlet! b:command_tail + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The executable should be configurable): + AssertEqual 'textlint', ale#handlers#textlint#GetExecutable(bufnr('')) + + let b:ale_textlint_executable = 'foobar' + + AssertEqual 'foobar', ale#handlers#textlint#GetExecutable(bufnr('')) + +Execute(The executable should be used in the command): + AssertEqual + \ ale#Escape('textlint') . ' -f json --stdin --stdin-filename %s', + \ ale#handlers#textlint#GetCommand(bufnr('')) + + let b:ale_textlint_executable = 'foobar' + + AssertEqual + \ ale#Escape('foobar') . ' -f json --stdin --stdin-filename %s', + \ ale#handlers#textlint#GetCommand(bufnr('')) + \ + +Execute(The options should be configurable): + let b:ale_textlint_options = '--something' + + AssertEqual + \ ale#Escape('textlint') . ' --something -f json --stdin --stdin-filename %s', + \ ale#handlers#textlint#GetCommand(bufnr('')) + +Execute(The local executable from .bin should be used if available): + call ale#test#SetFilename('textlint_paths/with_bin_path/foo.txt') + + AssertEqual + \ ale#path#Simplify(g:dir . '/textlint_paths/with_bin_path/node_modules/.bin/textlint'), + \ ale#handlers#textlint#GetExecutable(bufnr('')) + + AssertEqual + \ ale#Escape(ale#path#Simplify(g:dir . '/textlint_paths/with_bin_path/node_modules/.bin/textlint')) + \ . ' -f json --stdin --stdin-filename %s', + \ ale#handlers#textlint#GetCommand(bufnr('')) + +Execute(The local executable from textlint/bin should be used if available): + call ale#test#SetFilename('textlint_paths/with_textlint_bin_path/foo.txt') + + AssertEqual + \ ale#path#Simplify(g:dir . '/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#handlers#textlint#GetExecutable(bufnr('')) + + if has('win32') + AssertEqual + \ ale#Escape('node.exe') . ' ' . ale#Escape(ale#path#Simplify(g:dir . '/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s', + \ ale#handlers#textlint#GetCommand(bufnr('')) + else + AssertEqual + \ ale#Escape(ale#path#Simplify(g:dir . '/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s', + \ ale#handlers#textlint#GetCommand(bufnr('')) + endif diff --git a/test/command_callback/textlint_paths/with_bin_path/node_modules/.bin/textlint b/test/command_callback/textlint_paths/with_bin_path/node_modules/.bin/textlint new file mode 100755 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/textlint_paths/with_bin_path/node_modules/.bin/textlint diff --git a/test/command_callback/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js b/test/command_callback/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js new file mode 100755 index 00000000..e69de29b --- /dev/null +++ b/test/command_callback/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js diff --git a/test/handler/test_fish_handler.vader b/test/handler/test_fish_handler.vader index 567952e4..ad3a963c 100644 --- a/test/handler/test_fish_handler.vader +++ b/test/handler/test_fish_handler.vader @@ -37,3 +37,25 @@ Execute(The fish handler should handle basic warnings and syntax errors): \ "abbr --add p 'cd ~/Projects'", \ '^', \ ]) + +Execute(The fish handler should handle problems where the problem before before the line with the line number): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 23, + \ 'text': 'Unsupported use of ''||''. In fish, please use ''COMMAND; or COMMAND''.', + \ }, + \ { + \ 'lnum': 5, + \ 'col': 1, + \ 'text': 'wat', + \ }, + \ ], + \ ale_linters#fish#fish#Handle(bufnr(''), [ + \ 'Unsupported use of ''||''. In fish, please use ''COMMAND; or COMMAND''.', + \ '/tmp/vLz620o/258/test.fish (line 2): if set -q SSH_CLIENT || set -q SSH_TTY', + \ ' ^', + \ '/tmp/vLz620o/258/test.fish (line 5): wat', + \ ' ^', + \ ]) diff --git a/test/handler/test_govet_handler.vader b/test/handler/test_go_generic_handler.vader index b4bfdc93..624e56c1 100644 --- a/test/handler/test_govet_handler.vader +++ b/test/handler/test_go_generic_handler.vader @@ -1,10 +1,4 @@ -Before: - runtime ale_linters/go/govet.vim - -After: - call ale#linter#Reset() - -Execute(The govet handler should return the correct filenames): +Execute(The golang handler should return the correct filenames): AssertEqual \ [ \ { @@ -22,7 +16,7 @@ Execute(The govet handler should return the correct filenames): \ 'filename': ale#path#Simplify(expand('%:p:h') . '/other.go'), \ }, \ ], - \ ale_linters#go#govet#Handler(bufnr(''), [ + \ ale#handlers#go#Handler(bufnr(''), [ \ 'test.go:27: some error', \ 'other.go:27:5: some error with a column', \ ]) diff --git a/test/handler/test_markdownlint_handler.vader b/test/handler/test_markdownlint_handler.vader new file mode 100644 index 00000000..db6acc66 --- /dev/null +++ b/test/handler/test_markdownlint_handler.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/markdown/markdownlint.vim + +After: + call ale#linter#Reset() + +Execute(The Markdownlint handler should parse output correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': '(MD002/first-header-h1) First header should be a top level header [Expected: h1; Actual: h2]', + \ 'type': 'W' + \ }, + \ { + \ 'lnum': 298, + \ 'text': '(MD033/no-inline-html) Inline HTML [Element: p]', + \ 'type': 'W' + \ } + \ ], + \ ale#handlers#markdownlint#Handle(0, [ + \ 'README.md: 1: MD002/first-header-h1 First header should be a top level header [Expected: h1; Actual: h2]', + \ 'README.md: 298: MD033/no-inline-html Inline HTML [Element: p]' + \ ]) diff --git a/test/handler/test_qmllint_handler.vader b/test/handler/test_qmllint_handler.vader new file mode 100644 index 00000000..fcc65eb5 --- /dev/null +++ b/test/handler/test_qmllint_handler.vader @@ -0,0 +1,19 @@ +Before: + runtime ale_linters/qml/qmllint.vim + +After: + call ale#linter#Reset() + +Execute(The qmllint handler should parse error messages correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 2, + \ 'col': 0, + \ 'type': 'E', + \ 'text': 'Expected token ''}''' + \ } + \ ], + \ ale_linters#qml#qmllint#Handle(1, [ + \ '/tmp/ab34cd56/Test.qml:2 : Expected token ''}''' + \ ]) diff --git a/test/handler/test_remark_lint_handler.vader b/test/handler/test_remark_lint_handler.vader index f61da199..0794d51c 100644 --- a/test/handler/test_remark_lint_handler.vader +++ b/test/handler/test_remark_lint_handler.vader @@ -19,12 +19,21 @@ Execute(Warning and error messages should be handled correctly): \ 'type': 'E', \ 'text': 'Incorrect list-item indent: remove 1 space list-item-indent remark-lint', \ }, + \ { + \ 'lnum': 18, + \ 'col': 71, + \ 'end_lnum': 19, + \ 'end_col': 1, + \ 'type': 'E', + \ 'text': 'Missing new line after list item list-item-spacing remark-lint', + \ }, \ ], \ ale_linters#markdown#remark_lint#Handle(1, [ \ 'foo.md', \ ' 1:4 warning Incorrect list-item indent: add 1 space list-item-indent remark-lint', \ ' 3:5 error Incorrect list-item indent: remove 1 space list-item-indent remark-lint', + \ ' 18:71-19:1 error Missing new line after list item list-item-spacing remark-lint', \ '', \ '⚠ 1 warnings', - \ '✘ 1 errors', + \ '✘ 2 errors', \]) diff --git a/test/test_ale_toggle.vader b/test/test_ale_toggle.vader index d56f8c2b..ca8b25d5 100644 --- a/test/test_ale_toggle.vader +++ b/test/test_ale_toggle.vader @@ -5,12 +5,14 @@ Before: Save g:ale_run_synchronously Save g:ale_pattern_options Save g:ale_pattern_options_enabled + Save g:ale_set_balloons let g:ale_set_signs = 1 let g:ale_set_lists_synchronously = 1 let g:ale_run_synchronously = 1 let g:ale_pattern_options = {} let g:ale_pattern_options_enabled = 1 + let g:ale_set_balloons = has('balloon_eval') unlet! b:ale_enabled @@ -344,3 +346,41 @@ Execute(ALEResetBuffer should reset everything for a buffer): AssertEqual 1, g:ale_enabled AssertEqual 1, get(b:, 'ale_enabled', 1) + +Execute(Disabling ALE should disable balloons): + " These tests won't run in the console, but we can run them manually in GVim. + if has('balloon_eval') + call ale#linter#Reset() + + " Enable balloons, so we can check the expr value. + call ale#balloon#Enable() + + AssertEqual 1, &ballooneval + AssertEqual 'ale#balloon#Expr()', &balloonexpr + + " Toggle ALE off. + ALEToggle + + " The balloon settings should be reset. + AssertEqual 0, &ballooneval + AssertEqual '', &balloonexpr + endif + +Execute(Enabling ALE should enable balloons if the setting is on): + if has('balloon_eval') + call ale#linter#Reset() + call ale#balloon#Disable() + ALEDisable + let g:ale_set_balloons = 0 + ALEEnable + + AssertEqual 0, &ballooneval + AssertEqual '', &balloonexpr + + ALEDisable + let g:ale_set_balloons = 1 + ALEEnable + + AssertEqual 1, &ballooneval + AssertEqual 'ale#balloon#Expr()', &balloonexpr + endif diff --git a/test/test_balloon_messages.vader b/test/test_balloon_messages.vader index ec09fe29..8f4415ae 100644 --- a/test/test_balloon_messages.vader +++ b/test/test_balloon_messages.vader @@ -1,21 +1,25 @@ Before: Save g:ale_buffer_info + Save g:ale_enabled + Save g:ale_set_balloons - let g:ale_buffer_info[347] = {'loclist': [ + let g:ale_set_balloons = 1 + + let g:ale_buffer_info[bufnr('')] = {'loclist': [ \ { - \ 'bufnr': 347, + \ 'bufnr': bufnr(''), \ 'lnum': 1, \ 'col': 10, \ 'text': 'Missing semicolon. (semi)', \ }, \ { - \ 'bufnr': 347, + \ 'bufnr': bufnr(''), \ 'lnum': 2, \ 'col': 10, \ 'text': 'Infix operators must be spaced. (space-infix-ops)' \ }, \ { - \ 'bufnr': 347, + \ 'bufnr': bufnr(''), \ 'lnum': 2, \ 'col': 15, \ 'text': 'Missing radix parameter (radix)' @@ -25,17 +29,50 @@ Before: After: Restore + unlet! b:ale_enabled + unlet! b:ale_set_balloons + Execute(Balloon messages should be shown for the correct lines): AssertEqual \ 'Missing semicolon. (semi)', - \ ale#balloon#MessageForPos(347, 1, 1) + \ ale#balloon#MessageForPos(bufnr(''), 1, 1) Execute(Balloon messages should be shown for earlier columns): AssertEqual \ 'Infix operators must be spaced. (space-infix-ops)', - \ ale#balloon#MessageForPos(347, 2, 1) + \ ale#balloon#MessageForPos(bufnr(''), 2, 1) Execute(Balloon messages should be shown for later columns): AssertEqual \ 'Missing radix parameter (radix)', - \ ale#balloon#MessageForPos(347, 2, 16) + \ ale#balloon#MessageForPos(bufnr(''), 2, 16) + +Execute(Balloon messages should be disabled if ALE is disabled globally): + let g:ale_enabled = 0 + " Enabling the buffer should not make a difference. + let b:ale_enabled = 1 + + AssertEqual '', ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(Balloon messages should be disabled if ALE is disabled for a buffer): + let b:ale_enabled = 0 + + AssertEqual '', ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(Balloon messages should be disabled if the global setting is off): + let g:ale_set_balloons = 0 + + AssertEqual '', ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(Balloon messages should be disabled if the buffer setting is off): + let b:ale_set_balloons = 0 + + AssertEqual '', ale#balloon#MessageForPos(bufnr(''), 1, 1) + +Execute(The balloon buffer setting should override the global one): + let g:ale_set_balloons = 0 + let b:ale_set_balloons = 1 + + AssertEqual + \ 'Missing semicolon. (semi)', + \ ale#balloon#MessageForPos(bufnr(''), 1, 1) diff --git a/test/test_loclist_corrections.vader b/test/test_loclist_corrections.vader index 6224d608..46c7e272 100644 --- a/test/test_loclist_corrections.vader +++ b/test/test_loclist_corrections.vader @@ -324,7 +324,7 @@ Execute(FixLocList should interpret temporary filenames as being the current buf \ 'foobar', \ [ \ {'text': 'a', 'lnum': 2, 'filename': b:temp_name}, - \ {'text': 'a', 'lnum': 3, 'filename': b:temp_name}, + \ {'text': 'a', 'lnum': 3, 'filename': substitute(b:temp_name, '\\', '/', 'g')}, \ ], \ ) |