summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/report-a-bug.md16
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md3
-rw-r--r--README.md18
-rw-r--r--ale_linters/ansible/ansible_lint.vim13
-rw-r--r--ale_linters/d/dls.vim22
-rw-r--r--ale_linters/d/dmd.vim16
-rw-r--r--ale_linters/elixir/credo.vim23
-rw-r--r--ale_linters/elixir/dialyxir.vim9
-rw-r--r--ale_linters/elixir/dogma.vim9
-rw-r--r--ale_linters/elixir/elixir_ls.vim19
-rw-r--r--ale_linters/elixir/mix.vim16
-rw-r--r--ale_linters/haskell/hlint.vim3
-rw-r--r--ale_linters/haskell/stack_build.vim2
-rw-r--r--ale_linters/haskell/stack_ghc.vim2
-rw-r--r--ale_linters/java/pmd.vim2
-rw-r--r--ale_linters/php/psalm.vim31
-rw-r--r--ale_linters/ruby/solargraph.vim2
-rw-r--r--ale_linters/rust/cargo.vim13
-rw-r--r--autoload/ale/cursor.vim15
-rw-r--r--autoload/ale/d.vim16
-rw-r--r--autoload/ale/fix/registry.vim5
-rw-r--r--autoload/ale/fixers/google_java_format.vim10
-rw-r--r--autoload/ale/fixers/jq.vim9
-rw-r--r--autoload/ale/fixers/terraform.vim17
-rw-r--r--autoload/ale/handlers/elixir.vim13
-rw-r--r--autoload/ale/handlers/haskell.vim10
-rw-r--r--autoload/ale/linter.vim8
-rw-r--r--autoload/ale/lsp/message.vim6
-rw-r--r--autoload/ale/lsp_linter.vim6
-rw-r--r--autoload/ale/path.vim6
-rw-r--r--doc/ale-ansible.txt16
-rw-r--r--doc/ale-d.txt11
-rw-r--r--doc/ale-elixir.txt13
-rw-r--r--doc/ale-hcl.txt11
-rw-r--r--doc/ale-json.txt7
-rw-r--r--doc/ale-rust.txt31
-rw-r--r--doc/ale-terraform.txt18
-rw-r--r--doc/ale.txt41
-rw-r--r--run-tests.bat4
-rw-r--r--test/command_callback/elixir_paths/mix_project/lib/foo.ex0
-rw-r--r--test/command_callback/elixir_paths/mix_project/mix.exs3
-rwxr-xr-xtest/command_callback/psalm-project/vendor/bin/psalm-language-server0
-rw-r--r--test/command_callback/stack_build_paths/stack.yaml0
-rw-r--r--test/command_callback/stack_ghc_paths/stack.yaml0
-rw-r--r--test/command_callback/test_ansible_lint_command_callback.vader17
-rw-r--r--test/command_callback/test_c_cppcheck_command_callbacks.vader2
-rw-r--r--test/command_callback/test_cargo_command_callbacks.vader24
-rw-r--r--test/command_callback/test_cpp_cppcheck_command_callbacks.vader2
-rw-r--r--test/command_callback/test_cs_mcsc_command_callbacks.vader14
-rw-r--r--test/command_callback/test_d_dls_callbacks.vader19
-rw-r--r--test/command_callback/test_elixir_ls_command_callbacks.vader29
-rw-r--r--test/command_callback/test_elixir_mix_command_callbacks.vader7
-rw-r--r--test/command_callback/test_gobuild_command_callback.vader6
-rw-r--r--test/command_callback/test_golangci_lint_command_callback.vader8
-rw-r--r--test/command_callback/test_gometalinter_command_callback.vader8
-rw-r--r--test/command_callback/test_gosimple_command_callback.vader2
-rw-r--r--test/command_callback/test_gotype_command_callback.vader2
-rw-r--r--test/command_callback/test_govet_command_callback.vader6
-rw-r--r--test/command_callback/test_haskell_hlint_command_callbacks.vader3
-rw-r--r--test/command_callback/test_haskell_stack_build_command_callback.vader13
-rw-r--r--test/command_callback/test_haskell_stack_ghc_command_callback.vader14
-rw-r--r--test/command_callback/test_javac_command_callback.vader12
-rw-r--r--test/command_callback/test_lintr_command_callback.vader6
-rw-r--r--test/command_callback/test_mypy_command_callback.vader18
-rw-r--r--test/command_callback/test_psalm_command_callbacks.vader25
-rw-r--r--test/command_callback/test_ruby_solargraph.vader5
-rw-r--r--test/command_callback/test_sasslint_command_callback.vader2
-rw-r--r--test/command_callback/test_shellcheck_command_callback.vader2
-rw-r--r--test/command_callback/test_staticcheck_command_callback.vader6
-rw-r--r--test/command_callback/test_tslint_command_callback.vader6
-rw-r--r--test/fixers/test_goofle_java_format_fixer_callback.vader8
-rw-r--r--test/fixers/test_isort_fixer_callback.vader4
-rw-r--r--test/fixers/test_jq_fixer_callback.vader14
-rw-r--r--test/fixers/test_prettier_eslint_fixer.callback.vader4
-rw-r--r--test/fixers/test_prettier_fixer_callback.vader26
-rw-r--r--test/fixers/test_terraform_fmt_fixer_callback.vader34
-rw-r--r--test/handler/test_credo_handler.vader26
-rw-r--r--test/handler/test_php_psalm_handler.vader24
-rw-r--r--test/handler/test_pmd_handler.vader15
-rw-r--r--test/lsp/test_lsp_client_messages.vader16
-rw-r--r--test/test_gradle_build_classpath_command.vader8
-rw-r--r--test/test_linter_defintion_processing.vader31
-rw-r--r--test/util/test_cd_string_commands.vader6
83 files changed, 767 insertions, 202 deletions
diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md
index cf335c11..e617893f 100644
--- a/.github/ISSUE_TEMPLATE/report-a-bug.md
+++ b/.github/ISSUE_TEMPLATE/report-a-bug.md
@@ -23,14 +23,12 @@ about: Report a bug with ALE.
Operating System: <!-- Describe your operating system version. -->
-### :ALEInfo
-
-<!-- Paste the output of :ALEInfo here. Try :ALEInfoToClipboard -->
-<!-- Make sure to run :ALEInfo from the buffer where the bug occurred. -->
-
## What went wrong
-<!-- Describe what went wrong here. -->
+<!-- Describe what went wrong here. Be specific. -->
+
+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.
## Reproducing the bug
@@ -38,3 +36,9 @@ Operating System: <!-- Describe your operating system version. -->
1. I did this.
2. Then this happened.
+
+### :ALEInfo
+
+<!-- Paste the output of :ALEInfo here. Try :ALEInfoToClipboard -->
+<!-- Make sure to run :ALEInfo from the buffer where the bug occurred. -->
+<!-- Read the output. You might figure out what went wrong yourself. -->
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 8e1b5c57..31f55453 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -6,3 +6,6 @@ Before creating a pull request, do the following.
Have fun!
-->
+
+Where are the tests? Have you added tests? Have you updated the tests? Read the
+comment above and the documentation referenced in it first. Write tests!
diff --git a/README.md b/README.md
index 61220c45..ffd827fa 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ features, including:
* Diagnostics (via Language Server Protocol linters)
* Go To Definition (`:ALEGoToDefinition`)
-* Completion (`let g:ale_completion_enabled = 1`)
+* Completion (`let g:ale_completion_enabled = 1` before ALE is loaded)
* Finding references (`:ALEFindReferences`)
* Hover information (`:ALEHover`)
@@ -34,6 +34,9 @@ If you don't care about Language Server Protocol, ALE won't load any of the code
for working with it unless needed. One of ALE's general missions is that you
won't pay for the features that you don't use.
+If you enjoy this plugin, feel free to contribute or check out the author's
+other content at [w0rp.com](https://w0rp.com).
+
## Table of Contents
1. [Supported Languages and Tools](#supported-languages)
@@ -110,11 +113,11 @@ formatting.
| CSS | [csslint](http://csslint.net/), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) |
| Cucumber | [cucumber](https://cucumber.io/) |
| Cython (pyrex filetype) | [cython](http://cython.org/) |
-| D | [dmd](https://dlang.org/dmd-linux.html), [uncrustify](https://github.com/uncrustify/uncrustify) |
+| D | [dls](https://github.com/d-language-server/dls), [dmd](https://dlang.org/dmd-linux.html), [uncrustify](https://github.com/uncrustify/uncrustify) |
| Dafny | [dafny](https://rise4fun.com/Dafny) !! |
| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) |
| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) |
-| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!|
+| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!, [elixir-ls](https://github.com/JakeBecker/elixir-ls) |
| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) |
| Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) |
| Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) |
@@ -130,6 +133,7 @@ formatting.
| Haml | [haml-lint](https://github.com/brigade/haml-lint) |
| Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) |
| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [cabal-ghc](https://www.haskell.org/cabal/), [stylish-haskell](https://github.com/jaspervdj/stylish-haskell), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt), [hie](https://github.com/haskell/haskell-ide-engine) |
+| HCL | [terraform-fmt](https://github.com/hashicorp/terraform) |
| HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) |
| Idris | [idris](http://www.idris-lang.org/) |
| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/), [javalsp](https://github.com/georgewfraser/vscode-javac), [uncrustify](https://github.com/uncrustify/uncrustify) |
@@ -182,7 +186,7 @@ formatting.
| SQL | [sqlint](https://github.com/purcell/sqlint), [sqlfmt](https://github.com/jackc/sqlfmt) |
| Swift | [swiftlint](https://github.com/realm/SwiftLint), [swiftformat](https://github.com/nicklockwood/SwiftFormat) |
| Tcl | [nagelfar](http://nagelfar.sourceforge.net) !! |
-| Terraform | [tflint](https://github.com/wata727/tflint) |
+| Terraform | [fmt](https://github.com/hashicorp/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/), [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/) |
@@ -275,6 +279,7 @@ Protocol linters, or from `tsserver` for TypeScript.
```vim
" Enable completion where available.
+" This setting must be set before ALE is loaded.
let g:ale_completion_enabled = 1
```
@@ -308,8 +313,9 @@ ALE supports "hover" information for printing brief information about symbols at
the cursor taken from Language Server Protocol linters and `tsserver` with the
`ALEHover` command.
-On vim/gvim with `balloon` support you can see the information in a tooltip
-that appears under the mouse when you mouseover a symbol.
+The information can be displayed in a `balloon` tooltip in Vim or GVim by
+hovering your mouse over symbols. Mouse hovering is enabled by default in GVim,
+and needs to be configured for Vim 8.1+ in terminals.
See `:help ale-hover` for more information.
diff --git a/ale_linters/ansible/ansible_lint.vim b/ale_linters/ansible/ansible_lint.vim
index 0b3b39c8..99fff6c3 100644
--- a/ale_linters/ansible/ansible_lint.vim
+++ b/ale_linters/ansible/ansible_lint.vim
@@ -1,6 +1,12 @@
" Author: Bjorn Neergaard <bjorn@neersighted.com>
" Description: ansible-lint for ansible-yaml files
+call ale#Set('ansible_ansible_lint_executable', 'ansible-lint')
+
+function! ale_linters#ansible#ansible_lint#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'ansible_ansible_lint_executable')
+endfunction
+
function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort
for l:line in a:lines[:10]
if match(l:line, '^Traceback') >= 0
@@ -42,8 +48,9 @@ function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort
endfunction
call ale#linter#Define('ansible', {
-\ 'name': 'ansible',
-\ 'executable': 'ansible',
-\ 'command': 'ansible-lint -p %t',
+\ 'name': 'ansible_lint',
+\ 'aliases': ['ansible', 'ansible-lint'],
+\ 'executable_callback': 'ale_linters#ansible#ansible_lint#GetExecutable',
+\ 'command': '%e -p %t',
\ 'callback': 'ale_linters#ansible#ansible_lint#Handle',
\})
diff --git a/ale_linters/d/dls.vim b/ale_linters/d/dls.vim
new file mode 100644
index 00000000..7210d21e
--- /dev/null
+++ b/ale_linters/d/dls.vim
@@ -0,0 +1,22 @@
+" Author: aurieh <me@aurieh.me>
+" Description: A Language Server implementation for D
+
+call ale#Set('d_dls_executable', 'dls')
+
+function! ale_linters#d#dls#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'd_dls_executable')
+endfunction
+
+function! ale_linters#d#dls#FindProjectRoot(buffer) abort
+ " Note: this will return . if dub config is empty
+ " dls can run outside DUB projects just fine
+ return fnamemodify(ale#d#FindDUBConfig(a:buffer), ':h')
+endfunction
+
+call ale#linter#Define('d', {
+\ 'name': 'dls',
+\ 'lsp': 'stdio',
+\ 'executable_callback': 'ale_linters#d#dls#GetExecutable',
+\ 'command_callback': 'ale_linters#d#dls#GetExecutable',
+\ 'project_root_callback': 'ale_linters#d#dls#FindProjectRoot',
+\})
diff --git a/ale_linters/d/dmd.vim b/ale_linters/d/dmd.vim
index d64b6c3d..c816d592 100644
--- a/ale_linters/d/dmd.vim
+++ b/ale_linters/d/dmd.vim
@@ -1,20 +1,6 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: "dmd for D files"
-function! s:FindDUBConfig(buffer) abort
- " Find a DUB configuration file in ancestor paths.
- " The most DUB-specific names will be tried first.
- for l:possible_filename in ['dub.sdl', 'dub.json', 'package.json']
- let l:dub_file = ale#path#FindNearestFile(a:buffer, l:possible_filename)
-
- if !empty(l:dub_file)
- return l:dub_file
- endif
- endfor
-
- return ''
-endfunction
-
function! ale_linters#d#dmd#DUBCommand(buffer) abort
" If we can't run dub, then skip this command.
if !executable('dub')
@@ -22,7 +8,7 @@ function! ale_linters#d#dmd#DUBCommand(buffer) abort
return ''
endif
- let l:dub_file = s:FindDUBConfig(a:buffer)
+ let l:dub_file = ale#d#FindDUBConfig(a:buffer)
if empty(l:dub_file)
return ''
diff --git a/ale_linters/elixir/credo.vim b/ale_linters/elixir/credo.vim
index af2ff48a..d778471c 100644
--- a/ale_linters/elixir/credo.vim
+++ b/ale_linters/elixir/credo.vim
@@ -11,10 +11,18 @@ function! ale_linters#elixir#credo#Handle(buffer, lines) abort
let l:type = l:match[3]
let l:text = l:match[4]
- if l:type is# 'C'
- let l:type = 'E'
- elseif l:type is# 'R'
+ " Refactoring opportunities
+ if l:type is# 'F'
+ let l:type = 'W'
+ " Consistency
+ elseif l:type is# 'C'
let l:type = 'W'
+ " Software Design
+ elseif l:type is# 'D'
+ let l:type = 'I'
+ " Code Readability
+ elseif l:type is# 'R'
+ let l:type = 'I'
endif
call add(l:output, {
@@ -29,9 +37,16 @@ function! ale_linters#elixir#credo#Handle(buffer, lines) abort
return l:output
endfunction
+function! ale_linters#elixir#credo#GetCommand(buffer) abort
+ let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
+
+ return ale#path#CdString(l:project_root)
+ \ . ' mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
+endfunction
+
call ale#linter#Define('elixir', {
\ 'name': 'credo',
\ 'executable': 'mix',
-\ 'command': 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s',
+\ 'command_callback': 'ale_linters#elixir#credo#GetCommand',
\ 'callback': 'ale_linters#elixir#credo#Handle',
\})
diff --git a/ale_linters/elixir/dialyxir.vim b/ale_linters/elixir/dialyxir.vim
index bba0ae14..d28d3c70 100644
--- a/ale_linters/elixir/dialyxir.vim
+++ b/ale_linters/elixir/dialyxir.vim
@@ -25,10 +25,17 @@ function! ale_linters#elixir#dialyxir#Handle(buffer, lines) abort
return l:output
endfunction
+function! ale_linters#elixir#dialyxir#GetCommand(buffer) abort
+ let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
+
+ return ale#path#CdString(l:project_root)
+ \ . ' mix help dialyzer && mix dialyzer'
+endfunction
+
call ale#linter#Define('elixir', {
\ 'name': 'dialyxir',
\ 'executable': 'mix',
-\ 'command': 'mix help dialyzer && mix dialyzer',
+\ 'command_callback': 'ale_linters#elixir#dialyxir#GetCommand',
\ 'callback': 'ale_linters#elixir#dialyxir#Handle',
\})
diff --git a/ale_linters/elixir/dogma.vim b/ale_linters/elixir/dogma.vim
index 71cf4f4c..dcfb6f28 100644
--- a/ale_linters/elixir/dogma.vim
+++ b/ale_linters/elixir/dogma.vim
@@ -29,10 +29,17 @@ function! ale_linters#elixir#dogma#Handle(buffer, lines) abort
return l:output
endfunction
+function! ale_linters#elixir#dogma#GetCommand(buffer) abort
+ let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
+
+ return ale#path#CdString(l:project_root)
+ \ . ' mix help dogma && mix dogma %s --format=flycheck'
+endfunction
+
call ale#linter#Define('elixir', {
\ 'name': 'dogma',
\ 'executable': 'mix',
-\ 'command': 'mix help dogma && mix dogma %s --format=flycheck',
+\ 'command_callback': 'ale_linters#elixir#dogma#GetCommand',
\ 'lint_file': 1,
\ 'callback': 'ale_linters#elixir#dogma#Handle',
\})
diff --git a/ale_linters/elixir/elixir_ls.vim b/ale_linters/elixir/elixir_ls.vim
new file mode 100644
index 00000000..d5ad7cfc
--- /dev/null
+++ b/ale_linters/elixir/elixir_ls.vim
@@ -0,0 +1,19 @@
+" Author: Jon Parise <jon@indelible.org>
+" Description: elixir-ls integration (https://github.com/JakeBecker/elixir-ls)
+
+call ale#Set('elixir_elixir_ls_release', 'elixir-ls')
+
+function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort
+ let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_elixir_ls_release'))
+ let l:cmd = ale#Has('win32') ? '\language_server.bat' : '/language_server.sh'
+
+ return l:dir . l:cmd
+endfunction
+
+call ale#linter#Define('elixir', {
+\ 'name': 'elixir-ls',
+\ 'lsp': 'stdio',
+\ 'executable_callback': 'ale_linters#elixir#elixir_ls#GetExecutable',
+\ 'command_callback': 'ale_linters#elixir#elixir_ls#GetExecutable',
+\ 'project_root_callback': 'ale#handlers#elixir#FindMixProjectRoot',
+\})
diff --git a/ale_linters/elixir/mix.vim b/ale_linters/elixir/mix.vim
index 4552ace5..dc3c1818 100644
--- a/ale_linters/elixir/mix.vim
+++ b/ale_linters/elixir/mix.vim
@@ -29,18 +29,8 @@ function! ale_linters#elixir#mix#Handle(buffer, lines) abort
return l:output
endfunction
-function! ale_linters#elixir#mix#FindProjectRoot(buffer) abort
- let l:mix_file = ale#path#FindNearestFile(a:buffer, 'mix.exs')
-
- if !empty(l:mix_file)
- return fnamemodify(l:mix_file, ':p:h')
- endif
-
- return '.'
-endfunction
-
function! ale_linters#elixir#mix#GetCommand(buffer) abort
- let l:project_root = ale_linters#elixir#mix#FindProjectRoot(a:buffer)
+ let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
let l:temp_dir = ale#engine#CreateDirectory(a:buffer)
@@ -49,8 +39,8 @@ function! ale_linters#elixir#mix#GetCommand(buffer) abort
\ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir)
return ale#path#CdString(l:project_root)
- \ . l:mix_build_path
- \ . ' mix compile %s'
+ \ . l:mix_build_path
+ \ . ' mix compile %s'
endfunction
call ale#linter#Define('elixir', {
diff --git a/ale_linters/haskell/hlint.vim b/ale_linters/haskell/hlint.vim
index fbb49fdb..0cc7437f 100644
--- a/ale_linters/haskell/hlint.vim
+++ b/ale_linters/haskell/hlint.vim
@@ -1,6 +1,9 @@
" Author: jparoz <jesse.paroz@gmail.com>
" Description: hlint for Haskell files
+call ale#Set('haskell_hlint_executable', 'hlint')
+call ale#Set('haskell_hlint_options', get(g:, 'hlint_options', ''))
+
function! ale_linters#haskell#hlint#Handle(buffer, lines) abort
let l:output = []
diff --git a/ale_linters/haskell/stack_build.vim b/ale_linters/haskell/stack_build.vim
index f5bdf4b8..95a54587 100644
--- a/ale_linters/haskell/stack_build.vim
+++ b/ale_linters/haskell/stack_build.vim
@@ -16,7 +16,7 @@ call ale#linter#Define('haskell', {
\ 'name': 'stack_build',
\ 'aliases': ['stack-build'],
\ 'output_stream': 'stderr',
-\ 'executable': 'stack',
+\ 'executable_callback': 'ale#handlers#haskell#GetStackExecutable',
\ 'command_callback': 'ale_linters#haskell#stack_build#GetCommand',
\ 'lint_file': 1,
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
diff --git a/ale_linters/haskell/stack_ghc.vim b/ale_linters/haskell/stack_ghc.vim
index d702aa68..8f42b96c 100644
--- a/ale_linters/haskell/stack_ghc.vim
+++ b/ale_linters/haskell/stack_ghc.vim
@@ -5,7 +5,7 @@ call ale#linter#Define('haskell', {
\ 'name': 'stack_ghc',
\ 'aliases': ['stack-ghc'],
\ 'output_stream': 'stderr',
-\ 'executable': 'stack',
+\ 'executable_callback': 'ale#handlers#haskell#GetStackExecutable',
\ 'command': 'stack ghc -- -fno-code -v0 %t',
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\})
diff --git a/ale_linters/java/pmd.vim b/ale_linters/java/pmd.vim
index d461e094..b530ad09 100644
--- a/ale_linters/java/pmd.vim
+++ b/ale_linters/java/pmd.vim
@@ -2,7 +2,7 @@
" Description: PMD for Java files
function! ale_linters#java#pmd#Handle(buffer, lines) abort
- let l:pattern = '"\(\d\+\)",".\+","\(.\+\)","\(\d\+\)","\(\d\+\)","\(.\+\)","\(.\+\)","\(.\+\)"$'
+ let l:pattern = '"\(\d\+\)",".*","\(.\+\)","\(\d\+\)","\(\d\+\)","\(.\+\)","\(.\+\)","\(.\+\)"$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
diff --git a/ale_linters/php/psalm.vim b/ale_linters/php/psalm.vim
index cd20ab81..dce59178 100644
--- a/ale_linters/php/psalm.vim
+++ b/ale_linters/php/psalm.vim
@@ -1,28 +1,21 @@
-" Author: richard marmorstein <https://github.com/twitchard>
+" Author: Matt Brown <https://github.com/muglug>
" Description: plugin for Psalm, static analyzer for PHP
-call ale#Set('php_psalm_executable', 'psalm')
+call ale#Set('psalm_langserver_executable', 'psalm-language-server')
+call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0))
-function! ale_linters#php#psalm#Handle(buffer, lines) abort
- " Matches patterns like the following:
- let l:pattern = '^.*:\(\d\+\):\(\d\+\):\(\w\+\) - \(.*\)$'
- let l:output = []
+function! ale_linters#php#psalm#GetProjectRoot(buffer) abort
+ let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
- for l:match in ale#util#GetMatches(a:lines, l:pattern)
- call add(l:output, {
- \ 'lnum': l:match[1] + 0,
- \ 'text': l:match[4],
- \ 'type': l:match[3][:0] is# 'e' ? 'E' : 'W',
- \})
- endfor
-
- return l:output
+ return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
endfunction
call ale#linter#Define('php', {
\ 'name': 'psalm',
-\ 'command': '%e --diff --output-format=emacs %s',
-\ 'executable_callback': ale#VarFunc('php_psalm_executable'),
-\ 'callback': 'ale_linters#php#psalm#Handle',
-\ 'lint_file': 1,
+\ 'lsp': 'stdio',
+\ 'executable_callback': ale#node#FindExecutableFunc('psalm_langserver', [
+\ 'vendor/bin/psalm-language-server',
+\ ]),
+\ 'command': '%e',
+\ 'project_root_callback': 'ale_linters#php#psalm#GetProjectRoot',
\})
diff --git a/ale_linters/ruby/solargraph.vim b/ale_linters/ruby/solargraph.vim
index 7ca0399f..5ff0a759 100644
--- a/ale_linters/ruby/solargraph.vim
+++ b/ale_linters/ruby/solargraph.vim
@@ -5,6 +5,7 @@
" Description: updated to use stdio
call ale#Set('ruby_solargraph_executable', 'solargraph')
+call ale#Set('ruby_solargraph_options', {})
function! ale_linters#ruby#solargraph#GetCommand(buffer) abort
return '%e' . ale#Pad('stdio')
@@ -17,4 +18,5 @@ call ale#linter#Define('ruby', {
\ 'executable_callback': ale#VarFunc('ruby_solargraph_executable'),
\ 'command_callback': 'ale_linters#ruby#solargraph#GetCommand',
\ 'project_root_callback': 'ale#ruby#FindProjectRoot',
+\ 'initialization_options_callback': ale#VarFunc('ruby_solargraph_options'),
\})
diff --git a/ale_linters/rust/cargo.vim b/ale_linters/rust/cargo.vim
index 5aefe72c..cf6187f8 100644
--- a/ale_linters/rust/cargo.vim
+++ b/ale_linters/rust/cargo.vim
@@ -9,6 +9,8 @@ call ale#Set('rust_cargo_check_tests', 0)
call ale#Set('rust_cargo_avoid_whole_workspace', 1)
call ale#Set('rust_cargo_default_feature_behavior', 'default')
call ale#Set('rust_cargo_include_features', '')
+call ale#Set('rust_cargo_use_clippy', 0)
+call ale#Set('rust_cargo_clippy_options', '')
function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
if ale#path#FindNearestFile(a:bufnr, 'Cargo.toml') isnot# ''
@@ -70,14 +72,23 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
let l:default_feature = ''
endif
+ let l:subcommand = l:use_check ? 'check' : 'build'
+ let l:clippy_options = ''
+
+ if ale#Var(a:buffer, 'rust_cargo_use_clippy')
+ let l:subcommand = 'clippy'
+ let l:clippy_options = ' ' . ale#Var(a:buffer, 'rust_cargo_clippy_options')
+ endif
+
return l:nearest_cargo_prefix . 'cargo '
- \ . (l:use_check ? 'check' : 'build')
+ \ . l:subcommand
\ . (l:use_all_targets ? ' --all-targets' : '')
\ . (l:use_examples ? ' --examples' : '')
\ . (l:use_tests ? ' --tests' : '')
\ . ' --frozen --message-format=json -q'
\ . l:default_feature
\ . l:include_features
+ \ . l:clippy_options
endfunction
call ale#linter#Define('rust', {
diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim
index c3b48ca3..32ce8c84 100644
--- a/autoload/ale/cursor.vim
+++ b/autoload/ale/cursor.vim
@@ -26,7 +26,20 @@ function! ale#cursor#TruncatedEcho(original_message) abort
" The message is truncated and saved to the history.
setlocal shortmess+=T
- exec "norm! :echomsg l:message\n"
+
+ try
+ exec "norm! :echomsg l:message\n"
+ catch /^Vim\%((\a\+)\)\=:E523/
+ " Fallback into manual truncate (#1987)
+ let l:winwidth = winwidth(0)
+
+ if l:winwidth < strdisplaywidth(l:message)
+ " Truncate message longer than window width with trailing '...'
+ let l:message = l:message[:l:winwidth - 4] . '...'
+ endif
+
+ exec 'echomsg l:message'
+ endtry
" Reset the cursor position if we moved off the end of the line.
" Using :norm and :echomsg can move the cursor off the end of the
diff --git a/autoload/ale/d.vim b/autoload/ale/d.vim
new file mode 100644
index 00000000..0e232203
--- /dev/null
+++ b/autoload/ale/d.vim
@@ -0,0 +1,16 @@
+" Author: Auri <me@aurieh.me>
+" Description: Functions for integrating with D linters.
+
+function! ale#d#FindDUBConfig(buffer) abort
+ " Find a DUB configuration file in ancestor paths.
+ " The most DUB-specific names will be tried first.
+ for l:possible_filename in ['dub.sdl', 'dub.json', 'package.json']
+ let l:dub_file = ale#path#FindNearestFile(a:buffer, l:possible_filename)
+
+ if !empty(l:dub_file)
+ return l:dub_file
+ endif
+ endfor
+
+ return ''
+endfunction
diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim
index 76cce87f..98f52232 100644
--- a/autoload/ale/fix/registry.vim
+++ b/autoload/ale/fix/registry.vim
@@ -250,6 +250,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['c', 'cpp', 'cs', 'objc', 'objcpp', 'd', 'java', 'p', 'vala' ],
\ 'description': 'Fix C, C++, C#, ObjectiveC, ObjectiveC++, D, Java, Pawn, and VALA files with uncrustify.',
\ },
+\ 'terraform': {
+\ 'function': 'ale#fixers#terraform#Fix',
+\ 'suggested_filetypes': ['hcl', 'terraform'],
+\ 'description': 'Fix tf and hcl files with terraform fmt.',
+\ },
\}
" Reset the function registry to the default entries.
diff --git a/autoload/ale/fixers/google_java_format.vim b/autoload/ale/fixers/google_java_format.vim
index 6a2f5491..20086c73 100644
--- a/autoload/ale/fixers/google_java_format.vim
+++ b/autoload/ale/fixers/google_java_format.vim
@@ -1,13 +1,13 @@
" Author: butlerx <butlerx@notthe,cloud>
" Description: Integration of Google-java-format with ALE.
-call ale#Set('google_java_format_executable', 'google-java-format')
-call ale#Set('google_java_format_use_global', get(g:, 'ale_use_global_executables', 0))
-call ale#Set('google_java_format_options', '')
+call ale#Set('java_google_java_format_executable', 'google-java-format')
+call ale#Set('java_google_java_format_use_global', get(g:, 'ale_use_global_executables', 0))
+call ale#Set('java_google_java_format_options', '')
function! ale#fixers#google_java_format#Fix(buffer) abort
- let l:options = ale#Var(a:buffer, 'google_java_format_options')
- let l:executable = ale#Var(a:buffer, 'google_java_format_executable')
+ let l:options = ale#Var(a:buffer, 'java_google_java_format_options')
+ let l:executable = ale#Var(a:buffer, 'java_google_java_format_executable')
if !executable(l:executable)
return 0
diff --git a/autoload/ale/fixers/jq.vim b/autoload/ale/fixers/jq.vim
index b0a43fe2..1b743e49 100644
--- a/autoload/ale/fixers/jq.vim
+++ b/autoload/ale/fixers/jq.vim
@@ -1,5 +1,6 @@
call ale#Set('json_jq_executable', 'jq')
call ale#Set('json_jq_options', '')
+call ale#Set('json_jq_filters', '.')
function! ale#fixers#jq#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'json_jq_executable')
@@ -7,9 +8,15 @@ endfunction
function! ale#fixers#jq#Fix(buffer) abort
let l:options = ale#Var(a:buffer, 'json_jq_options')
+ let l:filters = ale#Var(a:buffer, 'json_jq_filters')
+
+ if empty(l:filters)
+ return 0
+ endif
return {
\ 'command': ale#Escape(ale#fixers#jq#GetExecutable(a:buffer))
- \ . ' . ' . l:options,
+ \ . ' ' . l:filters . ' '
+ \ . l:options,
\}
endfunction
diff --git a/autoload/ale/fixers/terraform.vim b/autoload/ale/fixers/terraform.vim
new file mode 100644
index 00000000..bc05380a
--- /dev/null
+++ b/autoload/ale/fixers/terraform.vim
@@ -0,0 +1,17 @@
+" Author: dsifford <dereksifford@gmail.com>
+" Description: Fixer for terraform and .hcl files
+
+call ale#Set('terraform_fmt_executable', 'terraform')
+call ale#Set('terraform_fmt_options', '')
+
+function! ale#fixers#terraform#Fix(buffer) abort
+ let l:executable = ale#Var(a:buffer, 'terraform_fmt_executable')
+ let l:options = ale#Var(a:buffer, 'terraform_fmt_options')
+
+ return {
+ \ 'command': ale#Escape(l:executable)
+ \ . ' fmt'
+ \ . (empty(l:options) ? '' : ' ' . l:options)
+ \ . ' -'
+ \}
+endfunction
diff --git a/autoload/ale/handlers/elixir.vim b/autoload/ale/handlers/elixir.vim
new file mode 100644
index 00000000..91b75aac
--- /dev/null
+++ b/autoload/ale/handlers/elixir.vim
@@ -0,0 +1,13 @@
+" Author: Matteo Centenaro (bugant) - https://github.com/bugant
+"
+" Description: find the root directory for an elixir project that uses mix
+
+function! ale#handlers#elixir#FindMixProjectRoot(buffer) abort
+ let l:mix_file = ale#path#FindNearestFile(a:buffer, 'mix.exs')
+
+ if !empty(l:mix_file)
+ return fnamemodify(l:mix_file, ':p:h')
+ endif
+
+ return '.'
+endfunction
diff --git a/autoload/ale/handlers/haskell.vim b/autoload/ale/handlers/haskell.vim
index 9223b650..9e495b36 100644
--- a/autoload/ale/handlers/haskell.vim
+++ b/autoload/ale/handlers/haskell.vim
@@ -1,5 +1,15 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Error handling for the format GHC outputs.
+"
+function! ale#handlers#haskell#GetStackExecutable(bufnr) abort
+ if ale#path#FindNearestFile(a:bufnr, 'stack.yaml') isnot# ''
+ return 'stack'
+ endif
+
+ " if there is no stack.yaml file, we don't use stack even if it exists,
+ " so we return '', because executable('') apparently always fails
+ return ''
+endfunction
" Remember the directory used for temporary files for Vim.
let s:temp_dir = fnamemodify(ale#util#Tempname(), ':h')
diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim
index 6c61e3db..7c1dc53e 100644
--- a/autoload/ale/linter.vim
+++ b/autoload/ale/linter.vim
@@ -256,6 +256,14 @@ function! ale#linter#PreProcess(filetype, linter) abort
elseif has_key(a:linter, 'initialization_options')
let l:obj.initialization_options = a:linter.initialization_options
endif
+
+ if has_key(a:linter, 'lsp_config')
+ if type(a:linter.lsp_config) isnot v:t_dict
+ throw '`lsp_config` must be a Dictionary'
+ endif
+
+ let l:obj.lsp_config = a:linter.lsp_config
+ endif
endif
let l:obj.output_stream = get(a:linter, 'output_stream', 'stdout')
diff --git a/autoload/ale/lsp/message.vim b/autoload/ale/lsp/message.vim
index 9e05156d..9ed41ac4 100644
--- a/autoload/ale/lsp/message.vim
+++ b/autoload/ale/lsp/message.vim
@@ -138,3 +138,9 @@ function! ale#lsp#message#Hover(buffer, line, column) abort
\ 'position': {'line': a:line - 1, 'character': a:column},
\}]
endfunction
+
+function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
+ return [0, 'workspace/didChangeConfiguration', {
+ \ 'settings': a:config,
+ \}]
+endfunction
diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim
index a11c76bc..55190483 100644
--- a/autoload/ale/lsp_linter.vim
+++ b/autoload/ale/lsp_linter.vim
@@ -190,6 +190,12 @@ function! ale#lsp_linter#StartLSP(buffer, linter) abort
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer)
+ if !empty(get(a:linter, 'lsp_config'))
+ " set LSP configuration options (workspace/didChangeConfiguration)
+ let l:config_message = ale#lsp#message#DidChangeConfiguration(a:buffer, a:linter.lsp_config)
+ call ale#lsp#Send(l:conn_id, l:config_message)
+ endif
+
let l:details = {
\ 'buffer': a:buffer,
\ 'connection_id': l:conn_id,
diff --git a/autoload/ale/path.vim b/autoload/ale/path.vim
index 2d8a6ac7..89b119f4 100644
--- a/autoload/ale/path.vim
+++ b/autoload/ale/path.vim
@@ -65,7 +65,11 @@ endfunction
" Output 'cd <directory> && '
" This function can be used changing the directory for a linter command.
function! ale#path#CdString(directory) abort
- return 'cd ' . ale#Escape(a:directory) . ' && '
+ if has('win32')
+ return 'cd /d ' . ale#Escape(a:directory) . ' && '
+ else
+ return 'cd ' . ale#Escape(a:directory) . ' && '
+ endif
endfunction
" Output 'cd <buffer_filename_directory> && '
diff --git a/doc/ale-ansible.txt b/doc/ale-ansible.txt
new file mode 100644
index 00000000..3a4efaa5
--- /dev/null
+++ b/doc/ale-ansible.txt
@@ -0,0 +1,16 @@
+===============================================================================
+ALE Ansible Integration *ale-ansible-options*
+
+
+===============================================================================
+ansible-lint *ale-ansible-ansible-lint*
+
+g:ale_ansible_ansible_lint_executable *g:ale_ansible_ansible_lint_executable*
+ *b:ale_ansible_ansible_lint_executable*
+ Type: |String|
+ Default: `'ansible-lint'`
+
+ This variable can be changed to modify the executable used for ansible-lint.
+
+===============================================================================
+ vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale-d.txt b/doc/ale-d.txt
index 8db04774..55596062 100644
--- a/doc/ale-d.txt
+++ b/doc/ale-d.txt
@@ -3,6 +3,17 @@ ALE D Integration *ale-d-options*
===============================================================================
+dls *ale-d-dls*
+
+g:ale_d_dls_executable *g:ale_d_dls_executable*
+ *b:ale_d_dls_executable*
+ Type: |String|
+ Default: `dls`
+
+See |ale-integrations-local-executables|
+
+
+===============================================================================
uncrustify *ale-d-uncrustify*
See |ale-c-uncrustify| for information about the available options.
diff --git a/doc/ale-elixir.txt b/doc/ale-elixir.txt
index ac0ec605..769842a4 100644
--- a/doc/ale-elixir.txt
+++ b/doc/ale-elixir.txt
@@ -41,4 +41,17 @@ See https://github.com/jeremyjh/dialyxir#with-explaining-stuff for more
information.
===============================================================================
+elixir-ls *ale-elixir-elixir-ls*
+
+Elixir Language Server (https://github.com/JakeBecker/elixir-ls)
+
+g:ale_elixir_elixir_ls_release *g:ale_elixir_elixir_ls_release*
+ *b:ale_elixir_elixir_ls_release*
+ Type: |String|
+ Default: `'elixir-ls'`
+
+ Location of the elixir-ls release directory. This directory must contain
+ the language server scripts (language_server.sh and language_server.bat).
+
+===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale-hcl.txt b/doc/ale-hcl.txt
new file mode 100644
index 00000000..8060ac44
--- /dev/null
+++ b/doc/ale-hcl.txt
@@ -0,0 +1,11 @@
+===============================================================================
+ALE HCL Integration *ale-hcl-options*
+
+
+===============================================================================
+terraform-fmt *ale-hcl-terraform-fmt*
+
+See |ale-terraform-fmt| for information about the available options.
+
+===============================================================================
+ vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale-json.txt b/doc/ale-json.txt
index 0ec7932d..6a0a9fae 100644
--- a/doc/ale-json.txt
+++ b/doc/ale-json.txt
@@ -73,6 +73,13 @@ g:ale_json_jq_options *g:ale_json_jq_options*
This option can be changed to pass extra options to `jq`.
+g:ale_json_jq_filters *g:ale_json_jq_filters*
+ *b:ale_json_jq_filters*
+ Type: |String|
+ Default: `'.'`
+
+ This option can be changed to pass custom filters to `jq`.
+
===============================================================================
prettier *ale-json-prettier*
diff --git a/doc/ale-rust.txt b/doc/ale-rust.txt
index 13e5f6f0..ce5634ae 100644
--- a/doc/ale-rust.txt
+++ b/doc/ale-rust.txt
@@ -109,6 +109,7 @@ g:ale_rust_cargo_include_features *g:ale_rust_cargo_include_features*
When defined, ALE will set the `--features` option when invoking `cargo` to
perform the lint check. See |g:ale_rust_cargo_default_feature_behavior|.
+
g:ale_rust_cargo_avoid_whole_workspace *g:ale_rust_cargo_avoid_whole_workspace*
*b:ale_rust_cargo_avoid_whole_workspace*
Type: |Number|
@@ -119,6 +120,36 @@ g:ale_rust_cargo_avoid_whole_workspace *g:ale_rust_cargo_avoid_whole_workspace*
in the crate's directory. Otherwise, behave as usual.
+g:ale_rust_cargo_use_clippy
+ *g:ale_rust_cargo_use_clippy*
+ *b:ale_rust_cargo_use_clippy*
+ Type: |Number|
+ Default: `0`
+
+ When set to 1, `cargo clippy` will be used instead of `cargo check` or
+ `cargo build` as linter.
+ For details of `cargo clippy`, please visit the following link:
+
+ https://github.com/rust-lang-nursery/rust-clippy
+
+ Since `cargo clippy` is optional toolchain, it's safer to check whether
+ `cargo-clippy` is executable as follows:
+>
+ let g:ale_rust_cargo_use_clippy = executable('cargo-clippy')
+<
+
+g:ale_rust_cargo_clippy_options
+ *g:ale_rust_cargo_clippy_options*
+ *b:ale_rust_cargo_clippy_options*
+
+ Type: |String|
+ Default: `''`
+
+ When `cargo clippy` is used, this value will be added to a command line to run
+ it. This variable is useful when you want to add some extra options which
+ only `cargo clippy` supports (e.g. `--deny`).
+
+
===============================================================================
rls *ale-rust-rls*
diff --git a/doc/ale-terraform.txt b/doc/ale-terraform.txt
index ec86e9a0..49a55028 100644
--- a/doc/ale-terraform.txt
+++ b/doc/ale-terraform.txt
@@ -3,6 +3,24 @@ ALE Terraform Integration *ale-terraform-options*
===============================================================================
+fmt *ale-terraform-fmt*
+
+g:ale_terraform_fmt_executable *g:ale_terraform_fmt_executable*
+ *b:ale_terraform_fmt_executable*
+
+ Type: |String|
+ Default: `'terraform'`
+
+ This variable can be changed to use a different executable for terraform.
+
+
+g:ale_terraform_fmt_options *g:ale_terraform_fmt_options*
+ *b:ale_terraform_fmt_options*
+ Type: |String|
+ Default: `''`
+
+
+===============================================================================
tflint *ale-terraform-tflint*
g:ale_terraform_tflint_executable *g:ale_terraform_tflint_executable*
diff --git a/doc/ale.txt b/doc/ale.txt
index 24d69fb2..7e37d2dc 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -18,6 +18,8 @@ CONTENTS *ale-contents*
6.1 Highlights........................|ale-highlights|
6.2 Options for write-good Linter.....|ale-write-good-options|
7. Integration Documentation............|ale-integrations|
+ ansible...............................|ale-ansible-options|
+ ansible-lint........................|ale-ansible-ansible-lint|
asciidoc..............................|ale-asciidoc-options|
write-good..........................|ale-asciidoc-write-good|
asm...................................|ale-asm-options|
@@ -67,6 +69,7 @@ CONTENTS *ale-contents*
cuda..................................|ale-cuda-options|
nvcc................................|ale-cuda-nvcc|
d.....................................|ale-d-options|
+ dls.................................|ale-d-dls|
uncrustify..........................|ale-d-uncrustify|
dart..................................|ale-dart-options|
dartanalyzer........................|ale-dart-dartanalyzer|
@@ -77,6 +80,7 @@ CONTENTS *ale-contents*
mix.................................|ale-elixir-mix|
mix_format..........................|ale-elixir-mix-format|
dialyxir............................|ale-elixir-dialyxir|
+ elixir-ls...........................|ale-elixir-elixir-ls|
elm...................................|ale-elm-options|
elm-format..........................|ale-elm-elm-format|
elm-make............................|ale-elm-elm-make|
@@ -125,6 +129,8 @@ CONTENTS *ale-contents*
stack-build.........................|ale-haskell-stack-build|
stylish-haskell.....................|ale-haskell-stylish-haskell|
hie.................................|ale-haskell-hie|
+ hcl...................................|ale-hcl-options|
+ terraform-fmt.......................|ale-hcl-terraform-fmt|
html..................................|ale-html-options|
htmlhint............................|ale-html-htmlhint|
tidy................................|ale-html-tidy|
@@ -295,6 +301,7 @@ CONTENTS *ale-contents*
tcl...................................|ale-tcl-options|
nagelfar............................|ale-tcl-nagelfar|
terraform.............................|ale-terraform-options|
+ fmt.................................|ale-terraform-fmt|
tflint..............................|ale-terraform-tflint|
tex...................................|ale-tex-options|
chktex..............................|ale-tex-chktex|
@@ -395,11 +402,11 @@ Notes:
* CSS: `csslint`, `prettier`, `stylelint`
* Cucumber: `cucumber`
* Cython (pyrex filetype): `cython`
-* D: `dmd`, `uncrustify`
+* D: `dls`, `dmd`, `uncrustify`
* Dafny: `dafny`!!
* Dart: `dartanalyzer`!!, `language_server`, dartfmt!!
* Dockerfile: `hadolint`
-* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!
+* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!, `elixir-ls`
* Elm: `elm-format, elm-make`
* Erb: `erb`, `erubi`, `erubis`
* Erlang: `erlc`, `SyntaxErl`
@@ -415,6 +422,7 @@ Notes:
* Haml: `haml-lint`
* Handlebars: `ember-template-lint`
* Haskell: `brittany`, `ghc`, `cabal-ghc`, `stylish-haskell`, `stack-ghc`, `stack-build`!!, `ghc-mod`, `hlint`, `hdevtools`, `hfmt`, `hie`
+* HCL: `terraform-fmt`
* HTML: `alex`!!, `HTMLHint`, `proselint`, `tidy`, `write-good`
* Idris: `idris`
* Java: `checkstyle`, `javac`, `google-java-format`, `PMD`, `javalsp`, `uncrustify`
@@ -467,7 +475,7 @@ Notes:
* SQL: `sqlint`, `sqlfmt`
* Swift: `swiftlint`, `swiftformat`
* Tcl: `nagelfar`!!
-* Terraform: `tflint`
+* Terraform: `fmt`, `tflint`
* Texinfo: `alex`!!, `proselint`, `write-good`
* Text^: `alex`!!, `proselint`, `redpen`, `textlint`, `vale`, `write-good`
* Thrift: `thrift`
@@ -712,10 +720,11 @@ Completion is only supported while at least one LSP linter is enabled. ALE
will only suggest symbols provided by the LSP servers.
Suggestions will be made while you type after completion is enabled.
-Completion can be enabled by setting |g:ale_completion_enabled| to `1`. The
-delay for completion can be configured with |g:ale_completion_delay|. ALE will
-only suggest so many possible matches for completion. The maximum number of
-items can be controlled with |g:ale_completion_max_suggestions|.
+Completion can be enabled by setting |g:ale_completion_enabled| to `1`. This
+setting must be set to `1` before ALE is loaded. The delay for completion can
+be configured with |g:ale_completion_delay|. ALE will only suggest so many
+possible matches for completion. The maximum number of items can be controlled
+with |g:ale_completion_max_suggestions|.
If you don't like some of the suggestions you see, you can filter them out
with |g:ale_completion_excluded_words| or |b:ale_completion_excluded_words|.
@@ -761,12 +770,25 @@ at the cursor taken from LSP linters. The following commands are supported:
|ALEHover| - Print information about the symbol at the cursor.
-If |b:ale_set_balloons| is set to `1` and your version of Vim supports the
+If |g:ale_set_balloons| is set to `1` and your version of Vim supports the
|balloon_show()| function, then "hover" information also show up when you move
the mouse over a symbol in a buffer. Diagnostic information will take priority
over hover information for balloons. If a line contains a problem, that
problem will be displayed in a balloon instead of hover information.
+For Vim 8.1+ terminals, mouse hovering is disabled by default. Enabling
+|balloonexpr| commands in terminals can cause scrolling issues in terminals,
+so ALE will not attempt to show balloons unless |g:ale_set_balloons| is set to
+`1` before ALE is loaded.
+
+For enabling mouse support in terminals, you may have to change your mouse
+settings. For example: >
+
+ " Example mouse settings.
+ " You will need to try different settings, depending on your terminal.
+ set mouse=a
+ set ttymouse=xterm
+<
===============================================================================
6. Global Options *ale-options*
@@ -879,6 +901,9 @@ g:ale_completion_enabled *g:ale_completion_enabled*
When this option is set to `1`, completion support will be enabled.
+ This setting must be set to `1` before ALE is loaded for this behavior
+ to be enabled.
+
See |ale-completion|
diff --git a/run-tests.bat b/run-tests.bat
index a3b47056..9ba6b554 100644
--- a/run-tests.bat
+++ b/run-tests.bat
@@ -13,7 +13,7 @@ set VADER_OUTPUT_FILE=%~dp0\vader_output
REM Automatically re-run Windows tests, which can fail some times.
set tries=0
-RUN_TESTS:
+:RUN_TESTS
set /a tries=%tries%+1
type nul > "%VADER_OUTPUT_FILE%"
C:\vim\vim\vim80\vim.exe -u test/vimrc "+Vader! %tests%"
@@ -23,7 +23,7 @@ IF %code% EQU 0 GOTO :SHOW_RESULTS
IF %tries% GEQ 2 GOTO :SHOW_RESULTS
GOTO :RUN_TESTS
-SHOW_RESULTS:
+:SHOW_RESULTS
type "%VADER_OUTPUT_FILE%"
del "%VADER_OUTPUT_FILE%"
diff --git a/test/command_callback/elixir_paths/mix_project/lib/foo.ex b/test/command_callback/elixir_paths/mix_project/lib/foo.ex
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/elixir_paths/mix_project/lib/foo.ex
diff --git a/test/command_callback/elixir_paths/mix_project/mix.exs b/test/command_callback/elixir_paths/mix_project/mix.exs
new file mode 100644
index 00000000..419685ae
--- /dev/null
+++ b/test/command_callback/elixir_paths/mix_project/mix.exs
@@ -0,0 +1,3 @@
+defmodule Test.MixProject do
+ # fake mix project file
+end
diff --git a/test/command_callback/psalm-project/vendor/bin/psalm-language-server b/test/command_callback/psalm-project/vendor/bin/psalm-language-server
new file mode 100755
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/psalm-project/vendor/bin/psalm-language-server
diff --git a/test/command_callback/stack_build_paths/stack.yaml b/test/command_callback/stack_build_paths/stack.yaml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/stack_build_paths/stack.yaml
diff --git a/test/command_callback/stack_ghc_paths/stack.yaml b/test/command_callback/stack_ghc_paths/stack.yaml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/stack_ghc_paths/stack.yaml
diff --git a/test/command_callback/test_ansible_lint_command_callback.vader b/test/command_callback/test_ansible_lint_command_callback.vader
new file mode 100644
index 00000000..ddc6c6c8
--- /dev/null
+++ b/test/command_callback/test_ansible_lint_command_callback.vader
@@ -0,0 +1,17 @@
+Before:
+ call ale#assert#SetUpLinterTest('ansible', 'ansible_lint')
+ let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
+
+After:
+ unlet! b:bin_dir
+ unlet! b:executable
+ call ale#assert#TearDownLinterTest()
+
+Execute(The ansible_lint command callback should return default string):
+ AssertLinter 'ansible-lint', ale#Escape('ansible-lint') . ' -p %t'
+
+Execute(The ansible_lint executable should be configurable):
+ let g:ale_ansible_ansible_lint_executable = '~/.local/bin/ansible-lint'
+
+ AssertLinter '~/.local/bin/ansible-lint',
+ \ ale#Escape('~/.local/bin/ansible-lint') . ' -p %t'
diff --git a/test/command_callback/test_c_cppcheck_command_callbacks.vader b/test/command_callback/test_c_cppcheck_command_callbacks.vader
index 3fc87a79..3ae4bdbe 100644
--- a/test/command_callback/test_c_cppcheck_command_callbacks.vader
+++ b/test/command_callback/test_c_cppcheck_command_callbacks.vader
@@ -19,6 +19,6 @@ Execute(cppcheck for C++ should detect compile_commands.json files):
call ale#test#SetFilename('cppcheck_paths/one/foo.cpp')
AssertLinter 'cppcheck',
- \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) . ' && '
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one'))
\ . ale#Escape('cppcheck')
\ . ' -q --language=c --project=compile_commands.json --enable=style %t'
diff --git a/test/command_callback/test_cargo_command_callbacks.vader b/test/command_callback/test_cargo_command_callbacks.vader
index ac8846b0..f0afbc91 100644
--- a/test/command_callback/test_cargo_command_callbacks.vader
+++ b/test/command_callback/test_cargo_command_callbacks.vader
@@ -128,3 +128,27 @@ Execute(When a crate belongs to a workspace we chdir into the crate, unless we d
\ 'cargo --version',
\ 'cargo check --frozen --message-format=json -q',
\]
+
+Execute(When ale_rust_cargo_use_clippy is set, cargo-clippy is used as linter):
+ let b:ale_rust_cargo_use_clippy = 1
+ AssertLinter '', [
+ \ 'cargo --version',
+ \ 'cargo clippy --frozen --message-format=json -q ',
+ \]
+
+Execute(When ale_rust_cargo_clippy_options is set, cargo-clippy appends it to commandline):
+ let b:ale_rust_cargo_use_clippy = 1
+ let b:ale_rust_cargo_clippy_options = '-- -D warnings'
+ AssertLinter '', [
+ \ 'cargo --version',
+ \ 'cargo clippy --frozen --message-format=json -q -- -D warnings',
+ \]
+
+Execute(cargo-check does not refer ale_rust_cargo_clippy_options):
+ let b:ale_rust_cargo_use_clippy = 0
+ let b:ale_rust_cargo_use_check = 1
+ let b:ale_rust_cargo_clippy_options = '-- -D warnings'
+ AssertLinter '', [
+ \ 'cargo --version',
+ \ 'cargo check --frozen --message-format=json -q',
+ \]
diff --git a/test/command_callback/test_cpp_cppcheck_command_callbacks.vader b/test/command_callback/test_cpp_cppcheck_command_callbacks.vader
index 3a7ada2c..352c88d5 100644
--- a/test/command_callback/test_cpp_cppcheck_command_callbacks.vader
+++ b/test/command_callback/test_cpp_cppcheck_command_callbacks.vader
@@ -17,6 +17,6 @@ Execute(cppcheck for C++ should detect compile_commands.json files):
call ale#test#SetFilename('cppcheck_paths/one/foo.cpp')
AssertLinter 'cppcheck',
- \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) . ' && '
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one'))
\ . ale#Escape('cppcheck')
\ . ' -q --language=c++ --project=compile_commands.json --enable=style %t'
diff --git a/test/command_callback/test_cs_mcsc_command_callbacks.vader b/test/command_callback/test_cs_mcsc_command_callbacks.vader
index 20ddb28b..d15898e0 100644
--- a/test/command_callback/test_cs_mcsc_command_callbacks.vader
+++ b/test/command_callback/test_cs_mcsc_command_callbacks.vader
@@ -5,43 +5,43 @@ After:
call ale#assert#TearDownLinterTest()
Execute(The mcsc linter should return the correct default command):
- AssertLinter 'mcs', 'cd ' . ale#Escape(g:dir) . ' && '
+ AssertLinter 'mcs', ale#path#CdString(g:dir)
\ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
Execute(The options should be be used in the command):
let g:ale_cs_mcsc_options = '-pkg:dotnet'
- AssertLinter 'mcs', 'cd ' . ale#Escape(g:dir) . ' && '
+ AssertLinter 'mcs', ale#path#CdString(g:dir)
\ . 'mcs -unsafe -pkg:dotnet -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
Execute(The souce path should be be used in the command):
let g:ale_cs_mcsc_source = '../foo/bar'
- AssertLinter 'mcs', 'cd ' . ale#Escape('../foo/bar') . ' && '
+ AssertLinter 'mcs', ale#path#CdString('../foo/bar')
\ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
Execute(The list of search pathes for assemblies should be be used in the command if not empty):
let g:ale_cs_mcsc_assembly_path = ['/usr/lib/mono', '../foo/bar']
- AssertLinter 'mcs', 'cd ' . ale#Escape(g:dir) . ' && '
+ AssertLinter 'mcs', ale#path#CdString(g:dir)
\ . 'mcs -unsafe'
\ . ' -lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar')
\ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
let g:ale_cs_mcsc_assembly_path = []
- AssertLinter 'mcs', 'cd ' . ale#Escape(g:dir) . ' && '
+ AssertLinter 'mcs', ale#path#CdString(g:dir)
\ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
Execute(The list of assemblies should be be used in the command if not empty):
let g:ale_cs_mcsc_assemblies = ['foo.dll', 'bar.dll']
- AssertLinter 'mcs', 'cd ' . ale#Escape(g:dir) . ' && '
+ AssertLinter 'mcs', ale#path#CdString(g:dir)
\ . 'mcs -unsafe'
\ . ' -r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll')
\ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
let g:ale_cs_mcsc_assemblies = []
- AssertLinter 'mcs', 'cd ' . ale#Escape(g:dir) . ' && '
+ AssertLinter 'mcs', ale#path#CdString(g:dir)
\ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs')
diff --git a/test/command_callback/test_d_dls_callbacks.vader b/test/command_callback/test_d_dls_callbacks.vader
new file mode 100644
index 00000000..156ebf66
--- /dev/null
+++ b/test/command_callback/test_d_dls_callbacks.vader
@@ -0,0 +1,19 @@
+Before:
+ call ale#assert#SetUpLinterTest('d', 'dls')
+
+ Save &filetype
+ let &filetype = 'd'
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The language string should be correct):
+ AssertLSPLanguage 'd'
+
+Execute(The default executable should be correct):
+ AssertLinter 'dls', 'dls'
+
+Execute(The executable should be configurable):
+ let g:ale_d_dls_executable = 'foobar'
+
+ AssertLinter 'foobar', 'foobar'
diff --git a/test/command_callback/test_elixir_ls_command_callbacks.vader b/test/command_callback/test_elixir_ls_command_callbacks.vader
new file mode 100644
index 00000000..0d00354b
--- /dev/null
+++ b/test/command_callback/test_elixir_ls_command_callbacks.vader
@@ -0,0 +1,29 @@
+Before:
+ call ale#assert#SetUpLinterTest('elixir', 'elixir_ls')
+
+ let g:ale_has_override['win32'] = 0
+
+After:
+ let g:ale_has_override = {}
+
+ call ale#assert#TearDownLinterTest()
+
+Execute(should set correct defaults (unix)):
+ AssertLinter 'elixir-ls/language_server.sh', 'elixir-ls/language_server.sh'
+
+Execute(should set correct defaults (win32)):
+ let g:ale_has_override['win32'] = 1
+
+ AssertLinter 'elixir-ls\language_server.bat', 'elixir-ls\language_server.bat'
+
+Execute(should configure elixir-ls release location):
+ let b:ale_elixir_elixir_ls_release = 'boo'
+
+ AssertLinter 'boo/language_server.sh', 'boo/language_server.sh'
+
+Execute(should set correct LSP values):
+ call ale#test#SetFilename('mix_paths/wrapped_project/lib/app.ex')
+
+ AssertLSPLanguage 'elixir'
+ AssertLSPOptions {}
+ AssertLSPProject ale#path#Simplify(g:dir . '/mix_paths/wrapped_project')
diff --git a/test/command_callback/test_elixir_mix_command_callbacks.vader b/test/command_callback/test_elixir_mix_command_callbacks.vader
index 18fb13ed..9315a850 100644
--- a/test/command_callback/test_elixir_mix_command_callbacks.vader
+++ b/test/command_callback/test_elixir_mix_command_callbacks.vader
@@ -17,3 +17,10 @@ Execute(The default mix command should be correct):
\ ale#path#CdString(ale#path#Simplify(g:dir . '/mix_paths/wrapped_project'))
\ . g:env_prefix
\ . 'mix compile %s'
+
+Execute(The FindMixProjectRoot should detect the project root directory via mix.exs):
+ silent execute 'file ' . fnameescape(g:dir . '/elixir_paths/mix_project/lib/app.ex')
+
+ AssertEqual
+ \ ale#path#Simplify(g:dir . '/elixir_paths/mix_project'),
+ \ ale#handlers#elixir#FindMixProjectRoot(bufnr(''))
diff --git a/test/command_callback/test_gobuild_command_callback.vader b/test/command_callback/test_gobuild_command_callback.vader
index 8acbec56..c6e324f2 100644
--- a/test/command_callback/test_gobuild_command_callback.vader
+++ b/test/command_callback/test_gobuild_command_callback.vader
@@ -11,14 +11,14 @@ After:
Execute(The default commands should be correct):
AssertLinter 'go',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . 'go test -c -o /dev/null ./'
Execute(Extra options should be supported):
let g:ale_go_gobuild_options = '--foo-bar'
AssertLinter 'go',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . 'go test --foo-bar -c -o /dev/null ./'
let g:ale_go_gobuild_options = ''
@@ -27,5 +27,5 @@ Execute(The executable should be configurable):
let g:ale_go_go_executable = 'foobar'
AssertLinter 'foobar',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . 'foobar test -c -o /dev/null ./'
diff --git a/test/command_callback/test_golangci_lint_command_callback.vader b/test/command_callback/test_golangci_lint_command_callback.vader
index b3805f3a..345f58b1 100644
--- a/test/command_callback/test_golangci_lint_command_callback.vader
+++ b/test/command_callback/test_golangci_lint_command_callback.vader
@@ -7,7 +7,7 @@ After:
Execute(The golangci-lint defaults should be correct):
AssertLinter 'golangci-lint',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --enable-all'
@@ -16,7 +16,7 @@ Execute(The golangci-lint callback should use a configured executable):
let b:ale_go_golangci_lint_executable = 'something else'
AssertLinter 'something else',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('something else')
\ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --enable-all'
@@ -25,7 +25,7 @@ Execute(The golangci-lint callback should use configured options):
let b:ale_go_golangci_lint_options = '--foobar'
AssertLinter 'golangci-lint',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --foobar'
@@ -34,5 +34,5 @@ Execute(The golangci-lint `lint_package` option should use the correct command):
let b:ale_go_golangci_lint_package = 1
AssertLinter 'golangci-lint',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('golangci-lint') . ' run --enable-all'
diff --git a/test/command_callback/test_gometalinter_command_callback.vader b/test/command_callback/test_gometalinter_command_callback.vader
index d788c5bd..88e86801 100644
--- a/test/command_callback/test_gometalinter_command_callback.vader
+++ b/test/command_callback/test_gometalinter_command_callback.vader
@@ -7,7 +7,7 @@ After:
Execute(The gometalinter defaults should be correct):
AssertLinter 'gometalinter',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('gometalinter')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' .'
@@ -16,7 +16,7 @@ Execute(The gometalinter callback should use a configured executable):
let b:ale_go_gometalinter_executable = 'something else'
AssertLinter 'something else',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('something else')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' .'
@@ -25,7 +25,7 @@ Execute(The gometalinter callback should use configured options):
let b:ale_go_gometalinter_options = '--foobar'
AssertLinter 'gometalinter',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('gometalinter')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' --foobar' . ' .'
@@ -34,5 +34,5 @@ Execute(The gometalinter `lint_package` option should use the correct command):
let b:ale_go_gometalinter_lint_package = 1
AssertLinter 'gometalinter',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('gometalinter') . ' .'
diff --git a/test/command_callback/test_gosimple_command_callback.vader b/test/command_callback/test_gosimple_command_callback.vader
index 7b8c66ae..59013df0 100644
--- a/test/command_callback/test_gosimple_command_callback.vader
+++ b/test/command_callback/test_gosimple_command_callback.vader
@@ -7,4 +7,4 @@ After:
Execute(The default gosimple command should be correct):
AssertLinter 'gosimple',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && gosimple .'
+ \ ale#path#CdString(expand('%:p:h')) . ' gosimple .'
diff --git a/test/command_callback/test_gotype_command_callback.vader b/test/command_callback/test_gotype_command_callback.vader
index da9ceaf3..1898a0cb 100644
--- a/test/command_callback/test_gotype_command_callback.vader
+++ b/test/command_callback/test_gotype_command_callback.vader
@@ -7,7 +7,7 @@ After:
Execute(The default gotype command should be correct):
AssertLinter 'gotype',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && gotype .'
+ \ ale#path#CdString(expand('%:p:h')) . ' gotype .'
Execute(The gotype callback should ignore test files):
call ale#test#SetFilename('bla_test.go')
diff --git a/test/command_callback/test_govet_command_callback.vader b/test/command_callback/test_govet_command_callback.vader
index ab93a5cb..a55c0812 100644
--- a/test/command_callback/test_govet_command_callback.vader
+++ b/test/command_callback/test_govet_command_callback.vader
@@ -8,12 +8,12 @@ After:
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
- AssertLinter 'go', 'cd ' . ale#Escape(expand('%:p:h')) . ' && go vet .'
+ AssertLinter 'go', ale#path#CdString(expand('%:p:h')) . ' go vet .'
Execute(Extra options should be supported):
let g:ale_go_govet_options = '--foo-bar'
- AssertLinter 'go', 'cd ' . ale#Escape(expand('%:p:h')) . ' && go vet --foo-bar .'
+ AssertLinter 'go', ale#path#CdString(expand('%:p:h')) . ' go vet --foo-bar .'
Execute(The executable should be configurable):
let g:ale_go_go_executable = 'foobar'
- AssertLinter 'foobar', 'cd ' . ale#Escape(expand('%:p:h')) . ' && foobar vet .'
+ AssertLinter 'foobar', ale#path#CdString(expand('%:p:h')) . ' foobar vet .'
diff --git a/test/command_callback/test_haskell_hlint_command_callbacks.vader b/test/command_callback/test_haskell_hlint_command_callbacks.vader
index d4ee708c..6d227c9d 100644
--- a/test/command_callback/test_haskell_hlint_command_callbacks.vader
+++ b/test/command_callback/test_haskell_hlint_command_callbacks.vader
@@ -1,9 +1,6 @@
Before:
call ale#assert#SetUpLinterTest('haskell', 'hlint')
- let g:ale_haskell_hlint_executable = 'hlint'
- let g:ale_haskell_hlint_options = ''
-
let b:base_opts = '--color=never --json -'
After:
diff --git a/test/command_callback/test_haskell_stack_build_command_callback.vader b/test/command_callback/test_haskell_stack_build_command_callback.vader
new file mode 100644
index 00000000..f1e6f755
--- /dev/null
+++ b/test/command_callback/test_haskell_stack_build_command_callback.vader
@@ -0,0 +1,13 @@
+Before:
+ call ale#assert#SetUpLinterTest('haskell', 'stack_build')
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The linter should not be executed when there's no stack.yaml file):
+ AssertLinterNotExecuted
+
+Execute(The linter should be executed when there is a stack.yaml file):
+ call ale#test#SetFilename('stack_build_paths/test.hs')
+
+ AssertLinter 'stack', 'stack build --fast'
diff --git a/test/command_callback/test_haskell_stack_ghc_command_callback.vader b/test/command_callback/test_haskell_stack_ghc_command_callback.vader
new file mode 100644
index 00000000..4adab583
--- /dev/null
+++ b/test/command_callback/test_haskell_stack_ghc_command_callback.vader
@@ -0,0 +1,14 @@
+Before:
+ call ale#assert#SetUpLinterTest('haskell', 'stack_ghc')
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The linter should not be executed when there's no stack.yaml file):
+ AssertLinterNotExecuted
+
+Execute(The linter should be executed when there is a stack.yaml file):
+ call ale#test#SetFilename('stack_ghc_paths/test.hs')
+
+ AssertLinter 'stack', 'stack ghc -- -fno-code -v0 %t'
+
diff --git a/test/command_callback/test_javac_command_callback.vader b/test/command_callback/test_javac_command_callback.vader
index 07a0794a..2dcb6a1b 100644
--- a/test/command_callback/test_javac_command_callback.vader
+++ b/test/command_callback/test_javac_command_callback.vader
@@ -3,7 +3,7 @@ Before:
call ale#test#SetFilename('dummy.java')
let g:cp_sep = has('unix') ? ':' : ';'
- let g:prefix = 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ let g:prefix = ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('javac') . ' -Xlint'
function! GetCommand(previous_output) abort
@@ -43,7 +43,7 @@ Execute(The executable should be configurable):
let g:ale_java_javac_executable = 'foobar'
AssertLinter 'foobar',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('foobar') . ' -Xlint'
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
@@ -106,7 +106,7 @@ Execute(The javac callback should detect source directories):
call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' . ale#Escape('javac') . ' -Xlint'
+ \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
\ )
@@ -124,7 +124,7 @@ Execute(The javac callback should combine detected source directories and classp
\ '/xyz/abc.jar',
\]
AssertLinter 'javac',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' . ale#Escape('javac') . ' -Xlint'
+ \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep))
\ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
@@ -147,7 +147,7 @@ Execute(The javac callback should include src/test/java for test paths):
call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' . ale#Escape('javac') . ' -Xlint'
+ \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/src/test/java/'),
@@ -160,7 +160,7 @@ Execute(The javac callback should include src/main/jaxb when available):
call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' . ale#Escape('javac') . ' -Xlint'
+ \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/jaxb/'),
diff --git a/test/command_callback/test_lintr_command_callback.vader b/test/command_callback/test_lintr_command_callback.vader
index 8a0e6c1c..187d3875 100644
--- a/test/command_callback/test_lintr_command_callback.vader
+++ b/test/command_callback/test_lintr_command_callback.vader
@@ -6,7 +6,7 @@ After:
Execute(The default lintr command should be correct):
AssertLinter 'Rscript',
- \ 'cd ' . ale#Escape(getcwd()) . ' && '
+ \ ale#path#CdString(getcwd())
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
@@ -17,7 +17,7 @@ Execute(The lintr options should be configurable):
let b:ale_r_lintr_options = 'with_defaults(object_usage_linter = NULL)'
AssertLinter 'Rscript',
- \ 'cd ' . ale#Escape(getcwd()) . ' && '
+ \ ale#path#CdString(getcwd())
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
@@ -28,7 +28,7 @@ Execute(If the lint_package flag is set, lintr::lint_package should be called):
let b:ale_r_lintr_lint_package = 1
AssertLinter 'Rscript',
- \ 'cd ' . ale#Escape(getcwd()) . ' && '
+ \ ale#path#CdString(getcwd())
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint_package(cache = FALSE, '
diff --git a/test/command_callback/test_mypy_command_callback.vader b/test/command_callback/test_mypy_command_callback.vader
index 037d8176..8ca35207 100644
--- a/test/command_callback/test_mypy_command_callback.vader
+++ b/test/command_callback/test_mypy_command_callback.vader
@@ -12,7 +12,7 @@ After:
Execute(The mypy callbacks should return the correct default values):
AssertLinter 'mypy',
- \ 'cd ' . ale#Escape(g:dir) . ' && ' . ale#Escape('mypy')
+ \ ale#path#CdString(g:dir) . ale#Escape('mypy')
\ . ' --show-column-numbers '
\ . '--shadow-file %s %t %s'
@@ -20,7 +20,7 @@ Execute(The mypy executable should be configurable, and escaped properly):
let g:ale_python_mypy_executable = 'executable with spaces'
AssertLinter 'executable with spaces',
- \ 'cd ' . ale#Escape(g:dir) . ' && ' . ale#Escape('executable with spaces')
+ \ ale#path#CdString(g:dir) . ale#Escape('executable with spaces')
\ . ' --show-column-numbers '
\ . '--shadow-file %s %t %s'
@@ -28,7 +28,7 @@ Execute(The mypy command callback should let you set options):
let g:ale_python_mypy_options = '--some-option'
AssertLinter 'mypy',
- \ 'cd ' . ale#Escape(g:dir) . ' && ' . ale#Escape('mypy')
+ \ ale#path#CdString(g:dir) . ale#Escape('mypy')
\ . ' --show-column-numbers --some-option '
\ . '--shadow-file %s %t %s'
@@ -36,8 +36,8 @@ Execute(The mypy command should switch directories to the detected project root)
silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py')
AssertLinter 'mypy',
- \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir'))
- \ . ' && ' . ale#Escape('mypy')
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir'))
+ \ . ale#Escape('mypy')
\ . ' --show-column-numbers '
\ . '--shadow-file %s %t %s'
@@ -47,8 +47,8 @@ Execute(The mypy callbacks should detect virtualenv directories and switch to th
let b:executable = ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/mypy')
AssertLinter b:executable,
- \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
- \ . ' && ' . ale#Escape(b:executable)
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
+ \ . ale#Escape(b:executable)
\ . ' --show-column-numbers '
\ . '--shadow-file %s %t %s'
@@ -57,8 +57,8 @@ Execute(You should able able to use the global mypy instead):
let g:ale_python_mypy_use_global = 1
AssertLinter 'mypy',
- \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
- \ . ' && ' . ale#Escape('mypy')
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
+ \ . ale#Escape('mypy')
\ . ' --show-column-numbers '
\ . '--shadow-file %s %t %s'
diff --git a/test/command_callback/test_psalm_command_callbacks.vader b/test/command_callback/test_psalm_command_callbacks.vader
index 4c31b7b4..d731054f 100644
--- a/test/command_callback/test_psalm_command_callbacks.vader
+++ b/test/command_callback/test_psalm_command_callbacks.vader
@@ -2,11 +2,28 @@ Before:
call ale#assert#SetUpLinterTest('php', 'psalm')
After:
+ if isdirectory(g:dir . '/.git')
+ call delete(g:dir . '/.git', 'd')
+ endif
+
call ale#assert#TearDownLinterTest()
-Execute(Custom executables should be used for the executable and command):
- let g:ale_php_psalm_executable = 'psalm_test'
+Execute(The default executable path should be correct):
+ AssertLinter 'psalm-language-server',
+ \ ale#Escape('psalm-language-server')
+
+Execute(Vendor executables should be detected):
+ call ale#test#SetFilename('psalm-project/test.php')
+
+ AssertLinter
+ \ ale#path#Simplify(g:dir . '/psalm-project/vendor/bin/psalm-language-server'),
+ \ ale#Escape(ale#path#Simplify(
+ \ g:dir
+ \ . '/psalm-project/vendor/bin/psalm-language-server'
+ \ ))
- AssertLinter 'psalm_test',
- \ ale#Escape('psalm_test') . ' --diff --output-format=emacs %s'
+Execute(The project path should be correct for .git directories):
+ call ale#test#SetFilename('psalm-project/test.php')
+ call mkdir(g:dir . '/.git')
+ AssertLSPProject g:dir \ No newline at end of file
diff --git a/test/command_callback/test_ruby_solargraph.vader b/test/command_callback/test_ruby_solargraph.vader
index b39f686e..c6aee271 100644
--- a/test/command_callback/test_ruby_solargraph.vader
+++ b/test/command_callback/test_ruby_solargraph.vader
@@ -37,3 +37,8 @@ Execute(should set solargraph for ruby app3):
AssertLSPLanguage 'ruby'
AssertLSPOptions {}
AssertLSPProject ale#path#Simplify(g:dir . 'command_callback/../ruby_fixtures/valid_ruby_app3')
+
+Execute(should accept initialization options):
+ AssertLSPOptions {}
+ let b:ale_ruby_solargraph_options = { 'diagnostics': 'true' }
+ AssertLSPOptions { 'diagnostics': 'true' }
diff --git a/test/command_callback/test_sasslint_command_callback.vader b/test/command_callback/test_sasslint_command_callback.vader
index 4d7cc4c7..9142c441 100644
--- a/test/command_callback/test_sasslint_command_callback.vader
+++ b/test/command_callback/test_sasslint_command_callback.vader
@@ -7,5 +7,5 @@ After:
Execute(The default sasslint command should be correct):
AssertLinter 'sass-lint',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('sass-lint') . ' -v -q -f compact %t'
diff --git a/test/command_callback/test_shellcheck_command_callback.vader b/test/command_callback/test_shellcheck_command_callback.vader
index 23684026..22a9ccb5 100644
--- a/test/command_callback/test_shellcheck_command_callback.vader
+++ b/test/command_callback/test_shellcheck_command_callback.vader
@@ -2,7 +2,7 @@ Before:
call ale#assert#SetUpLinterTest('sh', 'shellcheck')
call ale#test#SetFilename('test.sh')
- let b:prefix = 'cd ' . ale#Escape(ale#path#Simplify(g:dir)) . ' && '
+ let b:prefix = ale#path#CdString(ale#path#Simplify(g:dir))
let b:suffix = ' -f gcc -'
After:
diff --git a/test/command_callback/test_staticcheck_command_callback.vader b/test/command_callback/test_staticcheck_command_callback.vader
index 918c12a0..7f17b146 100644
--- a/test/command_callback/test_staticcheck_command_callback.vader
+++ b/test/command_callback/test_staticcheck_command_callback.vader
@@ -7,7 +7,7 @@ After:
Execute(The staticcheck callback should return the right defaults):
AssertLinter 'staticcheck',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . 'staticcheck '
\ . ale#Escape(expand('%' . ':t'))
@@ -15,7 +15,7 @@ Execute(The staticcheck callback should use configured options):
let b:ale_go_staticcheck_options = '-test'
AssertLinter 'staticcheck',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . 'staticcheck '
\ . '-test ' . ale#Escape(expand('%' . ':t'))
@@ -23,4 +23,4 @@ Execute(The staticcheck `lint_package` option should use the correct command):
let b:ale_go_staticcheck_lint_package = 1
AssertLinter 'staticcheck',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && staticcheck .',
+ \ ale#path#CdString(expand('%:p:h')) . 'staticcheck .',
diff --git a/test/command_callback/test_tslint_command_callback.vader b/test/command_callback/test_tslint_command_callback.vader
index bd8a12ec..229ccc96 100644
--- a/test/command_callback/test_tslint_command_callback.vader
+++ b/test/command_callback/test_tslint_command_callback.vader
@@ -7,14 +7,14 @@ After:
Execute(The default tslint command should be correct):
AssertLinter 'tslint',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('tslint') . ' --format json %t'
Execute(The rules directory option should be included if set):
let b:ale_typescript_tslint_rules_dir = '/foo/bar'
AssertLinter 'tslint',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('tslint') . ' --format json'
\ . ' -r ' . ale#Escape('/foo/bar')
\ . ' %t'
@@ -23,5 +23,5 @@ Execute(The executable should be configurable and escaped):
let b:ale_typescript_tslint_executable = 'foo bar'
AssertLinter 'foo bar',
- \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('foo bar') . ' --format json %t'
diff --git a/test/fixers/test_goofle_java_format_fixer_callback.vader b/test/fixers/test_goofle_java_format_fixer_callback.vader
index d64e2788..4c28b330 100644
--- a/test/fixers/test_goofle_java_format_fixer_callback.vader
+++ b/test/fixers/test_goofle_java_format_fixer_callback.vader
@@ -1,8 +1,8 @@
Before:
- Save g:ale_google_java_format_executable
+ Save g:ale_java_google_java_format_executable
" Use an invalid global executable, so we don't match it.
- let g:ale_google_java_format_executable = 'xxxinvalid'
+ let g:ale_java_google_java_format_executable = 'xxxinvalid'
call ale#test#SetDirectory('/testplugin/test/fixers')
@@ -17,11 +17,11 @@ Execute(The google-java-format callback should return 0 when the executable isn'
\ ale#fixers#google_java_format#Fix(bufnr(''))
Execute(The google-java-format callback should run the command when the executable test passes):
- let g:ale_google_java_format_executable = has('win32') ? 'cmd' : 'echo'
+ let g:ale_java_google_java_format_executable = has('win32') ? 'cmd' : 'echo'
AssertEqual
\ {
\ 'read_temporary_file': 1,
- \ 'command': ale#Escape(ale_google_java_format_executable) . ' --replace %t'
+ \ 'command': ale#Escape(ale_java_google_java_format_executable) . ' --replace %t'
\ },
\ ale#fixers#google_java_format#Fix(bufnr(''))
diff --git a/test/fixers/test_isort_fixer_callback.vader b/test/fixers/test_isort_fixer_callback.vader
index 56c08d26..50818621 100644
--- a/test/fixers/test_isort_fixer_callback.vader
+++ b/test/fixers/test_isort_fixer_callback.vader
@@ -27,7 +27,7 @@ Execute(The isort callback should return the correct default values):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir/foo')) . ' && '
+ \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir/foo'))
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort')) . ' -',
\ },
\ ale#fixers#isort#Fix(bufnr(''))
@@ -42,7 +42,7 @@ Execute(The isort callback should respect custom options):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir/foo')) . ' && '
+ \ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir/foo'))
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort'))
\ . ' --multi-line=3 --trailing-comma -',
\ },
diff --git a/test/fixers/test_jq_fixer_callback.vader b/test/fixers/test_jq_fixer_callback.vader
index 2e32bf8e..74580d3b 100644
--- a/test/fixers/test_jq_fixer_callback.vader
+++ b/test/fixers/test_jq_fixer_callback.vader
@@ -1,6 +1,7 @@
Before:
Save g:ale_json_jq_executable
Save g:ale_json_jq_options
+ Save g:ale_json_jq_filters
After:
Restore
@@ -8,7 +9,18 @@ After:
Execute(The jq fixer should use the options you set):
let g:ale_json_jq_executable = 'foo'
let g:ale_json_jq_options = '--bar'
+ let g:ale_json_jq_filters = '.baz'
AssertEqual
- \ {'command': ale#Escape('foo') . ' . --bar'},
+ \ {'command': ale#Escape('foo') . ' .baz --bar'},
+ \ ale#fixers#jq#Fix(bufnr(''))
+
+Execute(The jq fixer should return 0 when there are no filters):
+ let g:ale_json_jq_executable = 'jq'
+ let g:ale_json_jq_options = ''
+
+ let g:ale_json_jq_filters = ''
+
+ AssertEqual
+ \ 0,
\ ale#fixers#jq#Fix(bufnr(''))
diff --git a/test/fixers/test_prettier_eslint_fixer.callback.vader b/test/fixers/test_prettier_eslint_fixer.callback.vader
index ef0b35df..5c899d86 100644
--- a/test/fixers/test_prettier_eslint_fixer.callback.vader
+++ b/test/fixers/test_prettier_eslint_fixer.callback.vader
@@ -85,7 +85,7 @@ Execute(The new --stdin-filepath option should be used when the version is new e
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('prettier-eslint')
\ . ' --eslint-config-path ' . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/.eslintrc.js'))
\ . ' --stdin-filepath %s --stdin',
@@ -106,7 +106,7 @@ Execute(The version number should be cached):
" The newer command should be used.
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('prettier-eslint')
\ . ' --stdin-filepath %s --stdin',
\ },
diff --git a/test/fixers/test_prettier_fixer_callback.vader b/test/fixers/test_prettier_fixer_callback.vader
index 44245630..3697e87c 100644
--- a/test/fixers/test_prettier_fixer_callback.vader
+++ b/test/fixers/test_prettier_fixer_callback.vader
@@ -74,7 +74,7 @@ Execute(--stdin-filepath should be used when prettier is new enough):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --no-semi'
\ . ' --stdin-filepath %s --stdin',
@@ -90,7 +90,7 @@ Execute(The version number should be cached):
" Call it again without the version output. We should use the newer command.
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --stdin-filepath %s --stdin',
\ },
@@ -103,7 +103,7 @@ Execute(Should set --parser based on filetype, TypeScript):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser typescript'
\ . ' --stdin-filepath %s --stdin',
@@ -117,7 +117,7 @@ Execute(Should set --parser based on filetype, CSS):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser css'
\ . ' --stdin-filepath %s --stdin',
@@ -131,7 +131,7 @@ Execute(Should set --parser based on filetype, LESS):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser less'
\ . ' --stdin-filepath %s --stdin',
@@ -145,7 +145,7 @@ Execute(Should set --parser based on filetype, SCSS):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser scss'
\ . ' --stdin-filepath %s --stdin',
@@ -159,7 +159,7 @@ Execute(Should set --parser based on filetype, JSON):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser json'
\ . ' --stdin-filepath %s --stdin',
@@ -173,7 +173,7 @@ Execute(Should set --parser based on filetype, JSON5):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser json5'
\ . ' --stdin-filepath %s --stdin',
@@ -187,7 +187,7 @@ Execute(Should set --parser based on filetype, GraphQL):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser graphql'
\ . ' --stdin-filepath %s --stdin',
@@ -201,7 +201,7 @@ Execute(Should set --parser based on filetype, Markdown):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser markdown'
\ . ' --stdin-filepath %s --stdin',
@@ -215,7 +215,7 @@ Execute(Should set --parser based on filetype, Vue):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser vue'
\ . ' --stdin-filepath %s --stdin',
@@ -229,7 +229,7 @@ Execute(Should set --parser based on filetype, YAML):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser yaml'
\ . ' --stdin-filepath %s --stdin',
@@ -243,7 +243,7 @@ Execute(Should set --parser based on first filetype of multiple filetypes):
AssertEqual
\ {
- \ 'command': 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
+ \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser css'
\ . ' --stdin-filepath %s --stdin',
diff --git a/test/fixers/test_terraform_fmt_fixer_callback.vader b/test/fixers/test_terraform_fmt_fixer_callback.vader
new file mode 100644
index 00000000..15377a7e
--- /dev/null
+++ b/test/fixers/test_terraform_fmt_fixer_callback.vader
@@ -0,0 +1,34 @@
+Before:
+ Save g:ale_terraform_fmt_executable
+ Save g:ale_terraform_fmt_options
+
+ " Use an invalid global executable, so we don't match it.
+ let g:ale_terraform_fmt_executable = 'xxxinvalid'
+ let g:ale_terraform_fmt_options = ''
+
+ call ale#test#SetDirectory('/testplugin/test/fixers')
+
+After:
+ Restore
+
+ call ale#test#RestoreDirectory()
+
+Execute(The terraform fmt callback should return the correct default values):
+
+ AssertEqual
+ \ {
+ \ 'command': ale#Escape('xxxinvalid') . ' fmt -',
+ \ },
+ \ ale#fixers#terraform#Fix(bufnr(''))
+
+Execute(The terraform fmt callback should include custom options):
+ let g:ale_terraform_fmt_options = "-list=true"
+
+ AssertEqual
+ \ {
+ \ 'command': ale#Escape('xxxinvalid')
+ \ . ' fmt'
+ \ . ' ' . g:ale_terraform_fmt_options
+ \ . ' -',
+ \ },
+ \ ale#fixers#terraform#Fix(bufnr(''))
diff --git a/test/handler/test_credo_handler.vader b/test/handler/test_credo_handler.vader
index 5eb0e967..1fd54bb5 100644
--- a/test/handler/test_credo_handler.vader
+++ b/test/handler/test_credo_handler.vader
@@ -10,20 +10,44 @@ Execute(The credo handler should parse lines correctly):
\ {
\ 'bufnr': 347,
\ 'lnum': 1,
+ \ 'col': 24,
+ \ 'text': 'This code can be refactored',
+ \ 'type': 'W',
+ \ },
+ \ {
+ \ 'bufnr': 347,
+ \ 'lnum': 1,
\ 'col': 4,
\ 'text': 'There is no whitespace around parentheses/brackets most of the time, but here there is.',
- \ 'type': 'E',
+ \ 'type': 'W',
+ \ },
+ \ {
+ \ 'bufnr': 347,
+ \ 'lnum': 5,
+ \ 'col': 21,
+ \ 'text': 'TODO comment',
+ \ 'type': 'I',
\ },
\ {
\ 'bufnr': 347,
\ 'lnum': 26,
\ 'col': 0,
\ 'text': 'If/else blocks should not have a negated condition in `if`.',
+ \ 'type': 'I',
+ \ },
+ \ {
+ \ 'bufnr': 347,
+ \ 'lnum': 15,
+ \ 'col': 1,
+ \ 'text': 'Warning in the code',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#elixir#credo#Handle(347, [
\ 'This line should be ignored completely',
+ \ 'lib/my_code/test.ex:1:24: F: This code can be refactored',
\ 'lib/filename.ex:1:4: C: There is no whitespace around parentheses/brackets most of the time, but here there is.',
+ \ 'lib/my_code/test.ex:5:21: D: TODO comment',
\ 'lib/phoenix/channel.ex:26: R: If/else blocks should not have a negated condition in `if`.',
+ \ 'lib/my_code/test.ex:15:1: W: Warning in the code',
\ ])
diff --git a/test/handler/test_php_psalm_handler.vader b/test/handler/test_php_psalm_handler.vader
deleted file mode 100644
index fd62a467..00000000
--- a/test/handler/test_php_psalm_handler.vader
+++ /dev/null
@@ -1,24 +0,0 @@
-Before:
- runtime ale_linters/php/psalm.vim
-
-After:
- call ale#linter#Reset()
-
-Execute(The php static analyzer handler should parse errors from psalm):
- AssertEqual
- \ [
- \ {
- \ 'lnum': 1,
- \ 'type': 'W',
- \ 'text': 'somewarning',
- \ },
- \ {
- \ 'lnum': 11,
- \ 'type': 'E',
- \ 'text': 'someerror',
- \ },
- \ ],
- \ ale_linters#php#psalm#Handle(347, [
- \ "/file:1:3:warning - somewarning",
- \ "/file:11:33:error - someerror",
- \ ])
diff --git a/test/handler/test_pmd_handler.vader b/test/handler/test_pmd_handler.vader
index 0c95fb2a..4f64c9ca 100644
--- a/test/handler/test_pmd_handler.vader
+++ b/test/handler/test_pmd_handler.vader
@@ -25,3 +25,18 @@ Execute(The pmd handler should parse lines correctly):
\ '"1","rsb.performance.test.ros","/home/languitar/src/rsb-performance-test-api-ros/src/main/java/rsb/performance/test/ros/NodeHolder.java","3","18","Each class should declare at least one constructor","Code Style","AtLeastOneConstructor"',
\ '"2","rsb.performance.test.ros","/home/languitar/src/rsb-performance-test-api-ros/src/main/java/rsb/performance/test/ros/NodeHolder.java","1","36","Local variable ''node'' could be declared final","Code Style","LocalVariableCouldBeFinal"'
\ ])
+
+Execute(The pmd handler should parse lines correctly for java files that use unnamed packages):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 8,
+ \ 'text': 'Avoid unused local variables such as ''stest''.',
+ \ 'code': 'Best Practices - UnusedLocalVariable',
+ \ 'type': 'W',
+ \ },
+ \ ],
+ \ ale_linters#java#pmd#Handle(666, [
+ \ '"Problem","Package","File","Priority","Line","Description","Rule set","Rule"',
+ \ '"1","","/Users/diego/Projects/github.com/dlresende/kata-fizz-buzz/src/main/java/App.java","3","8","Avoid unused local variables such as ''stest''.","Best Practices","UnusedLocalVariable"'
+ \ ])
diff --git a/test/lsp/test_lsp_client_messages.vader b/test/lsp/test_lsp_client_messages.vader
index dc28c2e9..d4abaad9 100644
--- a/test/lsp/test_lsp_client_messages.vader
+++ b/test/lsp/test_lsp_client_messages.vader
@@ -175,6 +175,22 @@ Execute(ale#lsp#message#Hover() should return correct messages):
\ ],
\ ale#lsp#message#Hover(bufnr(''), 12, 34)
+Execute(ale#lsp#message#DidChangeConfiguration() should return correct messages):
+ let g:ale_lsp_configuration = {
+ \ 'foo': 'bar'
+ \ }
+ AssertEqual
+ \ [
+ \ 0,
+ \ 'workspace/didChangeConfiguration',
+ \ {
+ \ 'settings': {
+ \ 'foo': 'bar',
+ \ }
+ \ }
+ \ ],
+ \ ale#lsp#message#DidChangeConfiguration(bufnr(''), g:ale_lsp_configuration)
+
Execute(ale#lsp#tsserver_message#Open() should return correct messages):
AssertEqual
\ [
diff --git a/test/test_gradle_build_classpath_command.vader b/test/test_gradle_build_classpath_command.vader
index 3c1ecebe..491c2bf0 100644
--- a/test/test_gradle_build_classpath_command.vader
+++ b/test/test_gradle_build_classpath_command.vader
@@ -25,8 +25,8 @@ Execute(Should return 'gradlew' command if project includes gradle wapper):
call ale#test#SetFilename('gradle-test-files/wrapped-project/src/main/kotlin/dummy.kt')
AssertEqual
- \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/gradle-test-files/wrapped-project'))
- \ . ' && ' . ale#Escape(ale#path#Simplify(g:dir . '/gradle-test-files/wrapped-project/gradlew'))
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/gradle-test-files/wrapped-project'))
+ \ . ale#Escape(ale#path#Simplify(g:dir . '/gradle-test-files/wrapped-project/gradlew'))
\ . g:command_tail,
\ ale#gradle#BuildClasspathCommand(bufnr(''))
@@ -36,8 +36,8 @@ Execute(Should return 'gradle' command if project does not include gradle wapper
\ . ale#path#Simplify(g:dir . '/gradle-test-files')
AssertEqual
- \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/gradle-test-files/unwrapped-project'))
- \ . ' && ' . ale#Escape('gradle')
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/gradle-test-files/unwrapped-project'))
+ \ . ale#Escape('gradle')
\ . g:command_tail,
\ ale#gradle#BuildClasspathCommand(bufnr(''))
diff --git a/test/test_linter_defintion_processing.vader b/test/test_linter_defintion_processing.vader
index f0ec023a..a28edf9e 100644
--- a/test/test_linter_defintion_processing.vader
+++ b/test/test_linter_defintion_processing.vader
@@ -490,7 +490,7 @@ Execute(PreProcess should complain about using initialization_options and initia
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `initialization_options` or `initialization_options_callback` should be set', g:vader_exception
-Execute (PreProcess should throw when initialization_options_callback is not a callback):
+Execute(PreProcess should throw when initialization_options_callback is not a callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
@@ -500,3 +500,32 @@ Execute (PreProcess should throw when initialization_options_callback is not a c
\ 'initialization_options_callback': {},
\})
AssertEqual '`initialization_options_callback` must be a callback if defined', g:vader_exception
+
+Execute(PreProcess should accept LSP configuration options via lsp_config):
+ let g:ale_lsp_configuration = {
+ \ 'foo': 'bar'
+ \}
+
+ let g:linter = {
+ \ 'name': 'x',
+ \ 'lsp': 'socket',
+ \ 'address_callback': 'X',
+ \ 'language_callback': 'x',
+ \ 'project_root_callback': 'x',
+ \ 'lsp_config': g:ale_lsp_configuration,
+ \}
+
+ AssertEqual {'foo': 'bar'}, ale#linter#PreProcess('testft', g:linter).lsp_config
+
+
+Execute(PreProcess should throw when lsp_config is not a Dictionary):
+ AssertThrows call ale#linter#PreProcess('testft', {
+ \ 'name': 'foo',
+ \ 'lsp': 'socket',
+ \ 'address_callback': 'X',
+ \ 'language': 'x',
+ \ 'project_root_callback': 'x',
+ \ 'lsp_config': 'x',
+ \})
+ AssertEqual '`lsp_config` must be a Dictionary', g:vader_exception
+
diff --git a/test/util/test_cd_string_commands.vader b/test/util/test_cd_string_commands.vader
index 5f0e92fd..f2102e48 100644
--- a/test/util/test_cd_string_commands.vader
+++ b/test/util/test_cd_string_commands.vader
@@ -9,10 +9,12 @@ After:
Execute(CdString should output the correct command string):
" We will check that escaping is done correctly for each platform.
AssertEqual
- \ has('unix') ? 'cd ''/foo bar/baz'' && ' : 'cd "/foo bar/baz" && ',
+ \ has('unix') ? 'cd ''/foo bar/baz'' && ' : 'cd /d "/foo bar/baz" && ',
\ ale#path#CdString('/foo bar/baz')
Execute(BufferCdString should output the correct command string):
call ale#test#SetFilename('foo.txt')
- AssertEqual 'cd ' . ale#Escape(g:dir) . ' && ', ale#path#BufferCdString(bufnr(''))
+ AssertEqual
+ \ has('unix') ? 'cd ' . ale#Escape(g:dir) . ' && ' : 'cd /d ' . ale#Escape(g:dir) . ' && ',
+ \ ale#path#BufferCdString(bufnr(''))