summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/report-a-bug.md1
-rw-r--r--.github/ISSUE_TEMPLATE/suggest-a-new-linter-or-fixer.md1
-rw-r--r--.github/ISSUE_TEMPLATE/suggest-an-improvement.md1
-rw-r--r--LICENSE2
-rw-r--r--README.md11
-rw-r--r--ale_linters/bats/shellcheck.vim4
-rw-r--r--ale_linters/c/ccls.vim3
-rw-r--r--ale_linters/c/cppcheck.vim2
-rw-r--r--ale_linters/clojure/clj_kondo.vim2
-rw-r--r--ale_linters/cpp/ccls.vim3
-rw-r--r--ale_linters/cpp/cppcheck.vim2
-rw-r--r--ale_linters/dockerfile/dockerfile_lint.vim17
-rw-r--r--ale_linters/go/revive.vim21
-rw-r--r--ale_linters/graphql/eslint.vim2
-rw-r--r--ale_linters/java/checkstyle.vim2
-rw-r--r--ale_linters/java/eclipselsp.vim41
-rw-r--r--ale_linters/java/javac.vim35
-rw-r--r--ale_linters/javascript/standard.vim1
-rw-r--r--ale_linters/kotlin/kotlinc.vim1
-rw-r--r--ale_linters/kotlin/ktlint.vim2
-rw-r--r--ale_linters/objc/ccls.vim3
-rw-r--r--ale_linters/powershell/powershell.vim1
-rw-r--r--ale_linters/puppet/puppet.vim8
-rw-r--r--ale_linters/python/mypy.vim23
-rw-r--r--ale_linters/python/pyright.vim43
-rw-r--r--ale_linters/rust/analyzer.vim24
-rw-r--r--ale_linters/scala/metals.vim2
-rw-r--r--ale_linters/sh/bashate.vim43
-rw-r--r--ale_linters/sh/shellcheck.vim107
-rw-r--r--ale_linters/terraform/terraform_lsp.vim25
-rw-r--r--ale_linters/typescript/standard.vim31
-rw-r--r--ale_linters/verilog/hdl_checker.vim5
-rw-r--r--ale_linters/verilog/verilator.vim27
-rw-r--r--ale_linters/vhdl/hdl_checker.vim5
-rw-r--r--ale_linters/vim/vimls.vim61
-rw-r--r--ale_linters/zig/zls.vim20
-rw-r--r--autoload/ale.vim4
-rw-r--r--autoload/ale/ant.vim2
-rw-r--r--autoload/ale/code_action.vim20
-rw-r--r--autoload/ale/completion.vim210
-rw-r--r--autoload/ale/definition.vim39
-rw-r--r--autoload/ale/events.vim4
-rw-r--r--autoload/ale/fix.vim29
-rw-r--r--autoload/ale/fix/registry.vim10
-rw-r--r--autoload/ale/fixers/astyle.vim59
-rw-r--r--autoload/ale/fixers/eslint.vim9
-rw-r--r--autoload/ale/fixers/ktlint.vim3
-rw-r--r--autoload/ale/fixers/nimpretty.vim15
-rw-r--r--autoload/ale/fixers/standard.vim10
-rw-r--r--autoload/ale/fixers/tslint.vim2
-rw-r--r--autoload/ale/handlers/ccls.vim7
-rw-r--r--autoload/ale/handlers/cppcheck.vim15
-rw-r--r--autoload/ale/handlers/eslint.vim51
-rw-r--r--autoload/ale/handlers/go.vim5
-rw-r--r--autoload/ale/handlers/hdl_checker.vim71
-rw-r--r--autoload/ale/handlers/ktlint.vim2
-rw-r--r--autoload/ale/handlers/markdownlint.vim13
-rw-r--r--autoload/ale/handlers/shellcheck.vim107
-rw-r--r--autoload/ale/highlight.vim6
-rw-r--r--autoload/ale/hover.vim28
-rw-r--r--autoload/ale/linter.vim2
-rw-r--r--autoload/ale/lsp.vim24
-rw-r--r--autoload/ale/node.vim14
-rw-r--r--autoload/ale/organize_imports.vim2
-rw-r--r--autoload/ale/preview.vim37
-rw-r--r--autoload/ale/references.vim19
-rw-r--r--autoload/ale/rename.vim37
-rw-r--r--autoload/ale/sign.vim2
-rw-r--r--autoload/ale/util.vim61
-rw-r--r--doc/ale-bats.txt13
-rw-r--r--doc/ale-c.txt24
-rw-r--r--doc/ale-cloudformation.txt36
-rw-r--r--doc/ale-cpp.txt24
-rw-r--r--doc/ale-go.txt19
-rw-r--r--doc/ale-java.txt63
-rw-r--r--doc/ale-javascript.txt2
-rw-r--r--doc/ale-nim.txt20
-rw-r--r--doc/ale-python.txt90
-rw-r--r--doc/ale-rust.txt28
-rw-r--r--doc/ale-sh.txt23
-rw-r--r--doc/ale-supported-languages-and-tools.txt14
-rw-r--r--doc/ale-terraform.txt19
-rw-r--r--doc/ale-typescript.txt27
-rw-r--r--doc/ale-verilog.txt18
-rw-r--r--doc/ale-vhdl.txt75
-rw-r--r--doc/ale-vim.txt55
-rw-r--r--doc/ale-zig.txt33
-rw-r--r--doc/ale.txt304
-rw-r--r--ftplugin/ale-preview-selection.vim2
-rw-r--r--plugin/ale.vim47
-rw-r--r--rplugin/python3/deoplete/sources/ale.py22
-rw-r--r--supported-tools.md14
-rw-r--r--test/command_callback/ccls_paths/with_build_dir/unusual_build_dir_name/compile_commands.json0
-rw-r--r--test/command_callback/hdl_server/foo.vhd0
-rw-r--r--test/command_callback/hdl_server/with_config_file/.hdl_checker.config0
-rw-r--r--test/command_callback/hdl_server/with_config_file/_hdl_checker.config0
-rw-r--r--test/command_callback/hdl_server/with_config_file/foo.vhd0
-rw-r--r--test/command_callback/hdl_server/with_git/files/foo.vhd1
-rw-r--r--test/command_callback/java_paths/build/gen/main/java/com/something/dummy0
-rw-r--r--test/command_callback/java_paths/build/gen2/main/java/com/something/dummy0
-rw-r--r--test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/mypy.ini0
-rw-r--r--test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/tests/pytest.ini0
-rw-r--r--test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py0
-rw-r--r--test/command_callback/test_bashate_command_callback.vader15
-rw-r--r--test/command_callback/test_c_ccls_command_callbacks.vader20
-rw-r--r--test/command_callback/test_c_cppcheck_command_callbacks.vader10
-rw-r--r--test/command_callback/test_checkstyle_command_callback.vader4
-rw-r--r--test/command_callback/test_cpp_ccls_command_callbacks.vader20
-rw-r--r--test/command_callback/test_cpp_cppcheck_command_callbacks.vader6
-rw-r--r--test/command_callback/test_eclipselsp_command_callback.vader7
-rw-r--r--test/command_callback/test_gopls_command_callback.vader5
-rw-r--r--test/command_callback/test_javac_command_callback.vader141
-rw-r--r--test/command_callback/test_mypy_command_callback.vader9
-rw-r--r--test/command_callback/test_objc_ccls_command_callbacks.vader20
-rw-r--r--test/command_callback/test_pyright_command_callback.vader116
-rw-r--r--test/command_callback/test_revive_command_callbacks.vader30
-rw-r--r--test/command_callback/test_rust_analyzer_callbacks.vader20
-rw-r--r--test/command_callback/test_standardts_command_callback.vader43
-rw-r--r--test/command_callback/test_terraform_lsp_command_callback.vader48
-rw-r--r--test/command_callback/test_vim_vimls.vader76
-rw-r--r--test/command_callback/test_zig_zls_callbacks.vader15
-rw-r--r--test/command_callback/vim_fixtures/invalid_vim_project/test.vim0
-rw-r--r--test/command_callback/vim_fixtures/node_modules/.bin/vim-language-server0
-rw-r--r--test/command_callback/vim_fixtures/path_with_autoload/autoload/test.vim0
-rw-r--r--test/command_callback/vim_fixtures/path_with_autoload/test.vim0
-rw-r--r--test/command_callback/vim_fixtures/path_with_initvim/init.vim0
-rw-r--r--test/command_callback/vim_fixtures/path_with_plugin/plugin/test.vim0
-rw-r--r--test/command_callback/vim_fixtures/path_with_plugin/test.vim0
-rw-r--r--test/command_callback/vim_fixtures/path_with_vimrc/.vimrc0
-rw-r--r--test/command_callback/zig-zls-project/build.zig0
-rw-r--r--test/completion/test_completion_events.vader9
-rw-r--r--test/completion/test_lsp_completion_parsing.vader90
-rw-r--r--test/completion/test_public_completion_api.vader1
-rw-r--r--test/completion/test_tsserver_completion_parsing.vader10
-rw-r--r--test/eslint-test-files/react-app/subdir-with-package-json/node_modules/.gitkeep0
-rw-r--r--test/fixers/test_astyle_fixer_callback.vader96
-rw-r--r--test/fixers/test_eslint_fixer_callback.vader44
-rw-r--r--test/fixers/test_ktlint_fixer_callback.vader6
-rw-r--r--test/fixers/test_nimpretty_fixer_callback.vader23
-rw-r--r--test/fixers/test_tslint_fixer_callback.vader4
-rw-r--r--test/handler/test_bashate_handler.vader36
-rw-r--r--test/handler/test_cppcheck_handler.vader26
-rw-r--r--test/handler/test_dockerfile_lint_handler.vader6
-rw-r--r--test/handler/test_eslint_json_handler.vader20
-rw-r--r--test/handler/test_go_generic_handler.vader16
-rw-r--r--test/handler/test_markdownlint_handler.vader81
-rw-r--r--test/handler/test_mypy_handler.vader29
-rw-r--r--test/handler/test_puppet_handler.vader26
-rw-r--r--test/handler/test_shellcheck_handler.vader4
-rw-r--r--test/handler/test_verilator_handler.vader48
-rw-r--r--test/lsp/test_other_initialize_message_handling.vader53
-rw-r--r--test/python/test_deoplete_source.py72
-rw-r--r--test/sign/test_linting_sets_signs.vader2
-rw-r--r--test/sign/test_sign_parsing.vader14
-rw-r--r--test/sign/test_sign_placement.vader6
-rw-r--r--test/terraform_files/main.tf0
-rw-r--r--test/test_ale_has.vader1
-rw-r--r--test/test_autocmd_commands.vader28
-rw-r--r--test/test_c_projects/makefile_project/_astylerc0
-rw-r--r--test/test_code_action.vader48
-rw-r--r--test/test_cpp_project/.astylerc0
-rw-r--r--test/test_cpp_project/dummy.cpp0
-rw-r--r--test/test_cursor_warnings.vader14
-rw-r--r--test/test_eslint_executable_detection.vader35
-rw-r--r--test/test_filetype_linter_defaults.vader4
-rw-r--r--test/test_find_references.vader68
-rw-r--r--test/test_go_to_definition.vader38
-rw-r--r--test/test_hdl_checker_options.vader78
-rw-r--r--test/test_highlight_placement.vader21
-rw-r--r--test/test_hover.vader7
-rw-r--r--test/test_organize_imports.vader3
-rw-r--r--test/test_rename.vader112
-rw-r--r--test/test_shell_detection.vader28
173 files changed, 3677 insertions, 609 deletions
diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md
index 6d345c4a..4169029d 100644
--- a/.github/ISSUE_TEMPLATE/report-a-bug.md
+++ b/.github/ISSUE_TEMPLATE/report-a-bug.md
@@ -1,5 +1,6 @@
---
name: Report a bug
+labels: bug
about: Report a bug with ALE.
---
diff --git a/.github/ISSUE_TEMPLATE/suggest-a-new-linter-or-fixer.md b/.github/ISSUE_TEMPLATE/suggest-a-new-linter-or-fixer.md
index 75c7637f..ad235e57 100644
--- a/.github/ISSUE_TEMPLATE/suggest-a-new-linter-or-fixer.md
+++ b/.github/ISSUE_TEMPLATE/suggest-a-new-linter-or-fixer.md
@@ -1,5 +1,6 @@
---
name: Suggest a new linter or fixer
+labels: new tool
about: Suggest a new tool ALE can officially integrate with.
---
diff --git a/.github/ISSUE_TEMPLATE/suggest-an-improvement.md b/.github/ISSUE_TEMPLATE/suggest-an-improvement.md
index 855a6493..d39d0ac8 100644
--- a/.github/ISSUE_TEMPLATE/suggest-an-improvement.md
+++ b/.github/ISSUE_TEMPLATE/suggest-an-improvement.md
@@ -1,5 +1,6 @@
---
name: Suggest an improvement
+labels: enhancement
about: Suggest some way to improve ALE, or add a new feature.
---
diff --git a/LICENSE b/LICENSE
index f8f3524d..471776e4 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2016-2019, w0rp <devw0rp@gmail.com>
+Copyright (c) 2016-2020, w0rp <devw0rp@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index 1488d756..dcc4ed38 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,10 @@ 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.
+**Help Wanted:** If you would like to help maintain this plugin by managing the
+many issues and pull requests that are submitted, please send the author an
+email at [dev@w0rp.com](mailto:dev@w0rp.com?subject=Helping%20with%20ALE).
+
If you enjoy this plugin, feel free to contribute or check out the author's
other content at [w0rp.com](https://w0rp.com).
@@ -98,7 +102,7 @@ programs for checking the syntax and semantics of your programs. By default,
linters will be re-run in the background to check your syntax when you open
new buffers or as you make edits to your files.
-The behaviour of linting can be configured with a variety of options,
+The behavior of linting can be configured with a variety of options,
documented in [the Vim help file](doc/ale.txt). For more information on the
options ALE offers, consult `:help ale-options` for global options and `:help
ale-integration-options` for options specified to particular linters.
@@ -227,6 +231,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.
+Truncated information will be displayed when the cursor rests on a symbol by
+default, as long as there are no problems on the same line.
+
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.
@@ -731,7 +738,7 @@ while you type. ALE uses a timeout which is cancelled and reset every time you
type, and this delay can be increased so linters are run less often. See
`:help g:ale_lint_delay` for more information.
-If you don't wish to run linters while you type, you can disable that behaviour.
+If you don't wish to run linters while you type, you can disable that behavior.
Set `g:ale_lint_on_text_changed` to `never`. You won't get as frequent error
checking, but ALE shouldn't block your ability to edit a document after you save
a file, so the asynchronous nature of the plugin will still be an advantage.
diff --git a/ale_linters/bats/shellcheck.vim b/ale_linters/bats/shellcheck.vim
new file mode 100644
index 00000000..5c2a0ea9
--- /dev/null
+++ b/ale_linters/bats/shellcheck.vim
@@ -0,0 +1,4 @@
+" Author: Ian2020 <https://github.com/Ian2020>
+" Description: shellcheck linter for bats scripts.
+
+call ale#handlers#shellcheck#DefineLinter('bats')
diff --git a/ale_linters/c/ccls.vim b/ale_linters/c/ccls.vim
index 9e3dafe9..9f105712 100644
--- a/ale_linters/c/ccls.vim
+++ b/ale_linters/c/ccls.vim
@@ -3,6 +3,7 @@
call ale#Set('c_ccls_executable', 'ccls')
call ale#Set('c_ccls_init_options', {})
+call ale#Set('c_build_dir', '')
call ale#linter#Define('c', {
\ 'name': 'ccls',
@@ -10,5 +11,5 @@ call ale#linter#Define('c', {
\ 'executable': {b -> ale#Var(b, 'c_ccls_executable')},
\ 'command': '%e',
\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'),
-\ 'initialization_options': {b -> ale#Var(b, 'c_ccls_init_options')},
+\ 'initialization_options': {b -> ale#handlers#ccls#GetInitOpts(b, 'c_ccls_init_options')},
\})
diff --git a/ale_linters/c/cppcheck.vim b/ale_linters/c/cppcheck.vim
index 309b2851..b671fc8b 100644
--- a/ale_linters/c/cppcheck.vim
+++ b/ale_linters/c/cppcheck.vim
@@ -10,9 +10,11 @@ function! ale_linters#c#cppcheck#GetCommand(buffer) abort
let l:buffer_path_include = empty(l:compile_commands_option)
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : ''
+ let l:template = ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
return l:cd_command
\ . '%e -q --language=c'
+ \ . l:template
\ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options'))
\ . l:buffer_path_include
diff --git a/ale_linters/clojure/clj_kondo.vim b/ale_linters/clojure/clj_kondo.vim
index 5dd11c12..eb60ce77 100644
--- a/ale_linters/clojure/clj_kondo.vim
+++ b/ale_linters/clojure/clj_kondo.vim
@@ -29,6 +29,6 @@ call ale#linter#Define('clojure', {
\ 'name': 'clj-kondo',
\ 'output_stream': 'stdout',
\ 'executable': 'clj-kondo',
-\ 'command': 'clj-kondo --lint %t',
+\ 'command': 'clj-kondo --cache --lint %t',
\ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat',
\})
diff --git a/ale_linters/cpp/ccls.vim b/ale_linters/cpp/ccls.vim
index b265ff70..38f8df9c 100644
--- a/ale_linters/cpp/ccls.vim
+++ b/ale_linters/cpp/ccls.vim
@@ -3,6 +3,7 @@
call ale#Set('cpp_ccls_executable', 'ccls')
call ale#Set('cpp_ccls_init_options', {})
+call ale#Set('c_build_dir', '')
call ale#linter#Define('cpp', {
\ 'name': 'ccls',
@@ -10,5 +11,5 @@ call ale#linter#Define('cpp', {
\ 'executable': {b -> ale#Var(b, 'cpp_ccls_executable')},
\ 'command': '%e',
\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'),
-\ 'initialization_options': {b -> ale#Var(b, 'cpp_ccls_init_options')},
+\ 'initialization_options': {b -> ale#handlers#ccls#GetInitOpts(b, 'cpp_ccls_init_options')},
\})
diff --git a/ale_linters/cpp/cppcheck.vim b/ale_linters/cpp/cppcheck.vim
index 7cd80dbc..2c832246 100644
--- a/ale_linters/cpp/cppcheck.vim
+++ b/ale_linters/cpp/cppcheck.vim
@@ -10,9 +10,11 @@ function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
let l:buffer_path_include = empty(l:compile_commands_option)
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : ''
+ let l:template = ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
return l:cd_command
\ . '%e -q --language=c++'
+ \ . l:template
\ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options'))
\ . l:buffer_path_include
diff --git a/ale_linters/dockerfile/dockerfile_lint.vim b/ale_linters/dockerfile/dockerfile_lint.vim
index 95768b12..0c0ad533 100644
--- a/ale_linters/dockerfile/dockerfile_lint.vim
+++ b/ale_linters/dockerfile/dockerfile_lint.vim
@@ -32,14 +32,29 @@ function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort
let l:line = get(l:object, 'line', -1)
let l:message = l:object['message']
+ let l:link = get(l:object, 'reference_url', '')
+
+ if type(l:link) == v:t_list
+ " Somehow, reference_url is returned as two-part list.
+ " Anchor markers in that list are sometimes duplicated.
+ " See https://github.com/projectatomic/dockerfile_lint/issues/134
+ let l:link = join(l:link, '')
+ let l:link = substitute(l:link, '##', '#', '')
+ endif
+
+ let l:detail = l:message
+
if get(l:object, 'description', 'None') isnot# 'None'
- let l:message = l:message . '. ' . l:object['description']
+ let l:detail .= "\n\n" . l:object['description']
endif
+ let l:detail .= "\n\n" . l:link
+
call add(l:messages, {
\ 'lnum': l:line,
\ 'text': l:message,
\ 'type': ale_linters#dockerfile#dockerfile_lint#GetType(l:type),
+ \ 'detail': l:detail,
\})
endfor
endfor
diff --git a/ale_linters/go/revive.vim b/ale_linters/go/revive.vim
new file mode 100644
index 00000000..b14b5ab9
--- /dev/null
+++ b/ale_linters/go/revive.vim
@@ -0,0 +1,21 @@
+" Author: Penghui Liao <liaoishere@gmail.com>
+" Description: Adds support for revive
+
+call ale#Set('go_revive_executable', 'revive')
+call ale#Set('go_revive_options', '')
+
+function! ale_linters#go#revive#GetCommand(buffer) abort
+ let l:options = ale#Var(a:buffer, 'go_revive_options')
+
+ return ale#go#EnvString(a:buffer) . '%e'
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . ' %t'
+endfunction
+
+call ale#linter#Define('go', {
+\ 'name': 'revive',
+\ 'output_stream': 'both',
+\ 'executable': {b -> ale#Var(b, 'go_revive_executable')},
+\ 'command': function('ale_linters#go#revive#GetCommand'),
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/ale_linters/graphql/eslint.vim b/ale_linters/graphql/eslint.vim
index 654b8c17..aed1a371 100644
--- a/ale_linters/graphql/eslint.vim
+++ b/ale_linters/graphql/eslint.vim
@@ -5,5 +5,5 @@ call ale#linter#Define('graphql', {
\ 'name': 'eslint',
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'command': function('ale#handlers#eslint#GetCommand'),
-\ 'callback': 'ale#handlers#eslint#Handle',
+\ 'callback': 'ale#handlers#eslint#HandleJSON',
\})
diff --git a/ale_linters/java/checkstyle.vim b/ale_linters/java/checkstyle.vim
index 7901ff7e..ec7339d1 100644
--- a/ale_linters/java/checkstyle.vim
+++ b/ale_linters/java/checkstyle.vim
@@ -52,7 +52,7 @@ endfunction
function! ale_linters#java#checkstyle#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'java_checkstyle_options')
let l:config_option = ale#Var(a:buffer, 'java_checkstyle_config')
- let l:config = l:options !~# '\v(^| )-c' && !empty(l:config_option)
+ let l:config = l:options !~# '\v(^| )-c ' && !empty(l:config_option)
\ ? s:GetConfig(a:buffer, l:config_option)
\ : ''
diff --git a/ale_linters/java/eclipselsp.vim b/ale_linters/java/eclipselsp.vim
index 2648893b..c981b749 100644
--- a/ale_linters/java/eclipselsp.vim
+++ b/ale_linters/java/eclipselsp.vim
@@ -7,6 +7,7 @@ call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls'
call ale#Set('java_eclipselsp_config_path', '')
call ale#Set('java_eclipselsp_workspace_path', '')
call ale#Set('java_eclipselsp_executable', 'java')
+call ale#Set('java_eclipselsp_javaagent', '')
function! ale_linters#java#eclipselsp#Executable(buffer) abort
return ale#Var(a:buffer, 'java_eclipselsp_executable')
@@ -19,25 +20,32 @@ endfunction
function! ale_linters#java#eclipselsp#JarPath(buffer) abort
let l:path = ale_linters#java#eclipselsp#TargetPath(a:buffer)
+ if has('win32')
+ let l:platform = 'win32'
+ elseif has('macunix')
+ let l:platform = 'macosx'
+ else
+ let l:platform = 'linux'
+ endif
+
" Search jar file within repository path when manually built using mvn
- let l:repo_path = l:path . '/org.eclipse.jdt.ls.product/target/repository'
- let l:files = globpath(l:repo_path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
+ let l:files = globpath(l:path, '**/'.l:platform.'/**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
- if len(l:files) == 1
+ if len(l:files) > 1
return l:files[0]
endif
" Search jar file within VSCode extensions folder.
- let l:files = globpath(l:path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
+ let l:files = globpath(l:path, '**/'.l:platform.'/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
- if len(l:files) == 1
+ if len(l:files) > 1
return l:files[0]
endif
" Search jar file within system package path
let l:files = globpath('/usr/share/java/jdtls/plugins', 'org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
- if len(l:files) == 1
+ if len(l:files) > 1
return l:files[0]
endif
@@ -100,12 +108,30 @@ function! ale_linters#java#eclipselsp#WorkspacePath(buffer) abort
return ale#path#Dirname(ale#java#FindProjectRoot(a:buffer))
endfunction
+function! ale_linters#java#eclipselsp#Javaagent(buffer) abort
+ let l:rets = []
+ let l:raw = ale#Var(a:buffer, 'java_eclipselsp_javaagent')
+
+ if empty(l:raw)
+ return ''
+ endif
+
+ let l:jars = split(l:raw)
+
+ for l:jar in l:jars
+ call add(l:rets, ale#Escape('-javaagent:' . l:jar))
+ endfor
+
+ return join(l:rets, ' ')
+endfunction
+
function! ale_linters#java#eclipselsp#Command(buffer, version) abort
let l:path = ale#Var(a:buffer, 'java_eclipselsp_path')
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
let l:cmd = [ ale#Escape(l:executable),
+ \ ale_linters#java#eclipselsp#Javaagent(a:buffer),
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
@@ -147,7 +173,8 @@ function! ale_linters#java#eclipselsp#RunWithVersionCheck(buffer) abort
return ale#command#Run(
\ a:buffer,
\ l:command,
- \ function('ale_linters#java#eclipselsp#CommandWithVersion')
+ \ function('ale_linters#java#eclipselsp#CommandWithVersion'),
+ \ { 'output_stream': 'both' }
\)
endfunction
diff --git a/ale_linters/java/javac.vim b/ale_linters/java/javac.vim
index 8bb52c0b..f866eb09 100644
--- a/ale_linters/java/javac.vim
+++ b/ale_linters/java/javac.vim
@@ -6,6 +6,7 @@ let s:classpath_sep = has('unix') ? ':' : ';'
call ale#Set('java_javac_executable', 'javac')
call ale#Set('java_javac_options', '')
call ale#Set('java_javac_classpath', '')
+call ale#Set('java_javac_sourcepath', '')
function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
let l:command = ''
@@ -40,10 +41,15 @@ endfunction
function! s:BuildClassPathOption(buffer, import_paths) abort
" Filter out lines like [INFO], etc.
let l:class_paths = filter(a:import_paths[:], 'v:val !~# ''[''')
- call extend(
- \ l:class_paths,
- \ split(ale#Var(a:buffer, 'java_javac_classpath'), s:classpath_sep),
- \)
+ let l:cls_path = ale#Var(a:buffer, 'java_javac_classpath')
+
+ if !empty(l:cls_path) && type(l:cls_path) is v:t_string
+ call extend(l:class_paths, split(l:cls_path, s:classpath_sep))
+ endif
+
+ if !empty(l:cls_path) && type(l:cls_path) is v:t_list
+ call extend(l:class_paths, l:cls_path)
+ endif
return !empty(l:class_paths)
\ ? '-cp ' . ale#Escape(join(l:class_paths, s:classpath_sep))
@@ -79,6 +85,27 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths, meta) abort
endif
endif
+ let l:source_paths = []
+ let l:source_path = ale#Var(a:buffer, 'java_javac_sourcepath')
+
+ if !empty(l:source_path) && type(l:source_path) is v:t_string
+ let l:source_paths = split(l:source_path, s:classpath_sep)
+ endif
+
+ if !empty(l:source_path) && type(l:source_path) is v:t_list
+ let l:source_paths = l:source_path
+ endif
+
+ if !empty(l:source_paths)
+ for l:path in l:source_paths
+ let l:sp_path = ale#path#FindNearestDirectory(a:buffer, l:path)
+
+ if !empty(l:sp_path)
+ call add(l:sp_dirs, l:sp_path)
+ endif
+ endfor
+ endif
+
if !empty(l:sp_dirs)
let l:sp_option = '-sourcepath '
\ . ale#Escape(join(l:sp_dirs, s:classpath_sep))
diff --git a/ale_linters/javascript/standard.vim b/ale_linters/javascript/standard.vim
index 203a803e..1990adce 100644
--- a/ale_linters/javascript/standard.vim
+++ b/ale_linters/javascript/standard.vim
@@ -7,6 +7,7 @@ call ale#Set('javascript_standard_options', '')
function! ale_linters#javascript#standard#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
+ \ 'node_modules/standardx/bin/cmd.js',
\ 'node_modules/standard/bin/cmd.js',
\ 'node_modules/semistandard/bin/cmd.js',
\ 'node_modules/.bin/standard',
diff --git a/ale_linters/kotlin/kotlinc.vim b/ale_linters/kotlin/kotlinc.vim
index 3c6854fa..66c075be 100644
--- a/ale_linters/kotlin/kotlinc.vim
+++ b/ale_linters/kotlin/kotlinc.vim
@@ -174,6 +174,7 @@ endfunction
call ale#linter#Define('kotlin', {
\ 'name': 'kotlinc',
\ 'executable': 'kotlinc',
+\ 'output_stream': 'stderr',
\ 'command': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'),
\ 'callback': 'ale_linters#kotlin#kotlinc#Handle',
\ 'lint_file': 1,
diff --git a/ale_linters/kotlin/ktlint.vim b/ale_linters/kotlin/ktlint.vim
index f0384005..0bb64b19 100644
--- a/ale_linters/kotlin/ktlint.vim
+++ b/ale_linters/kotlin/ktlint.vim
@@ -6,5 +6,5 @@ call ale#linter#Define('kotlin', {
\ 'executable': 'ktlint',
\ 'command': function('ale#handlers#ktlint#GetCommand'),
\ 'callback': 'ale#handlers#ktlint#Handle',
-\ 'lint_file': 1
+\ 'output_stream': 'stderr'
\})
diff --git a/ale_linters/objc/ccls.vim b/ale_linters/objc/ccls.vim
index 51ecf056..7aef5325 100644
--- a/ale_linters/objc/ccls.vim
+++ b/ale_linters/objc/ccls.vim
@@ -3,6 +3,7 @@
call ale#Set('objc_ccls_executable', 'ccls')
call ale#Set('objc_ccls_init_options', {})
+call ale#Set('c_build_dir', '')
call ale#linter#Define('objc', {
\ 'name': 'ccls',
@@ -10,5 +11,5 @@ call ale#linter#Define('objc', {
\ 'executable': {b -> ale#Var(b, 'objc_ccls_executable')},
\ 'command': '%e',
\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'),
-\ 'initialization_options': {b -> ale#Var(b, 'objc_ccls_init_options')},
+\ 'initialization_options': {b -> ale#handlers#ccls#GetInitOpts(b, 'objc_ccls_init_options')},
\})
diff --git a/ale_linters/powershell/powershell.vim b/ale_linters/powershell/powershell.vim
index a63191fd..5f49f72c 100644
--- a/ale_linters/powershell/powershell.vim
+++ b/ale_linters/powershell/powershell.vim
@@ -12,6 +12,7 @@ endfunction
" https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/
function! ale_linters#powershell#powershell#GetCommand(buffer) abort
let l:script = ['Param($Script);
+ \ $ErrorView = "Normal";
\ trap {$_;continue} & {
\ $Contents = Get-Content -Path $Script;
\ $Contents = [string]::Join([Environment]::NewLine, $Contents);
diff --git a/ale_linters/puppet/puppet.vim b/ale_linters/puppet/puppet.vim
index ae648615..59228dc8 100644
--- a/ale_linters/puppet/puppet.vim
+++ b/ale_linters/puppet/puppet.vim
@@ -8,13 +8,15 @@ function! ale_linters#puppet#puppet#Handle(buffer, lines) abort
" Error: Could not parse for environment production: Syntax error at ':' at /root/puppetcode/modules/nginx/manifests/init.pp:43:12
" Error: Could not parse for environment production: Syntax error at '='; expected '}' at /root/puppetcode/modules/pancakes/manifests/init.pp:5"
" Error: Could not parse for environment production: Syntax error at 'parameter1' (file: /tmp/modules/mariadb/manifests/slave.pp, line: 4, column: 5)
- let l:pattern = '^Error: .*: \(.\+\) \((file:\|at\) .\+\.pp\(, line: \|:\)\(\d\+\)\(, column: \|:\)\=\(\d*\)'
+ " Error: Illegal attempt to assign to 'a Name'. Not an assignable reference (file: /tmp/modules/waffles/manifests/syrup.pp, line: 5, column: 11)
+ " Error: Could not parse for environment production: Syntax error at end of input (file: /tmp/modules/bob/manifests/init.pp)
+ let l:pattern = '^Error:\%(.*:\)\? \(.\+\) \((file:\|at\) .\+\.pp\(\(, line: \|:\)\(\d\+\)\(, column: \|:\)\=\(\d*\)\|)$\)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
- \ 'lnum': l:match[4] + 0,
- \ 'col': l:match[6] + 0,
+ \ 'lnum': l:match[5] + 0,
+ \ 'col': l:match[7] + 0,
\ 'text': l:match[1],
\})
endfor
diff --git a/ale_linters/python/mypy.vim b/ale_linters/python/mypy.vim
index dc4044e6..94dfae7d 100644
--- a/ale_linters/python/mypy.vim
+++ b/ale_linters/python/mypy.vim
@@ -3,6 +3,7 @@
call ale#Set('python_mypy_executable', 'mypy')
call ale#Set('python_mypy_ignore_invalid_syntax', 0)
+call ale#Set('python_mypy_show_notes', 1)
call ale#Set('python_mypy_options', '')
call ale#Set('python_mypy_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_mypy_auto_pipenv', 0)
@@ -18,6 +19,15 @@ endfunction
" The directory to change to before running mypy
function! s:GetDir(buffer) abort
+ " If we find a directory with "mypy.ini" in it use that,
+ " else try and find the "python project" root, or failing
+ " that, run from the same folder as the current file
+ for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
+ if filereadable(l:path . '/mypy.ini')
+ return l:path
+ endif
+ endfor
+
let l:project_root = ale#python#FindProjectRoot(a:buffer)
return !empty(l:project_root)
@@ -51,7 +61,16 @@ function! ale_linters#python#mypy#Handle(buffer, lines) abort
" Lines like these should be ignored below:
"
" file.py:4: note: (Stub files are from https://github.com/python/typeshed)
- let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: (error|warning): (.+)$'
+
+ let l:types = 'error|warning'
+
+ if ale#Var(a:buffer, 'python_mypy_show_notes')
+ let l:types = 'error|warning|note'
+ endif
+
+ let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: ('
+ \ . l:types
+ \ . '): (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
@@ -65,7 +84,7 @@ function! ale_linters#python#mypy#Handle(buffer, lines) abort
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
- \ 'type': l:match[4] is# 'error' ? 'E' : 'W',
+ \ 'type': l:match[4] is# 'error' ? 'E' : (l:match[4] is# 'note' ? 'I': 'W'),
\ 'text': l:match[5],
\})
endfor
diff --git a/ale_linters/python/pyright.vim b/ale_linters/python/pyright.vim
new file mode 100644
index 00000000..422ecd61
--- /dev/null
+++ b/ale_linters/python/pyright.vim
@@ -0,0 +1,43 @@
+call ale#Set('python_pyright_executable', 'pyright-langserver')
+call ale#Set('python_pyright_config', {})
+
+function! ale_linters#python#pyright#GetConfig(buffer) abort
+ let l:config = deepcopy(ale#Var(a:buffer, 'python_pyright_config'))
+
+ if !has_key(l:config, 'python')
+ let l:config.python = {}
+ endif
+
+ if type(l:config.python) is v:t_dict
+ " Automatically detect the virtualenv path and use it.
+ if !has_key(l:config.python, 'venvPath')
+ let l:venv = ale#python#FindVirtualenv(a:buffer)
+
+ if !empty(l:venv)
+ let l:config.python.venvPath = l:venv
+ endif
+ endif
+
+ " Automatically use the version of Python in virtualenv.
+ if type(get(l:config.python, 'venvPath')) is v:t_string
+ \&& !empty(l:config.python.venvPath)
+ \&& !has_key(l:config.python, 'pythonPath')
+ let l:config.python.pythonPath = ale#path#Simplify(
+ \ l:config.python.venvPath
+ \ . (has('win32') ? '/Scripts/python' : '/bin/python')
+ \)
+ endif
+ endif
+
+ return l:config
+endfunction
+
+call ale#linter#Define('python', {
+\ 'name': 'pyright',
+\ 'lsp': 'stdio',
+\ 'executable': {b -> ale#Var(b, 'python_pyright_executable')},
+\ 'command': '%e --stdio',
+\ 'project_root': function('ale#python#FindProjectRoot'),
+\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
+\ 'lsp_config': function('ale_linters#python#pyright#GetConfig'),
+\})
diff --git a/ale_linters/rust/analyzer.vim b/ale_linters/rust/analyzer.vim
new file mode 100644
index 00000000..3666ec03
--- /dev/null
+++ b/ale_linters/rust/analyzer.vim
@@ -0,0 +1,24 @@
+" Author: Jon Gjengset <jon@thesquareplanet.com>
+" Description: The next generation language server for Rust
+
+call ale#Set('rust_analyzer_executable', 'rust-analyzer')
+call ale#Set('rust_analyzer_config', {})
+
+function! ale_linters#rust#analyzer#GetCommand(buffer) abort
+ return '%e'
+endfunction
+
+function! ale_linters#rust#analyzer#GetProjectRoot(buffer) abort
+ let l:cargo_file = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
+
+ return !empty(l:cargo_file) ? fnamemodify(l:cargo_file, ':h') : ''
+endfunction
+
+call ale#linter#Define('rust', {
+\ 'name': 'analyzer',
+\ 'lsp': 'stdio',
+\ 'lsp_config': {b -> ale#Var(b, 'rust_analyzer_config')},
+\ 'executable': {b -> ale#Var(b, 'rust_analyzer_executable')},
+\ 'command': function('ale_linters#rust#analyzer#GetCommand'),
+\ 'project_root': function('ale_linters#rust#analyzer#GetProjectRoot'),
+\})
diff --git a/ale_linters/scala/metals.vim b/ale_linters/scala/metals.vim
index f78c7119..da9e855d 100644
--- a/ale_linters/scala/metals.vim
+++ b/ale_linters/scala/metals.vim
@@ -32,6 +32,8 @@ function! ale_linters#scala#metals#GetProjectRoot(buffer) abort
\)
endif
endfor
+
+ return ''
endfunction
function! ale_linters#scala#metals#GetCommand(buffer) abort
diff --git a/ale_linters/sh/bashate.vim b/ale_linters/sh/bashate.vim
new file mode 100644
index 00000000..3cd84245
--- /dev/null
+++ b/ale_linters/sh/bashate.vim
@@ -0,0 +1,43 @@
+" Author: hsanson <hsanson@gmail.com>
+" Description: Lints sh files using bashate
+" URL: https://github.com/openstack/bashate
+
+call ale#Set('sh_bashate_executable', 'bashate')
+call ale#Set('sh_bashate_options', '')
+
+function! ale_linters#sh#bashate#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'sh_bashate_executable')
+endfunction
+
+function! ale_linters#sh#bashate#GetCommand(buffer) abort
+ let l:options = ale#Var(a:buffer, 'sh_bashate_options')
+ let l:executable = ale_linters#sh#bashate#GetExecutable(a:buffer)
+
+ return ale#Escape(l:executable) . ' ' . l:options . ' ' . '%t'
+endfunction
+
+function! ale_linters#sh#bashate#Handle(buffer, lines) abort
+ " Matches patterns line the following:
+ "
+ " /path/to/script/file:694:1: E003 Indent not multiple of 4
+ let l:pattern = ':\(\d\+\):\(\d\+\): \(.*\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': str2nr(l:match[1]),
+ \ 'col': str2nr(l:match[2]),
+ \ 'text': l:match[3],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('sh', {
+\ 'name': 'bashate',
+\ 'output_stream': 'stdout',
+\ 'executable': function('ale_linters#sh#bashate#GetExecutable'),
+\ 'command': function('ale_linters#sh#bashate#GetCommand'),
+\ 'callback': 'ale_linters#sh#bashate#Handle',
+\})
diff --git a/ale_linters/sh/shellcheck.vim b/ale_linters/sh/shellcheck.vim
index 1d8b6096..d9945126 100644
--- a/ale_linters/sh/shellcheck.vim
+++ b/ale_linters/sh/shellcheck.vim
@@ -1,107 +1,4 @@
" Author: w0rp <devw0rp@gmail.com>
-" Description: This file adds support for using the shellcheck linter with
-" shell scripts.
+" Description: shellcheck linter for shell scripts.
-" This global variable can be set with a string of comma-separated error
-" codes to exclude from shellcheck. For example:
-"
-" let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004'
-call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_exclusions', ''))
-call ale#Set('sh_shellcheck_executable', 'shellcheck')
-call ale#Set('sh_shellcheck_dialect', 'auto')
-call ale#Set('sh_shellcheck_options', '')
-call ale#Set('sh_shellcheck_change_directory', 1)
-
-function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
- let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
-
- if !empty(l:shell_type)
- " Use the dash dialect for /bin/ash, etc.
- if l:shell_type is# 'ash'
- return 'dash'
- endif
-
- return l:shell_type
- endif
-
- " If there's no hashbang, try using Vim's buffer variables.
- if getbufvar(a:buffer, 'is_bash', 0)
- return 'bash'
- elseif getbufvar(a:buffer, 'is_sh', 0)
- return 'sh'
- elseif getbufvar(a:buffer, 'is_kornshell', 0)
- return 'ksh'
- endif
-
- return ''
-endfunction
-
-function! ale_linters#sh#shellcheck#GetCommand(buffer, version) abort
- let l:options = ale#Var(a:buffer, 'sh_shellcheck_options')
- let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
- let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
- let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
- let l:cd_string = ale#Var(a:buffer, 'sh_shellcheck_change_directory')
- \ ? ale#path#BufferCdString(a:buffer)
- \ : ''
-
- if l:dialect is# 'auto'
- let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
- endif
-
- return l:cd_string
- \ . '%e'
- \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
- \ . (!empty(l:options) ? ' ' . l:options : '')
- \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
- \ . l:external_option
- \ . ' -f gcc -'
-endfunction
-
-function! ale_linters#sh#shellcheck#Handle(buffer, lines) abort
- let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+) \[([^\]]+)\]$'
- let l:output = []
-
- for l:match in ale#util#GetMatches(a:lines, l:pattern)
- if l:match[4] is# 'error'
- let l:type = 'E'
- elseif l:match[4] is# 'note'
- let l:type = 'I'
- else
- let l:type = 'W'
- endif
-
- let l:item = {
- \ 'lnum': str2nr(l:match[2]),
- \ 'type': l:type,
- \ 'text': l:match[5],
- \ 'code': l:match[6],
- \}
-
- if !empty(l:match[3])
- let l:item.col = str2nr(l:match[3])
- endif
-
- " If the filename is something like <stdin>, <nofile> or -, then
- " this is an error for the file we checked.
- if l:match[1] isnot# '-' && l:match[1][0] isnot# '<'
- let l:item['filename'] = l:match[1]
- endif
-
- call add(l:output, l:item)
- endfor
-
- return l:output
-endfunction
-
-call ale#linter#Define('sh', {
-\ 'name': 'shellcheck',
-\ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')},
-\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
-\ buffer,
-\ ale#Var(buffer, 'sh_shellcheck_executable'),
-\ '%e --version',
-\ function('ale_linters#sh#shellcheck#GetCommand'),
-\ )},
-\ 'callback': 'ale_linters#sh#shellcheck#Handle',
-\})
+call ale#handlers#shellcheck#DefineLinter('sh')
diff --git a/ale_linters/terraform/terraform_lsp.vim b/ale_linters/terraform/terraform_lsp.vim
new file mode 100644
index 00000000..e2408c15
--- /dev/null
+++ b/ale_linters/terraform/terraform_lsp.vim
@@ -0,0 +1,25 @@
+" Author: OJFord <dev@ojford.com>
+" Description: terraform-lsp integration for ALE (cf. https://github.com/juliosueiras/terraform-lsp)
+
+call ale#Set('terraform_langserver_executable', 'terraform-lsp')
+call ale#Set('terraform_langserver_options', '')
+
+function! ale_linters#terraform#terraform_lsp#GetCommand(buffer) abort
+ return '%e'
+ \ . ale#Pad(ale#Var(a:buffer, 'terraform_langserver_options'))
+endfunction
+
+function! ale_linters#terraform#terraform_lsp#GetProjectRoot(buffer) abort
+ let l:tf_dir = ale#path#FindNearestDirectory(a:buffer, '.terraform')
+
+ return !empty(l:tf_dir) ? fnamemodify(l:tf_dir, ':h:h') : ''
+endfunction
+
+call ale#linter#Define('terraform', {
+\ 'name': 'terraform_lsp',
+\ 'lsp': 'stdio',
+\ 'executable': {b -> ale#Var(b, 'terraform_langserver_executable')},
+\ 'command': function('ale_linters#terraform#terraform_lsp#GetCommand'),
+\ 'project_root': function('ale_linters#terraform#terraform_lsp#GetProjectRoot'),
+\ 'language': 'terraform',
+\})
diff --git a/ale_linters/typescript/standard.vim b/ale_linters/typescript/standard.vim
new file mode 100644
index 00000000..da8f14eb
--- /dev/null
+++ b/ale_linters/typescript/standard.vim
@@ -0,0 +1,31 @@
+" Author: Ahmed El Gabri <@ahmedelgabri>
+" Description: standardjs for typescript files
+
+call ale#Set('typescript_standard_executable', 'standard')
+call ale#Set('typescript_standard_use_global', get(g:, 'ale_use_global_executables', 0))
+call ale#Set('typescript_standard_options', '')
+
+function! ale_linters#typescript#standard#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'typescript_standard', [
+ \ 'node_modules/standardx/bin/cmd.js',
+ \ 'node_modules/standard/bin/cmd.js',
+ \ 'node_modules/.bin/standard',
+ \])
+endfunction
+
+function! ale_linters#typescript#standard#GetCommand(buffer) abort
+ let l:executable = ale_linters#typescript#standard#GetExecutable(a:buffer)
+ let l:options = ale#Var(a:buffer, 'typescript_standard_options')
+
+ return ale#node#Executable(a:buffer, l:executable)
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . ' --stdin %s'
+endfunction
+
+" standard uses eslint and the output format is the same
+call ale#linter#Define('typescript', {
+\ 'name': 'standard',
+\ 'executable': function('ale_linters#typescript#standard#GetExecutable'),
+\ 'command': function('ale_linters#typescript#standard#GetCommand'),
+\ 'callback': 'ale#handlers#eslint#Handle',
+\})
diff --git a/ale_linters/verilog/hdl_checker.vim b/ale_linters/verilog/hdl_checker.vim
new file mode 100644
index 00000000..b05d8565
--- /dev/null
+++ b/ale_linters/verilog/hdl_checker.vim
@@ -0,0 +1,5 @@
+" Author: suoto <andre820@gmail.com>
+" Description: Adds support for HDL Code Checker, which wraps vcom/vlog, ghdl
+" or xvhdl. More info on https://github.com/suoto/hdl_checker
+
+call ale#handlers#hdl_checker#DefineLinter('verilog')
diff --git a/ale_linters/verilog/verilator.vim b/ale_linters/verilog/verilator.vim
index 64bb6e41..029dd4c9 100644
--- a/ale_linters/verilog/verilator.vim
+++ b/ale_linters/verilog/verilator.vim
@@ -28,21 +28,30 @@ function! ale_linters#verilog#verilator#Handle(buffer, lines) abort
" %Warning-UNDRIVEN: test.v:3: Signal is not driven: clk
" %Warning-UNUSED: test.v:4: Signal is not used: dout
" %Warning-BLKSEQ: test.v:10: Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).
- let l:pattern = '^%\(Warning\|Error\)[^:]*:\([^:]\+\):\(\d\+\): \(.\+\)$'
+ " Since version 4.032 (04/2020) verilator linter messages also contain the column number,
+ " and look like:
+ " %Error: /tmp/test.sv:3:1: syntax error, unexpected endmodule, expecting ';'
+ "
+ " to stay compatible with old versions of the tool, the column number is
+ " optional in the researched pattern
+ let l:pattern = '^%\(Warning\|Error\)[^:]*:\([^:]\+\):\(\d\+\):\(\d\+\)\?:\? \(.\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
- let l:line = l:match[3] + 0
- let l:type = l:match[1] is# 'Error' ? 'E' : 'W'
- let l:text = l:match[4]
+ let l:item = {
+ \ 'lnum': str2nr(l:match[3]),
+ \ 'text': l:match[5],
+ \ 'type': l:match[1] is# 'Error' ? 'E' : 'W',
+ \}
+
+ if !empty(l:match[4])
+ let l:item.col = str2nr(l:match[4])
+ endif
+
let l:file = l:match[2]
if l:file =~# '_verilator_linted.v'
- call add(l:output, {
- \ 'lnum': l:line,
- \ 'text': l:text,
- \ 'type': l:type,
- \})
+ call add(l:output, l:item)
endif
endfor
diff --git a/ale_linters/vhdl/hdl_checker.vim b/ale_linters/vhdl/hdl_checker.vim
new file mode 100644
index 00000000..c9d306b3
--- /dev/null
+++ b/ale_linters/vhdl/hdl_checker.vim
@@ -0,0 +1,5 @@
+" Author: suoto <andre820@gmail.com>
+" Description: Adds support for HDL Code Checker, which wraps vcom/vlog, ghdl
+" or xvhdl. More info on https://github.com/suoto/hdl_checker
+
+call ale#handlers#hdl_checker#DefineLinter('vhdl')
diff --git a/ale_linters/vim/vimls.vim b/ale_linters/vim/vimls.vim
new file mode 100644
index 00000000..26014d66
--- /dev/null
+++ b/ale_linters/vim/vimls.vim
@@ -0,0 +1,61 @@
+" Author: Jeffrey Lau - https://github.com/zoonfafer
+" Description: Vim Language Server integration for ALE
+
+call ale#Set('vim_vimls_executable', 'vim-language-server')
+call ale#Set('vim_vimls_use_global', get(g:, 'ale_use_global_executables', 0))
+call ale#Set('vim_vimls_config', {})
+
+function! ale_linters#vim#vimls#GetProjectRoot(buffer) abort
+ let l:trigger_file_candidates = [
+ \ '.vimrc',
+ \ 'init.vim',
+ \]
+
+ for l:candidate in l:trigger_file_candidates
+ let l:trigger_file = fnamemodify(bufname(a:buffer), ':t')
+
+ if l:trigger_file is# l:candidate
+ return fnamemodify(
+ \ bufname(a:buffer),
+ \ ':h',
+ \)
+ endif
+ endfor
+
+ let l:trigger_dir_candidates = [
+ \ 'autoload',
+ \ 'plugin',
+ \ '.git',
+ \]
+
+ let l:path_upwards = ale#path#Upwards(fnamemodify(bufname(a:buffer), ':p:h'))
+
+ for l:path in l:path_upwards
+ for l:candidate in l:trigger_dir_candidates
+ let l:trigger_dir = ale#path#Simplify(
+ \ l:path . '/' . l:candidate,
+ \)
+
+ if isdirectory(l:trigger_dir)
+ return fnamemodify(
+ \ l:trigger_dir,
+ \ ':p:h:h',
+ \)
+ endif
+ endfor
+ endfor
+
+ return ''
+endfunction
+
+call ale#linter#Define('vim', {
+\ 'name': 'vimls',
+\ 'lsp': 'stdio',
+\ 'lsp_config': {b -> ale#Var(b, 'vim_vimls_config')},
+\ 'executable': {b -> ale#node#FindExecutable(b, 'vim_vimls', [
+\ 'node_modules/.bin/vim-language-server',
+\ ])},
+\ 'command': '%e --stdio',
+\ 'language': 'vim',
+\ 'project_root': function('ale_linters#vim#vimls#GetProjectRoot'),
+\})
diff --git a/ale_linters/zig/zls.vim b/ale_linters/zig/zls.vim
new file mode 100644
index 00000000..1390f6b1
--- /dev/null
+++ b/ale_linters/zig/zls.vim
@@ -0,0 +1,20 @@
+" Author: CherryMan <skipper308@hotmail.ca>
+" Description: A language server for Zig
+
+call ale#Set('zig_zls_executable', 'zls')
+call ale#Set('zig_zls_config', {})
+
+function! ale_linters#zig#zls#GetProjectRoot(buffer) abort
+ let l:build_rs = ale#path#FindNearestFile(a:buffer, 'build.zig')
+
+ return !empty(l:build_rs) ? fnamemodify(l:build_rs, ':h') : ''
+endfunction
+
+call ale#linter#Define('zig', {
+\ 'name': 'zls',
+\ 'lsp': 'stdio',
+\ 'lsp_config': {b -> ale#Var(b, 'zig_zls_config')},
+\ 'executable': {b -> ale#Var(b, 'zig_zls_executable')},
+\ 'command': '%e',
+\ 'project_root': function('ale_linters#zig#zls#GetProjectRoot'),
+\})
diff --git a/autoload/ale.vim b/autoload/ale.vim
index ee1a0d54..6251b47b 100644
--- a/autoload/ale.vim
+++ b/autoload/ale.vim
@@ -163,7 +163,7 @@ function! ale#Queue(delay, ...) abort
endif
endfunction
-let s:current_ale_version = [2, 6, 0]
+let s:current_ale_version = [2, 7, 0]
" A function used to check for ALE features in files outside of the project.
function! ale#Has(feature) abort
@@ -258,9 +258,9 @@ function! ale#GetLocItemMessage(item, format_string) abort
" Replace special markers with certain information.
" \=l:variable is used to avoid escaping issues.
+ let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g')
let l:msg = substitute(l:msg, '\V%severity%', '\=l:severity', 'g')
let l:msg = substitute(l:msg, '\V%linter%', '\=l:linter_name', 'g')
- let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g')
" Replace %s with the text.
let l:msg = substitute(l:msg, '\V%s', '\=a:item.text', 'g')
diff --git a/autoload/ale/ant.vim b/autoload/ale/ant.vim
index 689b444b..7d02484e 100644
--- a/autoload/ale/ant.vim
+++ b/autoload/ale/ant.vim
@@ -1,4 +1,4 @@
-" Author: Andrew Lee <andrewl@mbda.fun>.
+" Author: Andrew Lee <andrew.lambda@tuta.io>.
" Inspired by ale/gradle.vim by Michael Pardo <michael@michaelpardo.com>
" Description: Functions for working with Ant projects.
diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim
index 0af1bb70..60c3bbef 100644
--- a/autoload/ale/code_action.vim
+++ b/autoload/ale/code_action.vim
@@ -1,7 +1,7 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Code action support for LSP / tsserver
-function! ale#code_action#HandleCodeAction(code_action) abort
+function! ale#code_action#HandleCodeAction(code_action, should_save) abort
let l:current_buffer = bufnr('')
let l:changes = a:code_action.changes
@@ -17,11 +17,14 @@ function! ale#code_action#HandleCodeAction(code_action) abort
for l:file_code_edit in l:changes
call ale#code_action#ApplyChanges(
- \ l:file_code_edit.fileName, l:file_code_edit.textChanges)
+ \ l:file_code_edit.fileName,
+ \ l:file_code_edit.textChanges,
+ \ a:should_save,
+ \ )
endfor
endfunction
-function! ale#code_action#ApplyChanges(filename, changes) abort
+function! ale#code_action#ApplyChanges(filename, changes, should_save) abort
let l:current_buffer = bufnr('')
" The buffer is used to determine the fileformat, if available.
let l:buffer = bufnr(a:filename)
@@ -106,10 +109,17 @@ function! ale#code_action#ApplyChanges(filename, changes) abort
call remove(l:lines, -1)
endif
- call ale#util#Writefile(l:buffer, l:lines, a:filename)
+ if a:should_save
+ call ale#util#Writefile(l:buffer, l:lines, a:filename)
+ else
+ call ale#util#SetBufferContents(l:buffer, l:lines)
+ endif
if l:is_current_buffer
- call ale#util#Execute(':e!')
+ if a:should_save
+ call ale#util#Execute(':e!')
+ endif
+
call setpos('.', [0, l:pos[0], l:pos[1], 0])
endif
endfunction
diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim
index d93acd66..f5e25cd0 100644
--- a/autoload/ale/completion.vim
+++ b/autoload/ale/completion.vim
@@ -1,5 +1,6 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Completion support for LSP linters
+scriptencoding utf-8
" The omnicompletion menu is shown through a special Plug mapping which is
" only valid in Insert mode. This way, feedkeys() won't send these keys if you
@@ -22,24 +23,101 @@ let s:timer_id = -1
let s:last_done_pos = []
" CompletionItemKind values from the LSP protocol.
-let s:LSP_COMPLETION_TEXT_KIND = 1
-let s:LSP_COMPLETION_METHOD_KIND = 2
-let s:LSP_COMPLETION_FUNCTION_KIND = 3
-let s:LSP_COMPLETION_CONSTRUCTOR_KIND = 4
-let s:LSP_COMPLETION_FIELD_KIND = 5
-let s:LSP_COMPLETION_VARIABLE_KIND = 6
-let s:LSP_COMPLETION_CLASS_KIND = 7
-let s:LSP_COMPLETION_INTERFACE_KIND = 8
-let s:LSP_COMPLETION_MODULE_KIND = 9
-let s:LSP_COMPLETION_PROPERTY_KIND = 10
-let s:LSP_COMPLETION_UNIT_KIND = 11
-let s:LSP_COMPLETION_VALUE_KIND = 12
-let s:LSP_COMPLETION_ENUM_KIND = 13
-let s:LSP_COMPLETION_KEYWORD_KIND = 14
-let s:LSP_COMPLETION_SNIPPET_KIND = 15
-let s:LSP_COMPLETION_COLOR_KIND = 16
-let s:LSP_COMPLETION_FILE_KIND = 17
-let s:LSP_COMPLETION_REFERENCE_KIND = 18
+let g:ale_lsp_types = {
+\ 1: 'text',
+\ 2: 'method',
+\ 3: 'function',
+\ 4: 'constructor',
+\ 5: 'field',
+\ 6: 'variable',
+\ 7: 'class',
+\ 8: 'interface',
+\ 9: 'module',
+\ 10: 'property',
+\ 11: 'unit',
+\ 12: 'value',
+\ 13: 'enum',
+\ 14: 'keyword',
+\ 15: 'snippet',
+\ 16: 'color',
+\ 17: 'file',
+\ 18: 'reference',
+\ 19: 'folder',
+\ 20: 'enum_member',
+\ 21: 'constant',
+\ 22: 'struct',
+\ 23: 'event',
+\ 24: 'operator',
+\ 25: 'type_parameter',
+\ }
+
+" from https://github.com/microsoft/TypeScript/blob/29becf05012bfa7ba20d50b0d16813971e46b8a6/lib/protocol.d.ts#L2472
+let g:ale_tsserver_types = {
+\ 'warning': 'text',
+\ 'keyword': 'keyword',
+\ 'script': 'file',
+\ 'module': 'module',
+\ 'class': 'class',
+\ 'local class': 'class',
+\ 'interface': 'interface',
+\ 'type': 'class',
+\ 'enum': 'enum',
+\ 'enum member': 'enum_member',
+\ 'var': 'variable',
+\ 'local var': 'variable',
+\ 'function': 'function',
+\ 'local function': 'function',
+\ 'method': 'method',
+\ 'getter': 'property',
+\ 'setter': 'method',
+\ 'property': 'property',
+\ 'constructor': 'constructor',
+\ 'call': 'method',
+\ 'index': 'index',
+\ 'construct': 'constructor',
+\ 'parameter': 'parameter',
+\ 'type parameter': 'type_parameter',
+\ 'primitive type': 'unit',
+\ 'label': 'text',
+\ 'alias': 'class',
+\ 'const': 'constant',
+\ 'let': 'variable',
+\ 'directory': 'folder',
+\ 'external module name': 'text',
+\ 'JSX attribute': 'parameter',
+\ 'string': 'text'
+\ }
+
+" For compatibility reasons, we only use built in VIM completion kinds
+" See :help complete-items for Vim completion kinds
+let g:ale_completion_symbols = get(g:, 'ale_completion_symbols', {
+\ 'text': 'v',
+\ 'method': 'f',
+\ 'function': 'f',
+\ 'constructor': 'f',
+\ 'field': 'm',
+\ 'variable': 'v',
+\ 'class': 't',
+\ 'interface': 't',
+\ 'module': 'd',
+\ 'property': 'm',
+\ 'unit': 'v',
+\ 'value': 'v',
+\ 'enum': 't',
+\ 'keyword': 'v',
+\ 'snippet': 'v',
+\ 'color': 'v',
+\ 'file': 'v',
+\ 'reference': 'v',
+\ 'folder': 'v',
+\ 'enum_member': 'm',
+\ 'constant': 'm',
+\ 'struct': 't',
+\ 'event': 'v',
+\ 'operator': 'f',
+\ 'type_parameter': 'p',
+\ '<default>': 'v'
+\ })
let s:LSP_INSERT_TEXT_FORMAT_PLAIN = 1
let s:LSP_INSERT_TEXT_FORMAT_SNIPPET = 2
@@ -184,6 +262,8 @@ function! s:ReplaceCompletionOptions() abort
if &l:completeopt =~# 'preview'
let &l:completeopt = 'menu,menuone,preview,noselect,noinsert'
+ elseif &l:completeopt =~# 'popup'
+ let &l:completeopt = 'menu,menuone,popup,noselect,noinsert'
else
let &l:completeopt = 'menu,menuone,noselect,noinsert'
endif
@@ -279,6 +359,27 @@ function! ale#completion#GetAllTriggers() abort
return deepcopy(s:trigger_character_map)
endfunction
+function! ale#completion#GetCompletionKind(kind) abort
+ let l:lsp_symbol = get(g:ale_lsp_types, a:kind, '')
+
+ if !empty(l:lsp_symbol)
+ return l:lsp_symbol
+ endif
+
+ return get(g:ale_tsserver_types, a:kind, '')
+endfunction
+
+function! ale#completion#GetCompletionSymbols(kind) abort
+ let l:kind = ale#completion#GetCompletionKind(a:kind)
+ let l:symbol = get(g:ale_completion_symbols, l:kind, '')
+
+ if !empty(l:symbol)
+ return l:symbol
+ endif
+
+ return get(g:ale_completion_symbols, '<default>', 'v')
+endfunction
+
function! s:CompletionStillValid(request_id) abort
let [l:line, l:column] = getpos('.')[1:2]
@@ -288,7 +389,6 @@ function! s:CompletionStillValid(request_id) abort
\&& b:ale_completion_info.line == l:line
\&& (
\ b:ale_completion_info.column == l:column
- \ || b:ale_completion_info.source is# 'deoplete'
\ || b:ale_completion_info.source is# 'ale-omnifunc'
\ || b:ale_completion_info.source is# 'ale-callback'
\)
@@ -334,18 +434,10 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
call add(l:documentationParts, l:part.text)
endfor
- if l:suggestion.kind is# 'className'
- let l:kind = 'f'
- elseif l:suggestion.kind is# 'parameterName'
- let l:kind = 'f'
- else
- let l:kind = 'v'
- endif
-
" See :help complete-items
let l:result = {
\ 'word': l:suggestion.name,
- \ 'kind': l:kind,
+ \ 'kind': ale#completion#GetCompletionSymbols(l:suggestion.kind),
\ 'icase': 1,
\ 'menu': join(l:displayParts, ''),
\ 'dup': g:ale_completion_tsserver_autoimport,
@@ -430,36 +522,52 @@ function! ale#completion#ParseLSPCompletions(response) abort
continue
endif
- " See :help complete-items for Vim completion kinds
- if !has_key(l:item, 'kind')
- let l:kind = 'v'
- elseif l:item.kind is s:LSP_COMPLETION_METHOD_KIND
- let l:kind = 'm'
- elseif l:item.kind is s:LSP_COMPLETION_CONSTRUCTOR_KIND
- let l:kind = 'm'
- elseif l:item.kind is s:LSP_COMPLETION_FUNCTION_KIND
- let l:kind = 'f'
- elseif l:item.kind is s:LSP_COMPLETION_CLASS_KIND
- let l:kind = 'f'
- elseif l:item.kind is s:LSP_COMPLETION_INTERFACE_KIND
- let l:kind = 'f'
- else
- let l:kind = 'v'
- endif
-
let l:doc = get(l:item, 'documentation', '')
if type(l:doc) is v:t_dict && has_key(l:doc, 'value')
let l:doc = l:doc.value
endif
- call add(l:results, {
+ let l:result = {
\ 'word': l:word,
- \ 'kind': l:kind,
+ \ 'kind': ale#completion#GetCompletionSymbols(get(l:item, 'kind', '')),
\ 'icase': 1,
\ 'menu': get(l:item, 'detail', ''),
\ 'info': (type(l:doc) is v:t_string ? l:doc : ''),
- \})
+ \}
+
+ if has_key(l:item, 'additionalTextEdits')
+ let l:text_changes = []
+
+ for l:edit in l:item.additionalTextEdits
+ let l:range = l:edit.range
+ call add(l:text_changes, {
+ \ 'start': {
+ \ 'line': l:range.start.line + 1,
+ \ 'offset': l:range.start.character + 1,
+ \ },
+ \ 'end': {
+ \ 'line': l:range.end.line + 1,
+ \ 'offset': l:range.end.character + 1,
+ \ },
+ \ 'newText': l:edit.newText,
+ \})
+ endfor
+
+ let l:changes = [{
+ \ 'fileName': expand('#' . l:buffer . ':p'),
+ \ 'textChanges': l:text_changes,
+ \}]
+ \
+ let l:result.user_data = json_encode({
+ \ 'codeActions': [{
+ \ 'description': 'completion',
+ \ 'changes': l:changes,
+ \ }],
+ \ })
+ endif
+
+ call add(l:results, l:result)
endfor
if has_key(l:info, 'prefix')
@@ -734,7 +842,9 @@ endfunction
function! ale#completion#HandleUserData(completed_item) abort
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
- if l:source isnot# 'ale-automatic' && l:source isnot# 'ale-manual' && l:source isnot# 'ale-callback'
+ if l:source isnot# 'ale-automatic'
+ \&& l:source isnot# 'ale-manual'
+ \&& l:source isnot# 'ale-callback'
return
endif
@@ -751,7 +861,7 @@ function! ale#completion#HandleUserData(completed_item) abort
endif
for l:code_action in get(l:user_data, 'codeActions', [])
- call ale#code_action#HandleCodeAction(l:code_action)
+ call ale#code_action#HandleCodeAction(l:code_action, v:false)
endfor
endfunction
diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim
index 3915cac1..ffcd9d10 100644
--- a/autoload/ale/definition.vim
+++ b/autoload/ale/definition.vim
@@ -5,6 +5,7 @@ let s:go_to_definition_map = {}
" Enable automatic updates of the tagstack
let g:ale_update_tagstack = get(g:, 'ale_update_tagstack', 1)
+let g:ale_default_navigation = get(g:, 'ale_default_navigation', 'buffer')
" Used to get the definition map in tests.
function! ale#definition#GetMap() abort
@@ -134,6 +135,10 @@ function! s:GoToLSPDefinition(linter, options, capability) abort
endfunction
function! ale#definition#GoTo(options) abort
+ if !get(g:, 'ale_ignore_2_7_warnings') && has_key(a:options, 'deprecated_command')
+ execute 'echom '':' . a:options.deprecated_command . ' is deprecated. Use `let g:ale_ignore_2_7_warnings = 1` to disable this message.'''
+ endif
+
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'definition')
@@ -142,6 +147,10 @@ function! ale#definition#GoTo(options) abort
endfunction
function! ale#definition#GoToType(options) abort
+ if !get(g:, 'ale_ignore_2_7_warnings') && has_key(a:options, 'deprecated_command')
+ execute 'echom '':' . a:options.deprecated_command . ' is deprecated. Use `let g:ale_ignore_2_7_warnings = 1` to disable this message.'''
+ endif
+
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
" TODO: handle typeDefinition for tsserver if supported by the
@@ -154,3 +163,33 @@ function! ale#definition#GoToType(options) abort
endif
endfor
endfunction
+
+function! ale#definition#GoToCommandHandler(command, ...) abort
+ let l:options = {}
+
+ if len(a:000) > 0
+ for l:option in a:000
+ if l:option is? '-tab'
+ let l:options.open_in = 'tab'
+ elseif l:option is? '-split'
+ let l:options.open_in = 'split'
+ elseif l:option is? '-vsplit'
+ let l:options.open_in = 'vsplit'
+ endif
+ endfor
+ endif
+
+ if !has_key(l:options, 'open_in')
+ let l:default_navigation = ale#Var(bufnr(''), 'default_navigation')
+
+ if index(['tab', 'split', 'vsplit'], l:default_navigation) >= 0
+ let l:options.open_in = l:default_navigation
+ endif
+ endif
+
+ if a:command is# 'type'
+ call ale#definition#GoToType(l:options)
+ else
+ call ale#definition#GoTo(l:options)
+ endif
+endfunction
diff --git a/autoload/ale/events.vim b/autoload/ale/events.vim
index da554ef9..731e36f2 100644
--- a/autoload/ale/events.vim
+++ b/autoload/ale/events.vim
@@ -147,6 +147,10 @@ function! ale#events#Init() abort
autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarning() | endif
endif
+ if g:ale_hover_cursor
+ autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif
+ endif
+
if g:ale_close_preview_on_insert
autocmd InsertEnter * if exists('*ale#preview#CloseIfTypeMatches') | call ale#preview#CloseIfTypeMatches('ale-preview') | endif
endif
diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim
index dad9e2bc..69817b36 100644
--- a/autoload/ale/fix.vim
+++ b/autoload/ale/fix.vim
@@ -4,40 +4,15 @@ call ale#Set('fix_on_save_ignore', {})
" Vim doesn't let you modify hidden buffers.
function! ale#fix#ApplyQueuedFixes(buffer) abort
let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0})
- let l:has_bufline_api = exists('*deletebufline') && exists('*setbufline')
- if !l:data.done || (!l:has_bufline_api && a:buffer isnot bufnr(''))
+ if !l:data.done || (!ale#util#HasBuflineApi() && a:buffer isnot bufnr(''))
return
endif
call remove(g:ale_fix_buffer_data, a:buffer)
if l:data.changes_made
- " If the file is in DOS mode, we have to remove carriage returns from
- " the ends of lines before calling setline(), or we will see them
- " twice.
- let l:new_lines = getbufvar(a:buffer, '&fileformat') is# 'dos'
- \ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')')
- \ : l:data.output
- let l:first_line_to_remove = len(l:new_lines) + 1
-
- " Use a Vim API for setting lines in other buffers, if available.
- if l:has_bufline_api
- call setbufline(a:buffer, 1, l:new_lines)
- call deletebufline(a:buffer, l:first_line_to_remove, '$')
- " Fall back on setting lines the old way, for the current buffer.
- else
- let l:old_line_length = len(l:data.lines_before)
-
- if l:old_line_length >= l:first_line_to_remove
- let l:save = winsaveview()
- silent execute
- \ l:first_line_to_remove . ',' . l:old_line_length . 'd_'
- call winrestview(l:save)
- endif
-
- call setline(1, l:new_lines)
- endif
+ let l:new_lines = ale#util#SetBufferContents(a:buffer, l:data.output)
if l:data.should_save
if a:buffer is bufnr('')
diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim
index 5ec27a10..02b02699 100644
--- a/autoload/ale/fix/registry.vim
+++ b/autoload/ale/fix/registry.vim
@@ -54,6 +54,11 @@ let s:default_registry = {
\ 'description': 'Apply elm-format to a file.',
\ 'aliases': ['format'],
\ },
+\ 'nimpretty': {
+\ 'function': 'ale#fixers#nimpretty#Fix',
+\ 'suggested_filetypes': ['nim'],
+\ 'description': 'Apply nimpretty to a file.',
+\ },
\ 'eslint': {
\ 'function': 'ale#fixers#eslint#Fix',
\ 'suggested_filetypes': ['javascript', 'typescript'],
@@ -155,6 +160,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['php'],
\ 'description': 'Fix PHP files with php-cs-fixer.',
\ },
+\ 'astyle': {
+\ 'function': 'ale#fixers#astyle#Fix',
+\ 'suggested_filetypes': ['c', 'cpp'],
+\ 'description': 'Fix C/C++ with astyle.',
+\ },
\ 'clangtidy': {
\ 'function': 'ale#fixers#clangtidy#Fix',
\ 'suggested_filetypes': ['c', 'cpp', 'objc'],
diff --git a/autoload/ale/fixers/astyle.vim b/autoload/ale/fixers/astyle.vim
new file mode 100644
index 00000000..3a5a70a1
--- /dev/null
+++ b/autoload/ale/fixers/astyle.vim
@@ -0,0 +1,59 @@
+" Author: James Kim <jhlink@users.noreply.github.com>
+" Description: Fix C/C++ files with astyle.
+
+function! s:set_variables() abort
+ for l:ft in ['c', 'cpp']
+ call ale#Set(l:ft . '_astyle_executable', 'astyle')
+ call ale#Set(l:ft . '_astyle_project_options', '')
+ endfor
+endfunction
+
+call s:set_variables()
+
+
+function! ale#fixers#astyle#Var(buffer, name) abort
+ let l:ft = getbufvar(str2nr(a:buffer), '&filetype')
+ let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c'
+
+ return ale#Var(a:buffer, l:ft . '_astyle_' . a:name)
+endfunction
+
+" Try to find a project options file.
+function! ale#fixers#astyle#FindProjectOptions(buffer) abort
+ let l:proj_options = ale#fixers#astyle#Var(a:buffer, 'project_options')
+
+ " If user has set project options variable then use it and skip any searching.
+ " This would allow users to use project files named differently than .astylerc.
+ if !empty(l:proj_options)
+ return l:proj_options
+ endif
+
+ " Try to find nearest .astylerc file.
+ let l:proj_options = fnamemodify(ale#path#FindNearestFile(a:buffer, '.astylerc'), ':t')
+
+ if !empty(l:proj_options)
+ return l:proj_options
+ endif
+
+ " Try to find nearest _astylerc file.
+ let l:proj_options = fnamemodify(ale#path#FindNearestFile(a:buffer, '_astylerc'), ':t')
+
+ if !empty(l:proj_options)
+ return l:proj_options
+ endif
+
+ " If no project options file is found return an empty string.
+ return ''
+endfunction
+
+function! ale#fixers#astyle#Fix(buffer) abort
+ let l:executable = ale#fixers#astyle#Var(a:buffer, 'executable')
+ let l:proj_options = ale#fixers#astyle#FindProjectOptions(a:buffer)
+ let l:command = ' --stdin=' . ale#Escape(expand('#' . a:buffer))
+
+ return {
+ \ 'command': ale#Escape(l:executable)
+ \ . (empty(l:proj_options) ? '' : ' --project=' . l:proj_options)
+ \ . l:command
+ \}
+endfunction
diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim
index 62e692b1..f725875c 100644
--- a/autoload/ale/fixers/eslint.vim
+++ b/autoload/ale/fixers/eslint.vim
@@ -53,7 +53,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
" Use --fix-to-stdout with eslint_d
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
return {
- \ 'command': ale#node#Executable(a:buffer, l:executable)
+ \ 'command': ale#handlers#eslint#GetCdString(a:buffer)
+ \ . ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
@@ -63,7 +64,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
" 4.9.0 is the first version with --fix-dry-run
if ale#semver#GTE(a:version, [4, 9, 0])
return {
- \ 'command': ale#node#Executable(a:buffer, l:executable)
+ \ 'command': ale#handlers#eslint#GetCdString(a:buffer)
+ \ . ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@@ -71,7 +73,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
endif
return {
- \ 'command': ale#node#Executable(a:buffer, l:executable)
+ \ 'command': ale#handlers#eslint#GetCdString(a:buffer)
+ \ . ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options)
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
\ . ' --fix %t',
diff --git a/autoload/ale/fixers/ktlint.vim b/autoload/ale/fixers/ktlint.vim
index cb975d6c..64d1340d 100644
--- a/autoload/ale/fixers/ktlint.vim
+++ b/autoload/ale/fixers/ktlint.vim
@@ -3,7 +3,6 @@
function! ale#fixers#ktlint#Fix(buffer) abort
return {
- \ 'command': ale#handlers#ktlint#GetCommand(a:buffer) . ' --format',
- \ 'read_temporary_file': 1,
+ \ 'command': ale#handlers#ktlint#GetCommand(a:buffer) . ' --format'
\}
endfunction
diff --git a/autoload/ale/fixers/nimpretty.vim b/autoload/ale/fixers/nimpretty.vim
new file mode 100644
index 00000000..fe2e7136
--- /dev/null
+++ b/autoload/ale/fixers/nimpretty.vim
@@ -0,0 +1,15 @@
+" Author: Nhan <hi@imnhan.com>
+" Description: Integration of nimpretty with ALE.
+
+call ale#Set('nim_nimpretty_executable', 'nimpretty')
+call ale#Set('nim_nimpretty_options', '--maxLineLen:80')
+
+function! ale#fixers#nimpretty#Fix(buffer) abort
+ let l:executable = ale#Var(a:buffer, 'nim_nimpretty_executable')
+ let l:options = ale#Var(a:buffer, 'nim_nimpretty_options')
+
+ return {
+ \ 'command': ale#Escape(l:executable) . ' %t' . ale#Pad(l:options),
+ \ 'read_temporary_file': 1,
+ \}
+endfunction
diff --git a/autoload/ale/fixers/standard.vim b/autoload/ale/fixers/standard.vim
index 77712d40..cffa9f9d 100644
--- a/autoload/ale/fixers/standard.vim
+++ b/autoload/ale/fixers/standard.vim
@@ -7,6 +7,7 @@ call ale#Set('javascript_standard_options', '')
function! ale#fixers#standard#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
+ \ 'node_modules/standardx/bin/cmd.js',
\ 'node_modules/standard/bin/cmd.js',
\ 'node_modules/.bin/standard',
\])
@@ -14,7 +15,14 @@ endfunction
function! ale#fixers#standard#Fix(buffer) abort
let l:executable = ale#fixers#standard#GetExecutable(a:buffer)
- let l:options = ale#Var(a:buffer, 'javascript_standard_options')
+ let l:filetype = getbufvar(a:buffer, '&filetype')
+ let l:options_type = 'javascript_standard_options'
+
+ if l:filetype =~# 'typescript'
+ let l:options_type = 'typescript_standard_options'
+ endif
+
+ let l:options = ale#Var(a:buffer, l:options_type)
return {
\ 'command': ale#node#Executable(a:buffer, l:executable)
diff --git a/autoload/ale/fixers/tslint.vim b/autoload/ale/fixers/tslint.vim
index b352af3a..15768fd5 100644
--- a/autoload/ale/fixers/tslint.vim
+++ b/autoload/ale/fixers/tslint.vim
@@ -16,7 +16,7 @@ function! ale#fixers#tslint#Fix(buffer) abort
return {
\ 'command': ale#node#Executable(a:buffer, l:executable)
\ . l:tslint_config_option
- \ . ' --fix %t',
+ \ . ' --outputAbsolutePaths --fix %t',
\ 'read_temporary_file': 1,
\}
endfunction
diff --git a/autoload/ale/handlers/ccls.vim b/autoload/ale/handlers/ccls.vim
index 1e2aa318..290f5852 100644
--- a/autoload/ale/handlers/ccls.vim
+++ b/autoload/ale/handlers/ccls.vim
@@ -17,3 +17,10 @@ function! ale#handlers#ccls#GetProjectRoot(buffer) abort
" Fall back on default project root detection.
return ale#c#FindProjectRoot(a:buffer)
endfunction
+
+function! ale#handlers#ccls#GetInitOpts(buffer, init_options_var) abort
+ let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
+ let l:init_options = empty(l:build_dir) ? {} : {'compilationDatabaseDirectory': l:build_dir}
+
+ return extend(l:init_options, ale#Var(a:buffer, a:init_options_var))
+endfunction
diff --git a/autoload/ale/handlers/cppcheck.vim b/autoload/ale/handlers/cppcheck.vim
index 6d8fa15d..7f68ba67 100644
--- a/autoload/ale/handlers/cppcheck.vim
+++ b/autoload/ale/handlers/cppcheck.vim
@@ -44,16 +44,21 @@ endfunction
function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
" Look for lines like the following.
"
- " [test.cpp:5]: (error) Array 'a[10]' accessed at index 10, which is out of bounds
- let l:pattern = '\v^\[(.+):(\d+)\]: \(([a-z]+)\) (.+)$'
+ "test.cpp:974:6: error: Array 'n[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\
+ " n[3]=3;
+ " ^
+ let l:pattern = '\v^(\f+):(\d+):(\d+): (\w+): (.*) \[(\w+)\]\'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
if ale#path#IsBufferPath(a:buffer, l:match[1])
call add(l:output, {
- \ 'lnum': str2nr(l:match[2]),
- \ 'type': l:match[3] is# 'error' ? 'E' : 'W',
- \ 'text': l:match[4],
+ \ 'lnum': str2nr(l:match[2]),
+ \ 'col': str2nr(l:match[3]),
+ \ 'type': l:match[4] is# 'error' ? 'E' : 'W',
+ \ 'sub_type': l:match[4] is# 'style' ? 'style' : '',
+ \ 'text': l:match[5],
+ \ 'code': l:match[6]
\})
endif
endfor
diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim
index 4d533ff2..e37d6902 100644
--- a/autoload/ale/handlers/eslint.vim
+++ b/autoload/ale/handlers/eslint.vim
@@ -1,6 +1,11 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Functions for working with eslint, for checking or fixing files.
+let s:executables = [
+\ 'node_modules/.bin/eslint_d',
+\ 'node_modules/eslint/bin/eslint.js',
+\ 'node_modules/.bin/eslint',
+\]
let s:sep = has('win32') ? '\' : '/'
call ale#Set('javascript_eslint_options', '')
@@ -30,11 +35,31 @@ function! ale#handlers#eslint#FindConfig(buffer) abort
endfunction
function! ale#handlers#eslint#GetExecutable(buffer) abort
- return ale#node#FindExecutable(a:buffer, 'javascript_eslint', [
- \ 'node_modules/.bin/eslint_d',
- \ 'node_modules/eslint/bin/eslint.js',
- \ 'node_modules/.bin/eslint',
- \])
+ return ale#node#FindExecutable(a:buffer, 'javascript_eslint', s:executables)
+endfunction
+
+" Given a buffer, return a command prefix string which changes directory
+" as necessary for running ESLint.
+function! ale#handlers#eslint#GetCdString(buffer) abort
+ " ESLint 6 loads plugins/configs/parsers from the project root
+ " By default, the project root is simply the CWD of the running process.
+ " https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md
+ " https://github.com/dense-analysis/ale/issues/2787
+ "
+ " If eslint is installed in a directory which contains the buffer, assume
+ " it is the ESLint project root. Otherwise, use nearest node_modules.
+ " Note: If node_modules not present yet, can't load local deps anyway.
+ let l:executable = ale#node#FindNearestExecutable(a:buffer, s:executables)
+
+ if !empty(l:executable)
+ let l:nmi = strridx(l:executable, 'node_modules')
+ let l:project_dir = l:executable[0:l:nmi - 2]
+ else
+ let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules')
+ let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : ''
+ endif
+
+ return !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : ''
endfunction
function! ale#handlers#eslint#GetCommand(buffer) abort
@@ -42,7 +67,8 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
- return ale#node#Executable(a:buffer, l:executable)
+ return ale#handlers#eslint#GetCdString(a:buffer)
+ \ . ale#node#Executable(a:buffer, l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -f json --stdin --stdin-filename %s'
endfunction
@@ -84,11 +110,14 @@ function! s:CheckForBadConfig(buffer, lines) abort
endfunction
function! s:parseJSON(buffer, lines) abort
- try
- let l:parsed = json_decode(a:lines[-1])
- catch
- return []
- endtry
+ let l:parsed = []
+
+ for l:line in a:lines
+ try
+ let l:parsed = extend(l:parsed, json_decode(l:line))
+ catch
+ endtry
+ endfor
if type(l:parsed) != v:t_list || empty(l:parsed)
return []
diff --git a/autoload/ale/handlers/go.vim b/autoload/ale/handlers/go.vim
index f17cd862..c969669d 100644
--- a/autoload/ale/handlers/go.vim
+++ b/autoload/ale/handlers/go.vim
@@ -6,9 +6,12 @@
"
" Author: Ben Paxton <ben@gn32.uk>
" Description: moved to generic Golang file from govet
+"
+" Author: mostfunkyduck <mostfunkyduck@protonmail.com>
+" Description: updated to work with go 1.14
function! ale#handlers#go#Handler(buffer, lines) abort
- let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? ?(.+)$'
+ let l:pattern = '\v^%(vet: )?([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? ?(.+)$'
let l:output = []
let l:dir = expand('#' . a:buffer . ':p:h')
diff --git a/autoload/ale/handlers/hdl_checker.vim b/autoload/ale/handlers/hdl_checker.vim
new file mode 100644
index 00000000..36dbd259
--- /dev/null
+++ b/autoload/ale/handlers/hdl_checker.vim
@@ -0,0 +1,71 @@
+" Author: suoto <andre820@gmail.com>
+" Description: Adds support for HDL Code Checker, which wraps vcom/vlog, ghdl
+" or xvhdl. More info on https://github.com/suoto/hdl_checker
+
+call ale#Set('hdl_checker_executable', 'hdl_checker')
+call ale#Set('hdl_checker_config_file', has('unix') ? '.hdl_checker.config' : '_hdl_checker.config')
+call ale#Set('hdl_checker_options', '')
+
+" Use this as a function so we can mock it on testing. Need to do this because
+" test files are inside /testplugin (which refers to the ale repo), which will
+" always have a .git folder
+function! ale#handlers#hdl_checker#IsDotGit(path) abort
+ return ! empty(a:path) && isdirectory(a:path)
+endfunction
+
+" Sould return (in order of preference)
+" 1. Nearest config file
+" 2. Nearest .git directory
+" 3. The current path
+function! ale#handlers#hdl_checker#GetProjectRoot(buffer) abort
+ let l:project_root = ale#path#FindNearestFile(
+ \ a:buffer,
+ \ ale#Var(a:buffer, 'hdl_checker_config_file'))
+
+ if !empty(l:project_root)
+ return fnamemodify(l:project_root, ':h')
+ endif
+
+ " Search for .git to use as root
+ let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
+
+ if ale#handlers#hdl_checker#IsDotGit(l:project_root)
+ return fnamemodify(l:project_root, ':h:h')
+ endif
+endfunction
+
+function! ale#handlers#hdl_checker#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'hdl_checker_executable')
+endfunction
+
+function! ale#handlers#hdl_checker#GetCommand(buffer) abort
+ let l:command = ale#Escape(ale#handlers#hdl_checker#GetExecutable(a:buffer)) . ' --lsp'
+
+ " Add extra parameters only if config has been set
+ let l:options = ale#Var(a:buffer, 'hdl_checker_options')
+
+ if ! empty(l:options)
+ let l:command = l:command . ' ' . l:options
+ endif
+
+ return l:command
+endfunction
+
+" To allow testing
+function! ale#handlers#hdl_checker#GetInitOptions(buffer) abort
+ return {'project_file': ale#Var(a:buffer, 'hdl_checker_config_file')}
+endfunction
+
+" Define the hdl_checker linter for a given filetype.
+function! ale#handlers#hdl_checker#DefineLinter(filetype) abort
+ call ale#linter#Define(a:filetype, {
+ \ 'name': 'hdl-checker',
+ \ 'lsp': 'stdio',
+ \ 'language': a:filetype,
+ \ 'executable': function('ale#handlers#hdl_checker#GetExecutable'),
+ \ 'command': function('ale#handlers#hdl_checker#GetCommand'),
+ \ 'project_root': function('ale#handlers#hdl_checker#GetProjectRoot'),
+ \ 'initialization_options': function('ale#handlers#hdl_checker#GetInitOptions'),
+ \ })
+endfunction
+
diff --git a/autoload/ale/handlers/ktlint.vim b/autoload/ale/handlers/ktlint.vim
index ad999485..77e7ab66 100644
--- a/autoload/ale/handlers/ktlint.vim
+++ b/autoload/ale/handlers/ktlint.vim
@@ -13,7 +13,7 @@ function! ale#handlers#ktlint#GetCommand(buffer) abort
return ale#Escape(l:executable)
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . (empty(l:rulesets) ? '' : ' ' . l:rulesets)
- \ . ' %t'
+ \ . ' --stdin'
endfunction
function! ale#handlers#ktlint#GetRulesets(buffer) abort
diff --git a/autoload/ale/handlers/markdownlint.vim b/autoload/ale/handlers/markdownlint.vim
index daaa1d66..6c273bd0 100644
--- a/autoload/ale/handlers/markdownlint.vim
+++ b/autoload/ale/handlers/markdownlint.vim
@@ -2,15 +2,22 @@
" Description: Adds support for markdownlint
function! ale#handlers#markdownlint#Handle(buffer, lines) abort
- let l:pattern=': \(\d*\): \(MD\d\{3}\)\(\/\)\([A-Za-z0-9-]\+\)\(.*\)$'
+ let l:pattern=': \?\(\d\+\)\(:\(\d\+\)\?\)\? \(MD\d\{3}/[A-Za-z0-9-/]\+\) \(.*\)$'
let l:output=[]
for l:match in ale#util#GetMatches(a:lines, l:pattern)
- call add(l:output, {
+ let l:result = ({
\ 'lnum': l:match[1] + 0,
- \ 'text': '(' . l:match[2] . l:match[3] . l:match[4] . ')' . l:match[5],
+ \ 'code': l:match[4],
+ \ 'text': l:match[5],
\ 'type': 'W',
\})
+
+ if len(l:match[3]) > 0
+ let l:result.col = (l:match[3] + 0)
+ endif
+
+ call add(l:output, l:result)
endfor
return l:output
diff --git a/autoload/ale/handlers/shellcheck.vim b/autoload/ale/handlers/shellcheck.vim
new file mode 100644
index 00000000..b16280f0
--- /dev/null
+++ b/autoload/ale/handlers/shellcheck.vim
@@ -0,0 +1,107 @@
+" Author: w0rp <devw0rp@gmail.com>
+" Description: This file adds support for using the shellcheck linter
+
+function! ale#handlers#shellcheck#GetDialectArgument(buffer) abort
+ let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
+
+ if !empty(l:shell_type)
+ " Use the dash dialect for /bin/ash, etc.
+ if l:shell_type is# 'ash'
+ return 'dash'
+ endif
+
+ return l:shell_type
+ endif
+
+ " If there's no hashbang, try using Vim's buffer variables.
+ if getbufvar(a:buffer, 'is_bash', 0)
+ return 'bash'
+ elseif getbufvar(a:buffer, 'is_sh', 0)
+ return 'sh'
+ elseif getbufvar(a:buffer, 'is_kornshell', 0)
+ return 'ksh'
+ endif
+
+ return ''
+endfunction
+
+function! ale#handlers#shellcheck#GetCommand(buffer, version) abort
+ let l:options = ale#Var(a:buffer, 'sh_shellcheck_options')
+ let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
+ let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
+ let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
+ let l:cd_string = ale#Var(a:buffer, 'sh_shellcheck_change_directory')
+ \ ? ale#path#BufferCdString(a:buffer)
+ \ : ''
+
+ if l:dialect is# 'auto'
+ let l:dialect = ale#handlers#shellcheck#GetDialectArgument(a:buffer)
+ endif
+
+ return l:cd_string
+ \ . '%e'
+ \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
+ \ . l:external_option
+ \ . ' -f gcc -'
+endfunction
+
+function! ale#handlers#shellcheck#Handle(buffer, lines) abort
+ let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+) \[([^\]]+)\]$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ if l:match[4] is# 'error'
+ let l:type = 'E'
+ elseif l:match[4] is# 'note'
+ let l:type = 'I'
+ else
+ let l:type = 'W'
+ endif
+
+ let l:item = {
+ \ 'lnum': str2nr(l:match[2]),
+ \ 'type': l:type,
+ \ 'text': l:match[5],
+ \ 'code': l:match[6],
+ \}
+
+ if !empty(l:match[3])
+ let l:item.col = str2nr(l:match[3])
+ endif
+
+ " If the filename is something like <stdin>, <nofile> or -, then
+ " this is an error for the file we checked.
+ if l:match[1] isnot# '-' && l:match[1][0] isnot# '<'
+ let l:item['filename'] = l:match[1]
+ endif
+
+ call add(l:output, l:item)
+ endfor
+
+ return l:output
+endfunction
+
+function! ale#handlers#shellcheck#DefineLinter(filetype) abort
+ " This global variable can be set with a string of comma-separated error
+ " codes to exclude from shellcheck. For example:
+ " let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004'
+ call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_exclusions', ''))
+ call ale#Set('sh_shellcheck_executable', 'shellcheck')
+ call ale#Set('sh_shellcheck_dialect', 'auto')
+ call ale#Set('sh_shellcheck_options', '')
+ call ale#Set('sh_shellcheck_change_directory', 1)
+
+ call ale#linter#Define(a:filetype, {
+ \ 'name': 'shellcheck',
+ \ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')},
+ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
+ \ buffer,
+ \ ale#Var(buffer, 'sh_shellcheck_executable'),
+ \ '%e --version',
+ \ function('ale#handlers#shellcheck#GetCommand'),
+ \ )},
+ \ 'callback': 'ale#handlers#shellcheck#Handle',
+ \})
+endfunction
diff --git a/autoload/ale/highlight.vim b/autoload/ale/highlight.vim
index 82ad57e0..473ad354 100644
--- a/autoload/ale/highlight.vim
+++ b/autoload/ale/highlight.vim
@@ -210,6 +210,12 @@ function! ale#highlight#SetHighlights(buffer, loclist) abort
" Set the list in the buffer variable.
call setbufvar(str2nr(a:buffer), 'ale_highlight_items', l:new_list)
+ let l:exclude_list = ale#Var(a:buffer, 'exclude_highlights')
+
+ if !empty(l:exclude_list)
+ call filter(l:new_list, 'empty(ale#util#GetMatches(v:val.text, l:exclude_list))')
+ endif
+
" Update highlights for the current buffer, which may or may not
" be the buffer we just set highlights for.
call ale#highlight#UpdateHighlights()
diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim
index 2af35aa4..a6462227 100644
--- a/autoload/ale/hover.vim
+++ b/autoload/ale/hover.vim
@@ -42,6 +42,13 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort
\&& exists('*balloon_show')
\&& ale#Var(l:options.buffer, 'set_balloons')
call balloon_show(a:response.body.displayString)
+ elseif get(l:options, 'truncated_echo', 0)
+ call ale#cursor#TruncatedEcho(split(a:response.body.displayString, "\n")[0])
+ elseif g:ale_hover_to_preview
+ call ale#preview#Show(split(a:response.body.displayString, "\n"), {
+ \ 'filetype': 'ale-preview.message',
+ \ 'stay_here': 1,
+ \})
else
call ale#util#ShowMessage(a:response.body.displayString)
endif
@@ -84,11 +91,12 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort
if type(l:result) is v:t_dict
" If the result is an object, then it's markup content.
- let l:result = [l:result.value]
+ let l:result = has_key(l:result, 'value') ? [l:result.value] : []
endif
if type(l:result) is v:t_list
" Replace objects with text values.
+ call filter(l:result, '!(type(v:val) is v:t_dict && !has_key(v:val, ''value''))')
call map(l:result, 'type(v:val) is v:t_string ? v:val : v:val.value')
let l:str = join(l:result, "\n")
let l:str = substitute(l:str, '^\s*\(.\{-}\)\s*$', '\1', '')
@@ -98,6 +106,13 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort
\&& exists('*balloon_show')
\&& ale#Var(l:options.buffer, 'set_balloons')
call balloon_show(l:str)
+ elseif get(l:options, 'truncated_echo', 0)
+ call ale#cursor#TruncatedEcho(split(l:str, "\n")[0])
+ elseif g:ale_hover_to_preview
+ call ale#preview#Show(split(l:str, "\n"), {
+ \ 'filetype': 'ale-preview.message',
+ \ 'stay_here': 1,
+ \})
else
call ale#util#ShowMessage(l:str)
endif
@@ -146,6 +161,7 @@ function! s:OnReady(line, column, opt, linter, lsp_details) abort
\ 'column': l:column,
\ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0),
\ 'show_documentation': get(a:opt, 'show_documentation', 0),
+ \ 'truncated_echo': get(a:opt, 'truncated_echo', 0),
\}
endfunction
@@ -179,6 +195,16 @@ function! ale#hover#ShowAtCursor() abort
call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], {})
endfunction
+function! ale#hover#ShowTruncatedMessageAtCursor() abort
+ let l:buffer = bufnr('')
+ let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
+
+ if empty(l:loc)
+ let l:pos = getpos('.')
+ call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], {'truncated_echo': 1})
+ endif
+endfunction
+
" This function implements the :ALEDocumentation command.
function! ale#hover#ShowDocumentationAtCursor() abort
let l:buffer = bufnr('')
diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim
index a85f06e2..f81b62be 100644
--- a/autoload/ale/linter.vim
+++ b/autoload/ale/linter.vim
@@ -44,7 +44,7 @@ let s:default_ale_linters = {
\ 'help': [],
\ 'perl': ['perlcritic'],
\ 'perl6': [],
-\ 'python': ['flake8', 'mypy', 'pylint'],
+\ 'python': ['flake8', 'mypy', 'pylint', 'pyright'],
\ 'rust': ['cargo'],
\ 'spec': [],
\ 'text': [],
diff --git a/autoload/ale/lsp.vim b/autoload/ale/lsp.vim
index 2509174e..ae8fd51d 100644
--- a/autoload/ale/lsp.vim
+++ b/autoload/ale/lsp.vim
@@ -196,14 +196,26 @@ function! s:UpdateCapabilities(conn, capabilities) abort
let a:conn.capabilities.hover = 1
endif
+ if type(get(a:capabilities, 'hoverProvider')) is v:t_dict
+ let a:conn.capabilities.hover = 1
+ endif
+
if get(a:capabilities, 'referencesProvider') is v:true
let a:conn.capabilities.references = 1
endif
+ if type(get(a:capabilities, 'referencesProvider')) is v:t_dict
+ let a:conn.capabilities.references = 1
+ endif
+
if get(a:capabilities, 'renameProvider') is v:true
let a:conn.capabilities.rename = 1
endif
+ if type(get(a:capabilities, 'renameProvider')) is v:t_dict
+ let a:conn.capabilities.rename = 1
+ endif
+
if !empty(get(a:capabilities, 'completionProvider'))
let a:conn.capabilities.completion = 1
endif
@@ -220,13 +232,25 @@ function! s:UpdateCapabilities(conn, capabilities) abort
let a:conn.capabilities.definition = 1
endif
+ if type(get(a:capabilities, 'definitionProvider')) is v:t_dict
+ let a:conn.capabilities.definition = 1
+ endif
+
if get(a:capabilities, 'typeDefinitionProvider') is v:true
let a:conn.capabilities.typeDefinition = 1
endif
+ if type(get(a:capabilities, 'typeDefinitionProvider')) is v:t_dict
+ let a:conn.capabilities.typeDefinition = 1
+ endif
+
if get(a:capabilities, 'workspaceSymbolProvider') is v:true
let a:conn.capabilities.symbol_search = 1
endif
+
+ if type(get(a:capabilities, 'workspaceSymbolProvider')) is v:t_dict
+ let a:conn.capabilities.symbol_search = 1
+ endif
endfunction
" Update a connection's configuration dictionary and notify LSP servers
diff --git a/autoload/ale/node.vim b/autoload/ale/node.vim
index 69060122..9b9b335a 100644
--- a/autoload/ale/node.vim
+++ b/autoload/ale/node.vim
@@ -12,6 +12,18 @@ function! ale#node#FindExecutable(buffer, base_var_name, path_list) abort
return ale#Var(a:buffer, a:base_var_name . '_executable')
endif
+ let l:nearest = ale#node#FindNearestExecutable(a:buffer, a:path_list)
+
+ if !empty(l:nearest)
+ return l:nearest
+ endif
+
+ return ale#Var(a:buffer, a:base_var_name . '_executable')
+endfunction
+
+" Given a buffer number, a base variable name, and a list of paths to search
+" for in ancestor directories, detect the executable path for a Node program.
+function! ale#node#FindNearestExecutable(buffer, path_list) abort
for l:path in a:path_list
let l:executable = ale#path#FindNearestFile(a:buffer, l:path)
@@ -20,7 +32,7 @@ function! ale#node#FindExecutable(buffer, base_var_name, path_list) abort
endif
endfor
- return ale#Var(a:buffer, a:base_var_name . '_executable')
+ return ''
endfunction
" Create a executable string which executes a Node.js script command with a
diff --git a/autoload/ale/organize_imports.vim b/autoload/ale/organize_imports.vim
index bc9b829e..e89c832c 100644
--- a/autoload/ale/organize_imports.vim
+++ b/autoload/ale/organize_imports.vim
@@ -15,7 +15,7 @@ function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
call ale#code_action#HandleCodeAction({
\ 'description': 'Organize Imports',
\ 'changes': l:file_code_edits,
- \})
+ \}, v:false)
endfunction
function! s:OnReady(linter, lsp_details) abort
diff --git a/autoload/ale/preview.vim b/autoload/ale/preview.vim
index 6d58aca9..7902ec63 100644
--- a/autoload/ale/preview.vim
+++ b/autoload/ale/preview.vim
@@ -1,6 +1,14 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Preview windows for showing whatever information in.
+if !has_key(s:, 'last_selection_list')
+ let s:last_selection_list = []
+endif
+
+if !has_key(s:, 'last_selection_open_in')
+ let s:last_selection_open_in = 'current-buffer'
+endif
+
" Open a preview window and show some lines in it.
" A second argument can be passed as a Dictionary with options. They are...
"
@@ -67,9 +75,24 @@ function! ale#preview#ShowSelection(item_list, ...) abort
call ale#preview#Show(l:lines, {'filetype': 'ale-preview-selection'})
let b:ale_preview_item_list = a:item_list
+ let b:ale_preview_item_open_in = get(l:options, 'open_in', 'current-buffer')
+
+ " Remove the last preview
+ let s:last_selection_list = b:ale_preview_item_list
+ let s:last_selection_open_in = b:ale_preview_item_open_in
endfunction
-function! s:Open(open_in_tab) abort
+function! ale#preview#RepeatSelection() abort
+ if empty(s:last_selection_list)
+ return
+ endif
+
+ call ale#preview#ShowSelection(s:last_selection_list, {
+ \ 'open_in': s:last_selection_open_in,
+ \})
+endfunction
+
+function! s:Open(open_in) abort
let l:item_list = get(b:, 'ale_preview_item_list', [])
let l:item = get(l:item_list, getpos('.')[1] - 1, {})
@@ -77,22 +100,20 @@ function! s:Open(open_in_tab) abort
return
endif
- if !a:open_in_tab
- :q!
- endif
+ :q!
call ale#util#Open(
\ l:item.filename,
\ l:item.line,
\ l:item.column,
- \ {'open_in_tab': a:open_in_tab},
+ \ {'open_in': a:open_in},
\)
endfunction
-function! ale#preview#OpenSelectionInBuffer() abort
- call s:Open(0)
+function! ale#preview#OpenSelection() abort
+ call s:Open(b:ale_preview_item_open_in)
endfunction
function! ale#preview#OpenSelectionInTab() abort
- call s:Open(1)
+ call s:Open('tab')
endfunction
diff --git a/autoload/ale/references.vim b/autoload/ale/references.vim
index b9725e1e..38ff0d3d 100644
--- a/autoload/ale/references.vim
+++ b/autoload/ale/references.vim
@@ -1,3 +1,5 @@
+let g:ale_default_navigation = get(g:, 'ale_default_navigation', 'buffer')
+
let s:references_map = {}
" Used to get the references map in tests.
@@ -99,7 +101,8 @@ function! s:OnReady(line, column, options, linter, lsp_details) abort
let l:request_id = ale#lsp#Send(l:id, l:message)
let s:references_map[l:request_id] = {
- \ 'use_relative_paths': has_key(a:options, 'use_relative_paths') ? a:options.use_relative_paths : 0
+ \ 'use_relative_paths': has_key(a:options, 'use_relative_paths') ? a:options.use_relative_paths : 0,
+ \ 'open_in': get(a:options, 'open_in', 'current-buffer'),
\}
endfunction
@@ -110,10 +113,24 @@ function! ale#references#Find(...) abort
for l:option in a:000
if l:option is? '-relative'
let l:options.use_relative_paths = 1
+ elseif l:option is? '-tab'
+ let l:options.open_in = 'tab'
+ elseif l:option is? '-split'
+ let l:options.open_in = 'split'
+ elseif l:option is? '-vsplit'
+ let l:options.open_in = 'vsplit'
endif
endfor
endif
+ if !has_key(l:options, 'open_in')
+ let l:default_navigation = ale#Var(bufnr(''), 'default_navigation')
+
+ if index(['tab', 'split', 'vsplit'], l:default_navigation) >= 0
+ let l:options.open_in = l:default_navigation
+ endif
+ endif
+
let l:buffer = bufnr('')
let [l:line, l:column] = getpos('.')[1:2]
let l:column = min([l:column, len(getline(l:line))])
diff --git a/autoload/ale/rename.vim b/autoload/ale/rename.vim
index 02b7b579..64952e63 100644
--- a/autoload/ale/rename.vim
+++ b/autoload/ale/rename.vim
@@ -80,7 +80,32 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort
call ale#code_action#HandleCodeAction({
\ 'description': 'rename',
\ 'changes': l:changes,
- \})
+ \}, v:true)
+endfunction
+
+function! s:getChanges(workspace_edit) abort
+ let l:changes = {}
+
+ if has_key(a:workspace_edit, 'changes') && !empty(a:workspace_edit.changes)
+ return a:workspace_edit.changes
+ elseif has_key(a:workspace_edit, 'documentChanges')
+ let l:document_changes = []
+
+ if type(a:workspace_edit.documentChanges) is v:t_dict
+ \ && has_key(a:workspace_edit.documentChanges, 'edits')
+ call add(l:document_changes, a:workspace_edit.documentChanges)
+ elseif type(a:workspace_edit.documentChanges) is v:t_list
+ let l:document_changes = a:workspace_edit.documentChanges
+ endif
+
+ for l:text_document_edit in l:document_changes
+ let l:filename = l:text_document_edit.textDocument.uri
+ let l:edits = l:text_document_edit.edits
+ let l:changes[l:filename] = l:edits
+ endfor
+ endif
+
+ return l:changes
endfunction
function! ale#rename#HandleLSPResponse(conn_id, response) abort
@@ -94,9 +119,9 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort
return
endif
- let l:workspace_edit = a:response.result
+ let l:changes_map = s:getChanges(a:response.result)
- if !has_key(l:workspace_edit, 'changes') || empty(l:workspace_edit.changes)
+ if empty(l:changes_map)
call s:message('No changes received from server')
return
@@ -104,8 +129,8 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort
let l:changes = []
- for l:file_name in keys(l:workspace_edit.changes)
- let l:text_edits = l:workspace_edit.changes[l:file_name]
+ for l:file_name in keys(l:changes_map)
+ let l:text_edits = l:changes_map[l:file_name]
let l:text_changes = []
for l:edit in l:text_edits
@@ -134,7 +159,7 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort
call ale#code_action#HandleCodeAction({
\ 'description': 'rename',
\ 'changes': l:changes,
- \})
+ \}, v:true)
endif
endfunction
diff --git a/autoload/ale/sign.vim b/autoload/ale/sign.vim
index db0e1ab6..8109c60e 100644
--- a/autoload/ale/sign.vim
+++ b/autoload/ale/sign.vim
@@ -23,7 +23,7 @@ let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000)
let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0)
let g:ale_sign_highlight_linenrs = get(g:, 'ale_sign_highlight_linenrs', 0)
-let s:supports_sign_groups = has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+let s:supports_sign_groups = has('nvim-0.4.2') || has('patch-8.1.614')
if !hlexists('ALEErrorSign')
highlight link ALEErrorSign error
diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim
index 99cd856a..ee62af28 100644
--- a/autoload/ale/util.vim
+++ b/autoload/ale/util.vim
@@ -91,17 +91,17 @@ endfunction
" options['open_in'] can be:
" current-buffer (default)
" tab
-" vertical-split
-" horizontal-split
+" split
+" vsplit
function! ale#util#Open(filename, line, column, options) abort
let l:open_in = get(a:options, 'open_in', 'current-buffer')
let l:args_to_open = '+' . a:line . ' ' . fnameescape(a:filename)
if l:open_in is# 'tab'
call ale#util#Execute('tabedit ' . l:args_to_open)
- elseif l:open_in is# 'horizontal-split'
+ elseif l:open_in is# 'split'
call ale#util#Execute('split ' . l:args_to_open)
- elseif l:open_in is# 'vertical-split'
+ elseif l:open_in is# 'vsplit'
call ale#util#Execute('vsplit ' . l:args_to_open)
elseif bufnr(a:filename) isnot bufnr('')
" Open another file only if we need to.
@@ -336,15 +336,11 @@ function! ale#util#GetMatches(lines, patterns) abort
endfunction
function! s:LoadArgCount(function) abort
- let l:Function = a:function
-
- redir => l:output
- silent! function Function
- redir END
-
- if !exists('l:output')
+ try
+ let l:output = execute('function a:function')
+ catch /E123/
return 0
- endif
+ endtry
let l:match = matchstr(split(l:output, "\n")[0], '\v\([^)]+\)')[1:-2]
let l:arg_list = filter(split(l:match, ', '), 'v:val isnot# ''...''')
@@ -480,3 +476,44 @@ endfunction
function! ale#util#Input(message, value) abort
return input(a:message, a:value)
endfunction
+
+function! ale#util#HasBuflineApi() abort
+ return exists('*deletebufline') && exists('*setbufline')
+endfunction
+
+" Sets buffer contents to lines
+function! ale#util#SetBufferContents(buffer, lines) abort
+ let l:has_bufline_api = ale#util#HasBuflineApi()
+
+ if !l:has_bufline_api && a:buffer isnot bufnr('')
+ return
+ endif
+
+ " If the file is in DOS mode, we have to remove carriage returns from
+ " the ends of lines before calling setline(), or we will see them
+ " twice.
+ let l:new_lines = getbufvar(a:buffer, '&fileformat') is# 'dos'
+ \ ? map(copy(a:lines), 'substitute(v:val, ''\r\+$'', '''', '''')')
+ \ : a:lines
+ let l:first_line_to_remove = len(l:new_lines) + 1
+
+ " Use a Vim API for setting lines in other buffers, if available.
+ if l:has_bufline_api
+ call setbufline(a:buffer, 1, l:new_lines)
+ call deletebufline(a:buffer, l:first_line_to_remove, '$')
+ " Fall back on setting lines the old way, for the current buffer.
+ else
+ let l:old_line_length = line('$')
+
+ if l:old_line_length >= l:first_line_to_remove
+ let l:save = winsaveview()
+ silent execute
+ \ l:first_line_to_remove . ',' . l:old_line_length . 'd_'
+ call winrestview(l:save)
+ endif
+
+ call setline(1, l:new_lines)
+ endif
+
+ return l:new_lines
+endfunction
diff --git a/doc/ale-bats.txt b/doc/ale-bats.txt
new file mode 100644
index 00000000..cf2199ec
--- /dev/null
+++ b/doc/ale-bats.txt
@@ -0,0 +1,13 @@
+===============================================================================
+ALE Bats Integration *ale-bats-options*
+
+
+===============================================================================
+shellcheck *ale-bats-shellcheck*
+
+The `shellcheck` linter for Bats uses the sh options for `shellcheck`; see:
+|ale-sh-shellcheck|.
+
+
+===============================================================================
+ vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale-c.txt b/doc/ale-c.txt
index c9eb79db..efc26f93 100644
--- a/doc/ale-c.txt
+++ b/doc/ale-c.txt
@@ -60,6 +60,30 @@ g:ale_c_parse_makefile *g:ale_c_parse_makefile*
===============================================================================
+astyle *ale-c-astyle*
+
+g:ale_c_astyle_executable *g:ale_c_astyle_executable*
+ *b:ale_c_astyle_executable*
+ Type: |String|
+ Default: `'astyle'`
+
+ This variable can be changed to use a different executable for astyle.
+
+
+g:ale_c_astyle_project_options *g:ale_c_astyle_project_options*
+ *b:ale_c_astyle_project_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be changed to use an option file for project level
+ configurations. Provide only the filename of the option file that should be
+ present at the project's root directory.
+
+ For example, if .astylrc is specified, the file is searched in the parent
+ directories of the source file's directory.
+
+
+===============================================================================
clang *ale-c-clang*
g:ale_c_clang_executable *g:ale_c_clang_executable*
diff --git a/doc/ale-cloudformation.txt b/doc/ale-cloudformation.txt
index 59c6af06..9724403b 100644
--- a/doc/ale-cloudformation.txt
+++ b/doc/ale-cloudformation.txt
@@ -7,8 +7,40 @@ cfn-python-lint *ale-cloudformation-cfn-python-lint*
cfn-python-lint is a linter for AWS CloudFormation template file.
-https://github.com/awslabs/cfn-python-lint
+Website: https://github.com/awslabs/cfn-python-lint
+Installation
+-------------------------------------------------------------------------------
+
+
+Install cfn-python-lint using either pip or brew: >
+
+`pip install cfn-lint`. If pip is not available, run
+`python setup.py clean --all` then `python setup.py install`.
+
+ Homebrew (macOS):
+
+`brew install cfn-lint`
+
+<
+Configuration
+-------------------------------------------------------------------------------
+
+To get cloudformation linter to work on only CloudFormation files we must set
+the buffer |filetype| to yaml.cloudformation.
+This causes ALE to lint the file with linters configured for cloudformation and
+yaml files.
+
+Just put:
+
+>
+
+ au BufRead,BufNewFile *.template.yaml set filetype=yaml.cloudformation
+
+<
+
+on `ftdetect/cloudformation.vim`
+
+This will get both cloudformation and yaml linters to work on any file with `.template.yaml` ext.
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
-
diff --git a/doc/ale-cpp.txt b/doc/ale-cpp.txt
index ead3be28..fbe31370 100644
--- a/doc/ale-cpp.txt
+++ b/doc/ale-cpp.txt
@@ -14,6 +14,30 @@ The following C options also apply to some C++ linters too.
===============================================================================
+astyle *ale-cpp-astyle*
+
+g:ale_cpp_astyle_executable *g:ale_cpp_astyle_executable*
+ *b:ale_cpp_astyle_executable*
+ Type: |String|
+ Default: `'astyle'`
+
+ This variable can be changed to use a different executable for astyle.
+
+
+g:ale_cpp_astyle_project_options *g:ale_cpp_astyle_project_options*
+ *b:ale_cpp_astyle_project_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be changed to use an option file for project level
+ configurations. Provide only the filename of the option file that should be
+ present at the project's root directory.
+
+ For example, if .astylrc is specified, the file is searched in the parent
+ directories of the source file's directory.
+
+
+===============================================================================
clang *ale-cpp-clang*
g:ale_cpp_clang_executable *g:ale_cpp_clang_executable*
diff --git a/doc/ale-go.txt b/doc/ale-go.txt
index be53783e..5c0791bc 100644
--- a/doc/ale-go.txt
+++ b/doc/ale-go.txt
@@ -220,6 +220,25 @@ g:ale_go_govet_options *g:ale_go_govet_options*
===============================================================================
+revive *ale-go-revive*
+
+g:ale_go_revive_executable *g:ale_go_revive_executable*
+ *b:ale_go_revive_executable*
+ Type: |String|
+ Default: `'revive'`
+
+ This variable can be set to change the revive executable path.
+
+
+g:ale_go_revive_options *g:ale_go_revive_options*
+ *b:ale_go_revive_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be set to pass additional options to the revive
+
+
+===============================================================================
staticcheck *ale-go-staticcheck*
g:ale_go_staticcheck_options *g:ale_go_staticcheck_options*
diff --git a/doc/ale-java.txt b/doc/ale-java.txt
index 32f0e6eb..0debc1af 100644
--- a/doc/ale-java.txt
+++ b/doc/ale-java.txt
@@ -46,7 +46,7 @@ javac *ale-java-javac*
g:ale_java_javac_classpath *g:ale_java_javac_classpath*
*b:ale_java_javac_classpath*
- Type: |String|
+ Type: |String| or |List|
Default: `''`
This variable can be set to change the global classpath for Java.
@@ -67,6 +67,30 @@ g:ale_java_javac_options *g:ale_java_javac_options*
This variable can be set to pass additional options to javac.
+g:ale_java_javac_sourcepath *g:ale_java_javac_sourcepath*
+ *b:ale_java_javac_sourcepath*
+ Type: |String| or |List|
+ Default: `''`
+
+This variable can set multiple source code paths, the source code path is a
+relative path (relative to the project root directory).
+
+Example:
+
+String type:
+Note that the unix system separator is a colon(`:`) window system
+is a semicolon(`;`).
+>
+ let g:ale_java_javac_sourcepath = 'build/gen/source/xx/main:build/gen/source'
+<
+List type:
+>
+ let g:ale_java_javac_sourcepath = [
+ \ 'build/generated/source/querydsl/main',
+ \ 'target/generated-sources/source/querydsl/main'
+ \ ]
+<
+
===============================================================================
google-java-format *ale-java-google-java-format*
@@ -107,18 +131,26 @@ javalsp *ale-java-javalsp*
To enable Java LSP linter you need to download and build the vscode-javac
language server from https://github.com/georgewfraser/java-language-server.
-Simply download the source code and then build a distribution:
- scripts/link_mac.sh
+Before building the language server you need to install pre-requisites: npm,
+maven, and protobuf. You also need to have Java 13 and JAVA_HOME properly
+set.
+
+After downloading the source code and installing all pre-requisites you can
+build the language server with the included build.sh script:
+
+ scripts/build.sh
-or
+This will create launch scripts for Linux, Mac, and Windows in the dist folder
+within the repo:
- scripts/link_windows.sh
+ - lang_server_linux.sh
+ - lang_server_mac.sh
+ - lang_server_windows.sh
-This generates a dist/mac or dist/windows directory that contains the
-language server. To let ALE use this language server you need to set the
+To let ALE use this language server you need to set the
g:ale_java_javalsp_executable variable to the absolute path of the launcher
-executable in this directory.
+executable for your platform.
g:ale_java_javalsp_executable *g:ale_java_javalsp_executable*
*b:ale_java_javalsp_executable*
@@ -128,7 +160,7 @@ g:ale_java_javalsp_executable *g:ale_java_javalsp_executable*
This variable must be set to the absolute path of the language server launcher
executable. For example:
>
- let g:ale_java_javalsp_executable=/java-language-server/dist/mac/bin/launcher
+ let g:ale_java_javalsp_executable=/java-language-server/dist/lang_server_linux.sh
<
g:ale_java_javalsp_config *g:ale_java_javalsp_config*
@@ -140,7 +172,7 @@ The javalsp linter automatically detects external depenencies for Maven and
Gradle projects. In case the javalsp fails to detect some of them, you can
specify them setting a dictionary to |g:ale_java_javalsp_config| variable.
>
- let g:ale_java_javalsp_executable =
+ let g:ale_java_javalsp_config =
\ {
\ 'java': {
\ 'externalDependencies': [
@@ -222,6 +254,17 @@ g:ale_java_eclipselsp_workspace_path *g:ale_java_eclipselsp_workspace_path*
absolute path of the Eclipse workspace. If not set this value will be set to
the parent folder of the project root.
+g:ale_java_eclipselsp_javaagent *g:ale_java_eclipselsp_javaagent*
+ *b:ale_java_eclipselsp_javaagent*
+
+ Type: |String|
+ Default: `''`
+
+ A variable to add java agent for annotation processing such as Lombok.
+ If you have multiple java agent files, use space to separate them. For example:
+>
+ let g:ale_java_eclipselsp_javaagent='/eclipse/lombok.jar /eclipse/jacoco.jar'
+<
===============================================================================
uncrustify *ale-java-uncrustify*
diff --git a/doc/ale-javascript.txt b/doc/ale-javascript.txt
index ea0a7089..13059eaa 100644
--- a/doc/ale-javascript.txt
+++ b/doc/ale-javascript.txt
@@ -138,7 +138,7 @@ g:ale_javascript_flow_use_respect_pragma
By default, ALE will use the `--respect-pragma` option for `flow`, so only
files with the `@flow` pragma are checked by ALE. This option can be set to
- `0` to disable that behaviour, so all files can be checked by `flow`.
+ `0` to disable that behavior, so all files can be checked by `flow`.
===============================================================================
diff --git a/doc/ale-nim.txt b/doc/ale-nim.txt
index ad7aa686..8985aeb8 100644
--- a/doc/ale-nim.txt
+++ b/doc/ale-nim.txt
@@ -22,4 +22,24 @@ g:nim_nimlsp_nim_sources *g:nim_nimlsp_nim_sources*
===============================================================================
+nimpretty *ale-nim-nimpretty*
+
+
+g:ale_nim_nimpretty_executable *g:ale_nim_nimpretty_executable*
+ *b:ale_nim_nimpretty_executable*
+ Type: |String|
+ Default: `'nimpretty'`
+
+ This variable can be changed to use a different executable for nimpretty.
+
+
+g:ale_nim_nimpretty_options *g:ale_nim_nimpretty_options*
+ *b:ale_nim_nimpretty_options*
+ Type: |String|
+ Default: `'--maxLineLen:80'`
+
+ This variable can be changed to modify flags given to nimpretty.
+
+
+===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale-python.txt b/doc/ale-python.txt
index 9d5846d2..60b0771d 100644
--- a/doc/ale-python.txt
+++ b/doc/ale-python.txt
@@ -145,8 +145,8 @@ g:ale_python_black_use_global *g:ale_python_black_use_global*
See |ale-integrations-local-executables|
-g:ale_python_black_auto_pipenv *g:ale_python_black_auto_pipenv*
- *b:ale_python_black_auto_pipenv*
+g:ale_python_black_auto_pipenv *g:ale_python_black_auto_pipenv*
+ *b:ale_python_black_auto_pipenv*
Type: |Number|
Default: `0`
@@ -263,6 +263,15 @@ to check for errors while you type.
`mypy` will be run from a detected project root, per |ale-python-root|.
+g:ale_python_mypy_auto_pipenv *g:ale_python_mypy_auto_pipenv*
+ *b:ale_python_mypy_auto_pipenv*
+ Type: |Number|
+ Default: `0`
+
+ Detect whether the file is inside a pipenv, and set the executable to `pipenv`
+ if true. This is overridden by a manually-set executable.
+
+
g:ale_python_mypy_executable *g:ale_python_mypy_executable*
*b:ale_python_mypy_executable*
Type: |String|
@@ -272,6 +281,7 @@ g:ale_python_mypy_executable *g:ale_python_mypy_executable*
Set this to `'pipenv'` to invoke `'pipenv` `run` `mypy'`.
+
g:ale_python_mypy_ignore_invalid_syntax
*g:ale_python_mypy_ignore_invalid_syntax*
*b:ale_python_mypy_ignore_invalid_syntax*
@@ -292,6 +302,14 @@ g:ale_python_mypy_options *g:ale_python_mypy_options*
invocation.
+g:ale_python_mypy_show_notes *g:ale_python_mypy_show_notes*
+ *b:ale_python_mypy_show_notes*
+ Type: |Number|
+ Default: `1`
+
+ If enabled, notes on lines will be displayed as 'I' (info) messages.
+
+
g:ale_python_mypy_use_global *g:ale_python_mypy_use_global*
*b:ale_python_mypy_use_global*
Type: |Number|
@@ -300,14 +318,6 @@ g:ale_python_mypy_use_global *g:ale_python_mypy_use_global*
See |ale-integrations-local-executables|
-g:ale_python_mypy_auto_pipenv *g:ale_python_mypy_auto_pipenv*
- *b:ale_python_mypy_auto_pipenv*
- Type: |Number|
- Default: `0`
-
- Detect whether the file is inside a pipenv, and set the executable to `pipenv`
- if true. This is overridden by a manually-set executable.
-
===============================================================================
prospector *ale-python-prospector*
@@ -588,6 +598,7 @@ g:ale_python_pylint_use_msg_id *g:ale_python_pylint_use_msg_id*
Use message for output (e.g. I0011) instead of symbolic name of the message
(e.g. locally-disabled).
+
===============================================================================
pyls *ale-python-pyls*
@@ -673,6 +684,65 @@ g:ale_python_pyre_auto_pipenv *g:ale_python_pyre_auto_pipenv*
===============================================================================
+pyright *ale-python-pyright*
+
+The `pyrlight` linter requires a recent version of `pyright` which includes
+the `pyright-langserver` executable. You can install `pyright` on your system
+through `npm` with `sudo npm install -g pyright` or similar.
+
+Refer to their README for installation instructions:
+https://github.com/Microsoft/pyright
+
+`pyright` needs to know the path to your Python executable and probably a
+virtualenv to run. ALE will try to detect these automatically.
+See |g:ale_python_pyright_config|.
+
+
+g:ale_python_pyright_executable *g:ale_python_pyright_executable*
+ *b:ale_python_pyright_executable*
+ Type: |String|
+ Default: `'pyright-langserver'`
+
+ The executable for running `pyright`, which is typically installed globally.
+
+
+g:ale_python_pyright_config *g:ale_python_pyright_config*
+ *b:ale_python_pyright_config*
+ Type: |Dictionary|
+ Default: `{}`
+
+ Settings for configuring the `pyright` language server.
+
+ See pyright's documentation for a full list of options:
+ https://github.com/microsoft/pyright/blob/master/docs/settings.md
+
+ ALE will automatically try to set defaults for `venvPath` and `pythonPath`
+ so your project can automatically be checked with the right libraries.
+ You can override these settings with whatever you want in your ftplugin
+ file like so: >
+
+ let b:ale_python_pyright_config = {
+ \ 'python': {
+ \ 'pythonPath': '/bin/python',
+ \ 'venvPath': '/other/dir',
+ \ },
+ \}
+<
+ If `venvPath` is set, but `pythonPath` is not,
+ ALE will use `venvPath . '/bin/python'` or similar as `pythonPath`.
+
+ A commonly used setting for `pyright` is disabling language services
+ apart from type checking and "hover" (|ale-hover|), you can set this
+ setting like so, or use whatever other settings you want: >
+
+ let b:ale_python_pyright_config = {
+ \ 'pyright': {
+ \ 'disableLanguageServices': v:true,
+ \ },
+ \}
+<
+
+===============================================================================
reorder-python-imports *ale-python-reorder_python_imports*
g:ale_python_reorder_python_imports_executable
diff --git a/doc/ale-rust.txt b/doc/ale-rust.txt
index 44a79b18..46d4714b 100644
--- a/doc/ale-rust.txt
+++ b/doc/ale-rust.txt
@@ -9,7 +9,7 @@ Integration Information
files for Rust distributed in Vim >=8.0.0501 or upstream:
https://github.com/rust-lang/rust.vim
- Note that there are three possible linters for Rust files:
+ Note that there are several possible linters and fixers for Rust files:
1. rustc -- The Rust compiler is used to check the currently edited file.
So, if your project consists of multiple files, you will get some errors
@@ -23,7 +23,12 @@ Integration Information
over cargo. rls implements the Language Server Protocol for incremental
compilation of Rust code, and can check Rust files while you type. `rls`
requires Rust files to contained in Cargo projects.
- 4. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to
+ 4. analyzer -- If you have rust-analyzer installed, you might prefer using
+ this linter over cargo and rls. rust-analyzer also implements the
+ Language Server Protocol for incremental compilation of Rust code, and is
+ the next iteration of rls. rust-analyzer, like rls, requires Rust files
+ to contained in Cargo projects.
+ 5. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to
consistently reformat your Rust code.
Only cargo is enabled by default. To switch to using rustc instead of cargo,
@@ -37,6 +42,25 @@ Integration Information
===============================================================================
+analyzer *ale-rust-analyzer*
+
+g:ale_rust_analyzer_executable *g:ale_rust_analyzer_executable*
+ *b:ale_rust_analyzer_executable*
+ Type: |String|
+ Default: `'rust-analyzer'`
+
+ This variable can be modified to change the executable path for
+ `rust-analyzer`.
+
+
+g:ale_rust_analyzer_config *g:ale_rust_analyzer_config*
+ *b:ale_rust_analyzer_config*
+ Type: |Dictionary|
+ Default: `{}`
+
+ Dictionary with configuration settings for rust-analyzer.
+
+===============================================================================
cargo *ale-rust-cargo*
g:ale_rust_cargo_use_check *g:ale_rust_cargo_use_check*
diff --git a/doc/ale-sh.txt b/doc/ale-sh.txt
index 3eac9038..c06f737a 100644
--- a/doc/ale-sh.txt
+++ b/doc/ale-sh.txt
@@ -3,6 +3,29 @@ ALE Shell Integration *ale-sh-options*
===============================================================================
+bashate *ale-sh-bashate*
+
+g:ale_sh_bashate_executable *g:ale_sh_bashate_executable*
+ *b:ale_sh_bashate_executable*
+ Type: |String|
+ Default: `'bashate'`
+
+ This variable sets executable used for bashate.
+
+
+g:ale_sh_bashate_options *g:ale_sh_bashate_options*
+ *b:ale_sh_bashate_options*
+ Type: |String|
+ Default: `''`
+
+ With this variable we are able to pass extra arguments for bashate. For
+ example to ignore the indentation rule:
+
+>
+ let g:ale_sh_bashate_options = '-i E003'
+<
+
+===============================================================================
sh-language-server *ale-sh-language-server*
g:ale_sh_language_server_executable *g:ale_sh_language_server_executable*
diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt
index b7542177..2dc05287 100644
--- a/doc/ale-supported-languages-and-tools.txt
+++ b/doc/ale-supported-languages-and-tools.txt
@@ -31,10 +31,13 @@ Notes:
* Awk
* `gawk`
* Bash
+ * `bashate`
* `language-server`
* `shell` (-n flag)
* `shellcheck`
* `shfmt`
+* Bats
+ * `shellcheck`
* BibTeX
* `bibclean`
* Bourne Shell
@@ -42,6 +45,7 @@ Notes:
* `shellcheck`
* `shfmt`
* C
+ * `astyle`
* `ccls`
* `clang`
* `clangd`
@@ -59,6 +63,7 @@ Notes:
* `mcsc`!!
* `uncrustify`
* C++ (filetype cpp)
+ * `astyle`
* `ccls`
* `clang`
* `clangcheck`!!
@@ -162,6 +167,7 @@ Notes:
* `gosimple`!!
* `gotype`!!
* `go vet`!!
+ * `revive`!!
* `staticcheck`!!
* GraphQL
* `eslint`
@@ -284,6 +290,7 @@ Notes:
* Nim
* `nim check`!!
* `nimlsp`
+ * `nimpretty`
* nix
* `nix-instantiate`
* `nixpkgs-fmt`
@@ -365,6 +372,7 @@ Notes:
* `pylint`!!
* `pyls`
* `pyre`
+ * `pyright`
* `reorder-python-imports`
* `vulture`!!
* `yapf`
@@ -407,6 +415,7 @@ Notes:
* Rust
* `cargo`!!
* `rls`
+ * `rust-analyzer`
* `rustc` (see |ale-integration-rust|)
* `rustfmt`
* Sass
@@ -468,12 +477,14 @@ Notes:
* `eslint`
* `fecs`
* `prettier`
+ * `standard`
* `tslint`
* `tsserver`
* `typecheck`
* VALA
* `uncrustify`
* Verilog
+ * `hdl-checker`
* `iverilog`
* `verilator`
* `vlog`
@@ -483,6 +494,7 @@ Notes:
* `vcom`
* `xvhdl`
* Vim
+ * `vimls`
* `vint`
* Vim help^
* `alex`!!
@@ -503,3 +515,5 @@ Notes:
* `yamllint`
* YANG
* `yang-lsp`
+* Zig
+ * `zls`
diff --git a/doc/ale-terraform.txt b/doc/ale-terraform.txt
index 387fd732..f62db190 100644
--- a/doc/ale-terraform.txt
+++ b/doc/ale-terraform.txt
@@ -33,6 +33,25 @@ g:ale_terraform_terraform_executable *g:ale_terraform_terraform_executable*
===============================================================================
+terraform-lsp *ale-terraform-terraform-lsp*
+
+g:ale_terraform_langserver_executable *g:ale_terraform_langserver_executable*
+ *b:ale_terraform_langserver_executable*
+ Type: |String|
+ Default: `'terraform-lsp'`
+
+ This variable can be changed to use a different executable for terraform-lsp.
+
+
+g:ale_terraform_langserver_options *g:ale_terraform_langserver_options*
+ *b:ale_terraform_langserver_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be changed to pass custom CLI flags to terraform-lsp.
+
+
+===============================================================================
tflint *ale-terraform-tflint*
g:ale_terraform_tflint_executable *g:ale_terraform_tflint_executable*
diff --git a/doc/ale-typescript.txt b/doc/ale-typescript.txt
index 7dc59820..2c50d119 100644
--- a/doc/ale-typescript.txt
+++ b/doc/ale-typescript.txt
@@ -17,6 +17,33 @@ See |ale-javascript-prettier| for information about the available options.
===============================================================================
+standard *ale-typescript-standard*
+
+g:ale_typescript_standard_executable *g:ale_typescript_standard_executable*
+ *b:ale_typescript_standard_executable*
+ Type: |String|
+ Default: `'standard'`
+
+ See |ale-integrations-local-executables|
+
+
+g:ale_typescript_standard_options *g:ale_typescript_standard_options*
+ *b:ale_typescript_standard_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be set to pass additional options to standard.
+
+
+g:ale_typescript_standard_use_global *g:ale_typescript_standard_use_global*
+ *b:ale_typescript_standard_use_global*
+ Type: |Number|
+ Default: `get(g:, 'ale_use_global_executables', 0)`
+
+ See |ale-integrations-local-executables|
+
+
+===============================================================================
tslint *ale-typescript-tslint*
This linter isn't recommended, because TSLint can't be used for checking for
diff --git a/doc/ale-verilog.txt b/doc/ale-verilog.txt
index 94b820b8..01af63c2 100644
--- a/doc/ale-verilog.txt
+++ b/doc/ale-verilog.txt
@@ -3,7 +3,10 @@ ALE Verilog/SystemVerilog Integration *ale-verilog-options*
===============================================================================
-ALE can use four different linters for Verilog HDL:
+ALE can use five different linters for Verilog HDL:
+
+ HDL Checker
+ Using `hdl_checker --lsp`
iverilog:
Using `iverilog -t null -Wall`
@@ -26,6 +29,9 @@ defining 'g:ale_linters' variable:
\ let g:ale_linters = {'systemverilog' : ['verilator'],}
<
+===============================================================================
+General notes
+
Linters/compilers that utilize a "work" directory for analyzing designs- such
as ModelSim and Vivado- can be passed the location of these directories as
part of their respective option strings listed below. This is useful for
@@ -40,6 +46,16 @@ changing. This can happen in the form of hangs or crashes. To help prevent
this when using these linters, it may help to run linting less frequently; for
example, only when a file is saved.
+HDL Checker is an alternative for some of the issues described above. It wraps
+around ghdl, Vivado and ModelSim/Questa and, when using the latter, it can
+handle mixed language (VHDL, Verilog, SystemVerilog) designs.
+
+===============================================================================
+hdl-checker *ale-verilog-hdl-checker*
+
+See |ale-vhdl-hdl-checker|
+
+
===============================================================================
iverilog *ale-verilog-iverilog*
diff --git a/doc/ale-vhdl.txt b/doc/ale-vhdl.txt
index 3fea947d..c2870240 100644
--- a/doc/ale-vhdl.txt
+++ b/doc/ale-vhdl.txt
@@ -3,10 +3,10 @@ ALE VHDL Integration *ale-vhdl-options*
===============================================================================
-ALE can use three different linters for VHDL:
+ALE can use four different linters for VHDL:
- iverilog:
- Using `iverilog -t null -Wall`
+ ghdl:
+ Using `ghdl --std=08`
ModelSim/Questa
Using `vcom -2008 -quiet -lint`
@@ -14,8 +14,15 @@ ALE can use three different linters for VHDL:
Vivado
Using `xvhdl --2008`
-Note all linters default to VHDL-2008 support. This, and other options, can be
-changed with each linter's respective option variable.
+ HDL Checker
+ Using `hdl_checker --lsp`
+
+===============================================================================
+General notes
+
+ghdl, ModelSim/Questa and Vivado linters default to VHDL-2008 support. This,
+and other options, can be changed with each linter's respective option
+variable.
Linters/compilers that utilize a "work" directory for analyzing designs- such
as ModelSim and Vivado- can be passed the location of these directories as
@@ -31,6 +38,10 @@ changing. This can happen in the form of hangs or crashes. To help prevent
this when using these linters, it may help to run linting less frequently; for
example, only when a file is saved.
+HDL Checker is an alternative for some of the issues described above. It wraps
+around ghdl, Vivado and ModelSim/Questa and, when using the latter, it can
+handle mixed language (VHDL, Verilog, SystemVerilog) designs.
+
===============================================================================
ghdl *ale-vhdl-ghdl*
@@ -51,6 +62,60 @@ g:ale_vhdl_ghdl_options *g:ale_vhdl_ghdl_options*
===============================================================================
+hdl-checker *ale-vhdl-hdl-checker*
+
+HDL Checker is a wrapper for VHDL/Verilg/SystemVerilog tools that aims to
+reduce the boilerplate code needed to set things up. It can automatically
+infer libraries for VHDL sources, determine the compilation order and provide
+some static checks.
+
+You can install it using pip:
+>
+ $ pip install hdl-checker
+
+`hdl-checker` will be run from a detected project root, determined by the
+following methods, in order:
+
+1. Find the first directory containing a configuration file (see
+ |g:ale_hdl_checker_config_file|)
+2. If no configuration file can be found, find the first directory containing
+ a folder named `'.git'
+3. If no such folder is found, use the directory of the current buffer
+
+
+g:ale_hdl_checker_executable
+ *g:ale_hdl_checker_executable*
+ *b:ale_hdl_checker_executable*
+ Type: |String|
+ Default: `'hdl_checker'`
+
+ This variable can be changed to the path to the 'hdl_checker' executable.
+
+
+g:ale_hdl_checker_options *g:ale_hdl_checker_options*
+ *b:ale_hdl_checker_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be changed to modify the flags/options passed to the
+ 'hdl_checker' server startup command.
+
+
+g:ale_hdl_checker_config_file *g:ale_hdl_checker_config_file*
+ *b:ale_hdl_checker_config_file*
+ Type: |String|
+ Default: `'.hdl_checker.config'` (Unix),
+ `'_hdl_checker.config'` (Windows)
+
+ This variable can be changed to modify the config file HDL Checker will try
+ to look for. It will also affect how the project's root directory is
+ determined (see |ale-vhdl-hdl-checker|).
+
+ More info on the configuration file format can be found at:
+ https://github.com/suoto/hdl_checker/wiki/Setting-up-a-project
+
+
+===============================================================================
vcom *ale-vhdl-vcom*
g:ale_vhdl_vcom_executable *g:ale_vhdl_vcom_executable*
diff --git a/doc/ale-vim.txt b/doc/ale-vim.txt
index 772bad23..f85b43eb 100644
--- a/doc/ale-vim.txt
+++ b/doc/ale-vim.txt
@@ -3,6 +3,61 @@ ALE Vim Integration *ale-vim-options*
===============================================================================
+vimls *ale-vim-vimls*
+
+ The `vim-language-server` is the engine that powers VimL editor support
+ using the Language Server Protocol. See the installation instructions:
+ https://github.com/iamcco/vim-language-server#install
+
+g:ale_vim_vimls_executable *g:ale_vim_vimls_executable*
+ *b:ale_vim_vimls_executable*
+ Type: |String|
+ Default: `'vim-language-server'`
+
+ This option can be set to change the executable path for vimls.
+
+
+g:ale_vim_vimls_config *g:ale_vim_vimls_config*
+ *b:ale_vim_vimls_config*
+ Type: |Dictionary|
+ Default: `{}`
+
+ Dictionary containing configuration settings that will be passed to the
+ language server. For example: >
+ {
+ \ 'vim': {
+ \ 'iskeyword': '@,48-57,_,192-255,-#',
+ \ 'vimruntime': '',
+ \ 'runtimepath': '',
+ \ 'diagnostic': {
+ \ 'enable': v:true
+ \ },
+ \ 'indexes': {
+ \ 'runtimepath': v:true,
+ \ 'gap': 100,
+ \ 'count': 3,
+ \ 'projectRootPatterns' : ['.git', 'autoload', 'plugin']
+ \ },
+ \ 'suggest': {
+ \ 'fromVimruntime': v:true,
+ \ 'fromRuntimepath': v:false
+ \ },
+ \ }
+ \}
+<
+ Consult the vim-language-server documentation for more information about
+ settings.
+
+
+g:ale_vim_vimls_use_global *g:ale_vim_vimls_use_global*
+ *b:ale_vim_vimls_use_global*
+ Type: |Number|
+ Default: `get(g:, 'ale_use_global_executables', 0)`
+
+ See |ale-integrations-local-executables|
+
+
+===============================================================================
vint *ale-vim-vint*
g:ale_vim_vint_executable *g:ale_vim_vint_executable*
diff --git a/doc/ale-zig.txt b/doc/ale-zig.txt
new file mode 100644
index 00000000..70a53bbb
--- /dev/null
+++ b/doc/ale-zig.txt
@@ -0,0 +1,33 @@
+===============================================================================
+ALE Zig Integration *ale-zig-options*
+ *ale-integration-zig*
+
+===============================================================================
+Integration Information
+
+ Currently, the only supported linter for zig is zls.
+
+===============================================================================
+zls *ale-zig-zls*
+
+g:ale_zig_zls_executable *g:ale_zig_zls_executable*
+ *b:ale_zig_zls_executable*
+ Type: |String|
+ Default: `'zls'`
+
+ This variable can be modified to change the executable path for `zls`.
+
+
+g:ale_zig_zls_config *g:ale_zig_zls_config*
+ *b:ale_zig_zls_config*
+ Type: |Dictionary|
+ Default: `{}`
+
+ WARNING: As of writing, zls does not support receiving configuration
+ from the client. This variable is a PLACEHOLDER until it does.
+
+ Dictionary with configuration settings for zls.
+
+
+===============================================================================
+ vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/doc/ale.txt b/doc/ale.txt
index c1cf928b..3b90e7e0 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -127,7 +127,7 @@ their relevant options.
* By showing balloons for your mouse cursor - |g:ale_set_balloons|
Please consult the documentation for each option, which can reveal some other
-ways of tweaking the behaviour of each way of displaying problems. You can
+ways of tweaking the behavior of each way of displaying problems. You can
disable or enable whichever options you prefer.
Most settings can be configured for each buffer. (|b:| instead of |g:|),
@@ -435,17 +435,54 @@ vimrc, and your issues should go away. >
set completeopt=menu,menuone,preview,noselect,noinsert
<
+Or alternatively, if you want to show documentation in popups: >
+
+ set completeopt=menu,menuone,popup,noselect,noinsert
+<
+ *ale-symbols*
+
+ALE provides a set of basic completion symbols. If you want to replace those
+symbols with others, you can set the variable |g:ale_completion_symbols| with
+a mapping of the type of completion to the symbol or other string that you
+would like to use. An example here shows the available options for symbols >
+
+ let g:ale_completion_symbols = {
+ \ 'text': '',
+ \ 'method': '',
+ \ 'function': '',
+ \ 'constructor': '',
+ \ 'field': '',
+ \ 'variable': '',
+ \ 'class': '',
+ \ 'interface': '',
+ \ 'module': '',
+ \ 'property': '',
+ \ 'unit': 'unit',
+ \ 'value': 'val',
+ \ 'enum': '',
+ \ 'keyword': 'keyword',
+ \ 'snippet': '',
+ \ 'color': 'color',
+ \ 'file': '',
+ \ 'reference': 'ref',
+ \ 'folder': '',
+ \ 'enum member': '',
+ \ 'constant': '',
+ \ 'struct': '',
+ \ 'event': 'event',
+ \ 'operator': '',
+ \ 'type_parameter': 'type param',
+ \ '<default>': 'v'
+ \ }
+<
-------------------------------------------------------------------------------
5.2 Go To Definition *ale-go-to-definition*
ALE supports jumping to the files and locations where symbols are defined
through any enabled LSP linters. The locations ALE will jump to depend on the
-information returned by LSP servers. The following commands are supported:
-
-|ALEGoToDefinition| - Open the definition of the symbol under the cursor.
-|ALEGoToDefinitionInTab| - The same, but for opening the file in a new tab.
-|ALEGoToDefinitionInSplit| - The same, but in a new split.
-|ALEGoToDefinitionInVSplit| - The same, but in a new vertical split.
+information returned by LSP servers. The |ALEGoToDefinition| command will jump
+to the definition of symbols under the cursor. See the documentation for the
+command for configuring how the location will be displayed.
ALE will update Vim's |tagstack| automatically unless |g:ale_update_tagstack| is
set to `0`.
@@ -455,15 +492,10 @@ set to `0`.
ALE supports jumping to the files and locations where symbols' types are
defined through any enabled LSP linters. The locations ALE will jump to depend
-on the information returned by LSP servers. The following commands are
-supported:
-
-|ALEGoToTypeDefinition| - Open the definition of the symbol's type under
- the cursor.
-|ALEGoToTypeDefinitionInTab| - The same, but for opening the file in a new tab.
-|ALEGoToTypeDefinitionInSplit| - The same, but in a new split.
-|ALEGoToTypeDefinitionInVSplit| - The same, but in a new vertical split.
-
+on the information returned by LSP servers. The |ALEGoToTypeDefinition|
+command will jump to the definition of symbols under the cursor. See the
+documentation for the command for configuring how the location will be
+displayed.
-------------------------------------------------------------------------------
5.4 Find References *ale-find-references*
@@ -486,12 +518,19 @@ at the cursor taken from LSP linters. The following commands are supported:
|ALEHover| - Print information about the symbol at the cursor.
+Truncated information will be displayed when the cursor rests on a symbol by
+default, as long as there are no problems on the same line. You can disable
+this behavior by setting |g:ale_hover_cursor| to `0`.
+
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.
+Hover information can be displayed in the preview window instead by setting
+|g:ale_hover_to_preview| to `1`.
+
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
@@ -625,7 +664,7 @@ g:ale_completion_delay *g:ale_completion_delay*
g:ale_completion_enabled *g:ale_completion_enabled*
-b:ale_completion_enabled *b:ale_completion_enabled*
+ *b:ale_completion_enabled*
Type: |Number|
Default: `0`
@@ -681,6 +720,47 @@ g:ale_completion_excluded_words *g:ale_completion_excluded_words*
let b:ale_completion_excluded_words = ['it', 'describe']
<
+g:ale_completion_symbols *g:ale_completion_symbols*
+
+ Type: |Dictionary|
+
+
+ A mapping from completion types to symbols for completions. See
+ |ale-symbols| for more information.
+
+ By default, this mapping only uses built in Vim completion kinds, but it can
+ be updated to use any unicode character for the completion kind. For
+ example: >
+ let g:ale_completion_symbols = {
+ \ 'text': '',
+ \ 'method': '',
+ \ 'function': '',
+ \ 'constructor': '',
+ \ 'field': '',
+ \ 'variable': '',
+ \ 'class': '',
+ \ 'interface': '',
+ \ 'module': '',
+ \ 'property': '',
+ \ 'unit': 'v',
+ \ 'value': 'v',
+ \ 'enum': 't',
+ \ 'keyword': 'v',
+ \ 'snippet': 'v',
+ \ 'color': 'v',
+ \ 'file': 'v',
+ \ 'reference': 'v',
+ \ 'folder': 'v',
+ \ 'enum_member': 'm',
+ \ 'constant': 'm',
+ \ 'struct': 't',
+ \ 'event': 'v',
+ \ 'operator': 'f',
+ \ 'type_parameter': 'p',
+ \ '<default>': 'v'
+ \ })
+<
+
g:ale_completion_max_suggestions *g:ale_completion_max_suggestions*
Type: |Number|
@@ -719,6 +799,16 @@ g:ale_cursor_detail *g:ale_cursor_detail*
loaded for messages to be displayed. See |ale-lint-settings-on-startup|.
+g:ale_default_navigation *g:ale_default_navigation*
+ *b:ale_default_navigation*
+
+ Type: |String|
+ Default: `'buffer'`
+
+ The default method for navigating away from the current buffer to another
+ buffer, such as for |ALEFindReferences:|, or |ALEGoToDefinition|.
+
+
g:ale_disable_lsp *g:ale_disable_lsp*
*b:ale_disable_lsp*
@@ -771,7 +861,7 @@ g:ale_echo_msg_error_str *g:ale_echo_msg_error_str*
g:ale_echo_msg_format *g:ale_echo_msg_format*
-b:ale_echo_msg_format *b:ale_echo_msg_format*
+ *b:ale_echo_msg_format*
Type: |String|
Default: `'%code: %%s'`
@@ -849,6 +939,21 @@ g:ale_enabled *g:ale_enabled*
See |g:ale_pattern_options| for more information on that option.
+g:ale_exclude_highlights *g:ale_exclude_highlights*
+ *b:ale_exclude_highlights*
+
+ Type: |List|
+ Default: `[]`
+
+ A list of regular expressions for matching against highlight messages to
+ remove. For example: >
+
+ " Do not highlight messages matching strings like these.
+ let b:ale_exclude_highlights = ['line too long', 'foo.*bar']
+<
+ See also: |g:ale_set_highlights|
+
+
g:ale_fixers *g:ale_fixers*
*b:ale_fixers*
@@ -872,7 +977,7 @@ g:ale_fixers *g:ale_fixers*
<
g:ale_fix_on_save *g:ale_fix_on_save*
-b:ale_fix_on_save *b:ale_fix_on_save*
+ *b:ale_fix_on_save*
Type: |Number|
Default: `0`
@@ -894,7 +999,7 @@ b:ale_fix_on_save *b:ale_fix_on_save*
g:ale_fix_on_save_ignore *g:ale_fix_on_save_ignore*
-b:ale_fix_on_save_ignore *b:ale_fix_on_save_ignore*
+ *b:ale_fix_on_save_ignore*
Type: |Dictionary| or |List|
Default: `{}`
@@ -957,6 +1062,34 @@ g:ale_history_log_output *g:ale_history_log_output*
if you want to save on some memory usage.
+g:ale_hover_cursor *g:ale_hover_cursor*
+
+ Type: |Number|
+ Default: `1`
+
+ If set to `1`, ALE will show truncated information in the echo line about
+ the symbol at the cursor automatically when the |CursorHold| event is fired.
+ The delay before requesting hover information is based on 'updatetime', as
+ with all |CursorHold| events.
+
+ If there's a problem on the line where the cursor is resting, ALE will not
+ show any hover information.
+
+ See |ale-hover| for more information on hover information.
+
+ This setting must be set to `1` before ALE is loaded for this behavior
+ to be enabled. See |ale-lint-settings-on-startup|.
+
+
+g:ale_hover_to_preview *g:ale_hover_to_preview*
+ *b:ale_hover_to_preview*
+ Type: |Number|
+ Default: `0`
+
+ If set to `1`, hover messages will be displayed in the preview window,
+ instead of in balloons or the message line.
+
+
g:ale_keep_list_window_open *g:ale_keep_list_window_open*
*b:ale_keep_list_window_open*
Type: |Number|
@@ -1167,7 +1300,7 @@ g:ale_linters *g:ale_linters*
\ 'help': [],
\ 'perl': ['perlcritic'],
\ 'perl6': [],
- \ 'python': ['flake8', 'mypy', 'pylint'],
+ \ 'python': ['flake8', 'mypy', 'pylint', 'pyright'],
\ 'rust': ['cargo'],
\ 'spec': [],
\ 'text': [],
@@ -1260,7 +1393,7 @@ g:ale_list_vertical *g:ale_list_vertical*
g:ale_loclist_msg_format *g:ale_loclist_msg_format*
-b:ale_loclist_msg_format *b:ale_loclist_msg_format*
+ *b:ale_loclist_msg_format*
Type: |String|
Default: `g:ale_echo_msg_format`
@@ -1271,7 +1404,7 @@ b:ale_loclist_msg_format *b:ale_loclist_msg_format*
The strings for configuring `%severity%` are also used for this option.
-g:ale_lsp_show_message_format *g:ale_lsp_show_message_format*
+g:ale_lsp_show_message_format *g:ale_lsp_show_message_format*
Type: |String|
Default: `'%severity%:%linter%: %s'`
@@ -1293,7 +1426,7 @@ g:ale_lsp_show_message_format *g:ale_lsp_show_message_
separately for each buffer like |g:ale_echo_msg_format| can.
-g:ale_lsp_show_message_severity *g:ale_lsp_show_message_severity*
+g:ale_lsp_show_message_severity *g:ale_lsp_show_message_severity*
Type: |String|
Default: `'error'`
@@ -1312,7 +1445,7 @@ g:ale_lsp_show_message_severity *g:ale_lsp_show_message_
g:ale_lsp_root *g:ale_lsp_root*
-b:ale_lsp_root *b:ale_lsp_root*
+ *b:ale_lsp_root*
Type: |Dictionary| or |String|
Default: {}
@@ -1525,6 +1658,8 @@ g:ale_set_highlights *g:ale_set_highlights*
match highlights, whereas the line highlights when signs are enabled will
run to the edge of the screen.
+ Highlights can be excluded with the |g:ale_exclude_highlights| option.
+
g:ale_set_loclist *g:ale_set_loclist*
@@ -1791,7 +1926,8 @@ g:ale_virtualtext_cursor *g:ale_virtualtext_cursor*
g:ale_virtualtext_delay *g:ale_virtualtext_delay*
-b:ale_virtualtext_delay *b:ale_virtualtext_delay*
+ *b:ale_virtualtext_delay*
+
Type: |Number|
Default: `10`
@@ -1810,7 +1946,7 @@ g:ale_virtualtext_prefix *g:ale_virtualtext_prefix*
Prefix to be used with |g:ale_virtualtext_cursor|.
g:ale_virtualenv_dir_names *g:ale_virtualenv_dir_names*
-b:ale_virtualenv_dir_names *b:ale_virtualenv_dir_names*
+ *b:ale_virtualenv_dir_names*
Type: |List|
Default: `['.env', '.venv', 'env', 've-py3', 've', 'virtualenv', 'venv']`
@@ -1824,7 +1960,7 @@ b:ale_virtualenv_dir_names *b:ale_virtualenv_dir_names*
g:ale_warn_about_trailing_blank_lines *g:ale_warn_about_trailing_blank_lines*
-b:ale_warn_about_trailing_blank_lines *b:ale_warn_about_trailing_blank_lines*
+ *b:ale_warn_about_trailing_blank_lines*
Type: |Number|
Default: `1`
@@ -1836,7 +1972,7 @@ b:ale_warn_about_trailing_blank_lines *b:ale_warn_about_trailing_blank_lines*
g:ale_warn_about_trailing_whitespace *g:ale_warn_about_trailing_whitespace*
-b:ale_warn_about_trailing_whitespace *b:ale_warn_about_trailing_whitespace*
+ *b:ale_warn_about_trailing_whitespace*
Type: |Number|
Default: `1`
@@ -2175,9 +2311,12 @@ documented in additional help files.
gcc...................................|ale-asm-gcc|
awk.....................................|ale-awk-options|
gawk..................................|ale-awk-gawk|
+ bats....................................|ale-bats-options|
+ shellcheck............................|ale-bats-shellcheck|
bib.....................................|ale-bib-options|
bibclean..............................|ale-bib-bibclean|
c.......................................|ale-c-options|
+ astyle................................|ale-c-astyle|
clang.................................|ale-c-clang|
clangd................................|ale-c-clangd|
clang-format..........................|ale-c-clangformat|
@@ -2200,6 +2339,7 @@ documented in additional help files.
cmakelint.............................|ale-cmake-cmakelint|
cmake-format..........................|ale-cmake-cmakeformat|
cpp.....................................|ale-cpp-options|
+ astyle................................|ale-cpp-astyle|
clang.................................|ale-cpp-clang|
clangd................................|ale-cpp-clangd|
clangcheck............................|ale-cpp-clangcheck|
@@ -2273,6 +2413,7 @@ documented in additional help files.
gometalinter..........................|ale-go-gometalinter|
gopls.................................|ale-go-gopls|
govet.................................|ale-go-govet|
+ revive................................|ale-go-revive|
staticcheck...........................|ale-go-staticcheck|
graphql.................................|ale-graphql-options|
eslint................................|ale-graphql-eslint|
@@ -2371,6 +2512,7 @@ documented in additional help files.
nim.....................................|ale-nim-options|
nimcheck..............................|ale-nim-nimcheck|
nimlsp................................|ale-nim-nimlsp|
+ nimpretty.............................|ale-nim-nimpretty|
nix.....................................|ale-nix-options|
nixpkgs-fmt...........................|ale-nix-nixpkgs-fmt|
nroff...................................|ale-nroff-options|
@@ -2446,6 +2588,7 @@ documented in additional help files.
pylint................................|ale-python-pylint|
pyls..................................|ale-python-pyls|
pyre..................................|ale-python-pyre|
+ pyright...............................|ale-python-pyright|
reorder-python-imports................|ale-python-reorder_python_imports|
vulture...............................|ale-python-vulture|
yapf..................................|ale-python-yapf|
@@ -2474,6 +2617,7 @@ documented in additional help files.
sorbet................................|ale-ruby-sorbet|
standardrb............................|ale-ruby-standardrb|
rust....................................|ale-rust-options|
+ analyzer..............................|ale-rust-analyzer|
cargo.................................|ale-rust-cargo|
rls...................................|ale-rust-rls|
rustc.................................|ale-rust-rustc|
@@ -2491,6 +2635,7 @@ documented in additional help files.
sasslint..............................|ale-scss-sasslint|
stylelint.............................|ale-scss-stylelint|
sh......................................|ale-sh-options|
+ bashate...............................|ale-sh-bashate|
sh-language-server....................|ale-sh-language-server|
shell.................................|ale-sh-shell|
shellcheck............................|ale-sh-shellcheck|
@@ -2518,6 +2663,7 @@ documented in additional help files.
terraform...............................|ale-terraform-options|
terraform-fmt-fixer...................|ale-terraform-fmt-fixer|
terraform.............................|ale-terraform-terraform|
+ terraform-lsp.........................|ale-terraform-terraform-lsp|
tflint................................|ale-terraform-tflint|
tex.....................................|ale-tex-options|
chktex................................|ale-tex-chktex|
@@ -2534,20 +2680,24 @@ documented in additional help files.
typescript..............................|ale-typescript-options|
eslint................................|ale-typescript-eslint|
prettier..............................|ale-typescript-prettier|
+ standard..............................|ale-typescript-standard|
tslint................................|ale-typescript-tslint|
tsserver..............................|ale-typescript-tsserver|
vala....................................|ale-vala-options|
uncrustify............................|ale-vala-uncrustify|
verilog/systemverilog...................|ale-verilog-options|
+ hdl-checker...........................|ale-verilog-hdl-checker|
iverilog..............................|ale-verilog-iverilog|
verilator.............................|ale-verilog-verilator|
vlog..................................|ale-verilog-vlog|
xvlog.................................|ale-verilog-xvlog|
vhdl....................................|ale-vhdl-options|
ghdl..................................|ale-vhdl-ghdl|
+ hdl-checker...........................|ale-vhdl-hdl-checker|
vcom..................................|ale-vhdl-vcom|
xvhdl.................................|ale-vhdl-xvhdl|
vim.....................................|ale-vim-options|
+ vimls.................................|ale-vim-vimls|
vint..................................|ale-vim-vint|
vim help................................|ale-vim-help-options|
write-good............................|ale-vim-help-write-good|
@@ -2564,6 +2714,8 @@ documented in additional help files.
yamllint..............................|ale-yaml-yamllint|
yang....................................|ale-yang-options|
yang-lsp..............................|ale-yang-lsp|
+ zig.....................................|ale-zig-options|
+ zls...................................|ale-zig-zls|
===============================================================================
@@ -2601,11 +2753,23 @@ ALEFindReferences *ALEFindReferences*
Enter key (`<CR>`) can be used to jump to a referencing location, or the `t`
key can be used to jump to the location in a new tab.
+ The locations opened in different ways using the following variations.
+
+ `:ALEFindReferences -tab` - Open the location in a new tab.
+ `:ALEFindReferences -split` - Open the location in a horizontal split.
+ `:ALEFindReferences -vsplit` - Open the location in a vertical split.
+
+ The default method used for navigating to a new location can be changed
+ by modifying |g:ale_default_navigation|.
+
+ The selection can be opened again with the |ALERepeatSelection| command.
+
You can jump back to the position you were at before going to a reference of
something with jump motions like CTRL-O. See |jump-motions|.
A plug mapping `<Plug>(ale_find_references)` is defined for this command.
+
ALEFix *ALEFix*
Fix problems with the current buffer. See |ale-fix| for more information.
@@ -2620,40 +2784,29 @@ ALEFixSuggest *ALEFixSuggest*
See |ale-fix| for more information.
-ALEGoToDefinition *ALEGoToDefinition*
+ALEGoToDefinition `<options>` *ALEGoToDefinition*
Jump to the definition of a symbol under the cursor using the enabled LSP
linters for the buffer. ALE will jump to a definition if an LSP server
provides a location to jump to. Otherwise, ALE will do nothing.
- You can jump back to the position you were at before going to the definition
- of something with jump motions like CTRL-O. See |jump-motions|.
-
- A plug mapping `<Plug>(ale_go_to_definition)` is defined for this command.
-
-
-ALEGoToDefinitionInTab *ALEGoToDefinitionInTab*
-
- The same as |ALEGoToDefinition|, but opens results in a new tab.
-
- A plug mapping `<Plug>(ale_go_to_definition_in_tab)` is defined for this
- command.
+ The locations opened in different ways using the following variations.
+ `:ALEGoToDefinition -tab` - Open the location in a new tab.
+ `:ALEGoToDefinition -split` - Open the location in a horizontal split.
+ `:ALEGoToDefinition -vsplit` - Open the location in a vertical split.
-ALEGoToDefinitionInSplit *ALEGoToDefinitionInSplit*
+ The default method used for navigating to a new location can be changed
+ by modifying |g:ale_default_navigation|.
- The same as |ALEGoToDefinition|, but opens results in a new split.
-
- A plug mapping `<Plug>(ale_go_to_definition_in_split)` is defined for this
- command.
-
-
-ALEGoToDefinitionInVSplit *ALEGoToDefinitionInVSplit*
+ You can jump back to the position you were at before going to the definition
+ of something with jump motions like CTRL-O. See |jump-motions|.
- The same as |ALEGoToDefinition|, but opens results in a new vertical split.
+ You should consider using the 'hidden' option in combination with this
+ command. Otherwise, Vim will refuse to leave the buffer you're jumping from
+ unless you have saved your edits.
- A plug mapping `<Plug>(ale_go_to_definition_in_vsplit)` is defined for this
- command.
+ A plug mapping `<Plug>(ale_go_to_definition)` is defined for this command.
ALEGoToTypeDefinition *ALEGoToTypeDefinition*
@@ -2663,6 +2816,15 @@ ALEGoToTypeDefinition *ALEGoToTypeDefinition*
definition if an LSP server provides a location to jump to. Otherwise, ALE
will do nothing.
+ The locations opened in different ways using the following variations.
+
+ `:ALEGoToTypeDefinition -tab` - Open the location in a new tab.
+ `:ALEGoToTypeDefinition -split` - Open the location in a horizontal split.
+ `:ALEGoToTypeDefinition -vsplit` - Open the location in a vertical split.
+
+ The default method used for navigating to a new location can be changed
+ by modifying |g:ale_default_navigation|.
+
You can jump back to the position you were at before going to the definition
of something with jump motions like CTRL-O. See |jump-motions|.
@@ -2670,31 +2832,6 @@ ALEGoToTypeDefinition *ALEGoToTypeDefinition*
command.
-ALEGoToTypeDefinitionInTab *ALEGoToTypeDefinitionInTab*
-
- The same as |ALEGoToTypeDefinition|, but opens results in a new tab.
-
- A plug mapping `<Plug>(ale_go_to_type_definition_in_tab)` is defined for
- this command.
-
-
-ALEGoToTypeDefinitionInSplit *ALEGoToTypeDefinitionInSplit*
-
- The same as |ALEGoToTypeDefinition|, but opens results in a new split.
-
- A plug mapping `<Plug>(ale_go_to_type_definition_in_split)` is defined for
- this command.
-
-
-ALEGoToTypeDefinitionInVSplit *ALEGoToTypeDefinitionInVSplit*
-
- The same as |ALEGoToTypeDefinition|, but opens results in a new vertical
- split.
-
- A plug mapping `<Plug>(ale_go_to_type_definition_in_vsplit)` is defined for
- this command.
-
-
ALEHover *ALEHover*
Print brief information about the symbol under the cursor, taken from any
@@ -2720,6 +2857,11 @@ ALERename *ALERename*
The user will be prompted for a new name.
+ALERepeatSelection *ALERepeatSelection*
+
+ Repeat the last selection displayed in the preview window.
+
+
ALESymbolSearch `<query>` *ALESymbolSearch*
Search for symbols in the workspace, taken from any available LSP linters.
@@ -2756,7 +2898,7 @@ ALELast *ALELast*
the last or first warning or error in the file, respectively.
`ALEPrevious` and `ALENext` take optional flags arguments to custom their
- behaviour :
+ behavior :
`-wrap` enable wrapping around the file
`-error`, `-warning` and `-info` enable jumping to errors, warnings or infos
respectively, ignoring anything else. They are mutually exclusive and if
@@ -3028,7 +3170,6 @@ ale#command#Run(buffer, command, callback, [options]) *ale#command#Run()*
'command': {b -> ale#command#Run(b, 'foo', function('s:GetCommand'))}
<
-
The following `options` can be provided.
`output_stream` - Either `'stdout'`, `'stderr'`, `'both'`, or `'none`' for
@@ -3399,7 +3540,7 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
contents of the buffer being checked. All occurrences of `%t` in command
strings will reference the one temporary file. The temporary file will be
created inside a temporary directory, and the entire temporary directory
- will be automatically deleted, following the behaviour of
+ will be automatically deleted, following the behavior of
|ale#command#ManageDirectory|. This option can be used for some linters which
do not support reading from stdin.
@@ -3424,7 +3565,6 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
be used to replace those characters to avoid formatting issues.
*ale-linter-loading-behavior*
- *ale-linter-loading-behaviour*
Linters for ALE will be loaded by searching |runtimepath| in the following
format: >
diff --git a/ftplugin/ale-preview-selection.vim b/ftplugin/ale-preview-selection.vim
index d77b4f98..7ec84068 100644
--- a/ftplugin/ale-preview-selection.vim
+++ b/ftplugin/ale-preview-selection.vim
@@ -12,5 +12,5 @@ noremap <buffer> A <NOP>
noremap <buffer> o <NOP>
noremap <buffer> O <NOP>
" Keybinds for opening selection items.
-noremap <buffer> <CR> :call ale#preview#OpenSelectionInBuffer()<CR>
+noremap <buffer> <CR> :call ale#preview#OpenSelection()<CR>
noremap <buffer> t :call ale#preview#OpenSelectionInTab()<CR>
diff --git a/plugin/ale.vim b/plugin/ale.vim
index 1912a9c0..65c5a77c 100644
--- a/plugin/ale.vim
+++ b/plugin/ale.vim
@@ -109,6 +109,9 @@ let g:ale_set_signs = get(g:, 'ale_set_signs', has('signs'))
" This flag can be set to 0 to disable setting error highlights.
let g:ale_set_highlights = get(g:, 'ale_set_highlights', has('syntax'))
+" This List can be configured to exclude particular highlights.
+let g:ale_exclude_highlights = get(g:, 'ale_exclude_highlights', [])
+
" This flag can be set to 0 to disable echoing when the cursor moves.
let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', 1)
@@ -118,6 +121,9 @@ let g:ale_cursor_detail = get(g:, 'ale_cursor_detail', 0)
" This flag can be set to 1 to enable virtual text when the cursor moves.
let g:ale_virtualtext_cursor = get(g:, 'ale_virtualtext_cursor', 0)
+" This flag can be set to 1 to enable LSP hover messages at the cursor.
+let g:ale_hover_cursor = get(g:, 'ale_hover_cursor', 1)
+
" This flag can be set to 1 to automatically close the preview window upon
" entering Insert Mode.
let g:ale_close_preview_on_insert = get(g:, 'ale_close_preview_on_insert', 0)
@@ -125,6 +131,9 @@ let g:ale_close_preview_on_insert = get(g:, 'ale_close_preview_on_insert', 0)
" This flag can be set to 0 to disable balloon support.
let g:ale_set_balloons = get(g:, 'ale_set_balloons', has('balloon_eval') && has('gui_running'))
+" Use preview window for hover messages.
+let g:ale_hover_to_preview = get(g:, 'ale_hover_to_preview', 0)
+
" This flag can be set to 0 to disable warnings for trailing whitespace
let g:ale_warn_about_trailing_whitespace = get(g:, 'ale_warn_about_trailing_whitespace', 1)
" This flag can be set to 0 to disable warnings for trailing blank lines
@@ -196,16 +205,23 @@ command! -bar -nargs=* -complete=customlist,ale#fix#registry#CompleteFixers ALEF
command! -bar ALEFixSuggest :call ale#fix#registry#Suggest(&filetype)
" Go to definition for tsserver and LSP
-command! -bar ALEGoToDefinition :call ale#definition#GoTo({})
-command! -bar ALEGoToDefinitionInTab :call ale#definition#GoTo({'open_in': 'tab'})
-command! -bar ALEGoToDefinitionInSplit :call ale#definition#GoTo({'open_in': 'horizontal-split'})
-command! -bar ALEGoToDefinitionInVSplit :call ale#definition#GoTo({'open_in': 'vertical-split'})
+command! -bar -nargs=* ALEGoToDefinition :call ale#definition#GoToCommandHandler('', <f-args>)
+
+" Deprecated commands we have to keep for now.
+command! -bar ALEGoToDefinitionInTab :call ale#definition#GoTo({'open_in': 'tab', 'deprecated_command': 'ALEGoToDefinitionInTab'})
+command! -bar ALEGoToDefinitionInSplit :call ale#definition#GoTo({'open_in': 'split', 'deprecated_command': 'ALEGoToDefinitionInSplit'})
+command! -bar ALEGoToDefinitionInVSplit :call ale#definition#GoTo({'open_in': 'vsplit', 'deprecated_command': 'ALEGoToDefinitionInVSplit'})
" Go to type definition for tsserver and LSP
-command! -bar ALEGoToTypeDefinition :call ale#definition#GoToType({})
-command! -bar ALEGoToTypeDefinitionInTab :call ale#definition#GoToType({'open_in': 'tab'})
-command! -bar ALEGoToTypeDefinitionInSplit :call ale#definition#GoToType({'open_in': 'horizontal-split'})
-command! -bar ALEGoToTypeDefinitionInVSplit :call ale#definition#GoToType({'open_in': 'vertical-split'})
+command! -bar -nargs=* ALEGoToTypeDefinition :call ale#definition#GoToCommandHandler('type', <f-args>)
+
+" Deprecated commands we have to keep for now.
+command! -bar ALEGoToTypeDefinitionInTab :call ale#definition#GoToType({'open_in': 'tab', 'deprecated_command': 'ALEGoToTypeDefinitionInTab'})
+command! -bar ALEGoToTypeDefinitionInSplit :call ale#definition#GoToType({'open_in': 'split', 'deprecated_command': 'ALEGoToTypeDefinitionInSplit'})
+command! -bar ALEGoToTypeDefinitionInVSplit :call ale#definition#GoToType({'open_in': 'vsplit', 'deprecated_command': 'ALEGoToTypeDefinitionInVSplit'})
+
+" Repeat a previous selection in the preview window
+command! -bar ALERepeatSelection :call ale#preview#RepeatSelection()
" Find references for tsserver and LSP
command! -bar -nargs=* ALEFindReferences :call ale#references#Find(<f-args>)
@@ -254,18 +270,21 @@ nnoremap <silent> <Plug>(ale_lint) :ALELint<Return>
nnoremap <silent> <Plug>(ale_detail) :ALEDetail<Return>
nnoremap <silent> <Plug>(ale_fix) :ALEFix<Return>
nnoremap <silent> <Plug>(ale_go_to_definition) :ALEGoToDefinition<Return>
-nnoremap <silent> <Plug>(ale_go_to_definition_in_tab) :ALEGoToDefinitionInTab<Return>
-nnoremap <silent> <Plug>(ale_go_to_definition_in_split) :ALEGoToDefinitionInSplit<Return>
-nnoremap <silent> <Plug>(ale_go_to_definition_in_vsplit) :ALEGoToDefinitionInVSplit<Return>
nnoremap <silent> <Plug>(ale_go_to_type_definition) :ALEGoToTypeDefinition<Return>
-nnoremap <silent> <Plug>(ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinitionInTab<Return>
-nnoremap <silent> <Plug>(ale_go_to_type_definition_in_split) :ALEGoToTypeDefinitionInSplit<Return>
-nnoremap <silent> <Plug>(ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionInVSplit<Return>
nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return>
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
nnoremap <silent> <Plug>(ale_documentation) :ALEDocumentation<Return>
inoremap <silent> <Plug>(ale_complete) <C-\><C-O>:ALEComplete<Return>
nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
+nnoremap <silent> <Plug>(ale_repeat_selection) :ALERepeatSelection<Return>
+
+" Deprecated <Plug> mappings
+nnoremap <silent> <Plug>(ale_go_to_definition_in_tab) :ALEGoToDefinitionInTab<Return>
+nnoremap <silent> <Plug>(ale_go_to_definition_in_split) :ALEGoToDefinitionInSplit<Return>
+nnoremap <silent> <Plug>(ale_go_to_definition_in_vsplit) :ALEGoToDefinitionInVSplit<Return>
+nnoremap <silent> <Plug>(ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinitionInTab<Return>
+nnoremap <silent> <Plug>(ale_go_to_type_definition_in_split) :ALEGoToTypeDefinitionInSplit<Return>
+nnoremap <silent> <Plug>(ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionInVSplit<Return>
" Set up autocmd groups now.
call ale#events#Init()
diff --git a/rplugin/python3/deoplete/sources/ale.py b/rplugin/python3/deoplete/sources/ale.py
index 3955ed2d..ae1f4039 100644
--- a/rplugin/python3/deoplete/sources/ale.py
+++ b/rplugin/python3/deoplete/sources/ale.py
@@ -24,6 +24,7 @@ class Source(Base):
self.rank = 1000
self.is_bytepos = True
self.min_pattern_length = 1
+ self.is_volatile = True
# Do not forget to update s:trigger_character_map in completion.vim in
# updating entries in this map.
self.input_patterns = {
@@ -44,21 +45,16 @@ class Source(Base):
if not self.vim.call('ale#completion#CanProvideCompletions'):
return None
- if context.get('is_refresh'):
- context['is_async'] = False
+ event = context.get('event')
- if context['is_async']:
- # Result is the same as for omnifunc, or None.
+ if event == 'Async':
result = self.vim.call('ale#completion#GetCompletionResult')
+ return result or []
- if result is not None:
- context['is_async'] = False
-
- return result
- else:
- context['is_async'] = True
-
- # Request some completion results.
- self.vim.call('ale#completion#GetCompletions', 'deoplete')
+ if context.get('is_refresh'):
+ self.vim.command(
+ "call ale#completion#GetCompletions('ale-callback', " + \
+ "{'callback': {completions -> deoplete#auto_complete() }})"
+ )
return []
diff --git a/supported-tools.md b/supported-tools.md
index 324e2000..7fa6ec4f 100644
--- a/supported-tools.md
+++ b/supported-tools.md
@@ -40,10 +40,13 @@ formatting.
* Awk
* [gawk](https://www.gnu.org/software/gawk/)
* Bash
+ * [bashate](https://github.com/openstack/bashate)
* [language-server](https://github.com/mads-hartmann/bash-language-server)
* shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set)
* [shellcheck](https://www.shellcheck.net/)
* [shfmt](https://github.com/mvdan/sh)
+* Bats
+ * [shellcheck](https://www.shellcheck.net/)
* BibTeX
* [bibclean](http://ftp.math.utah.edu/pub/bibclean/)
* Bourne Shell
@@ -51,6 +54,7 @@ formatting.
* [shellcheck](https://www.shellcheck.net/)
* [shfmt](https://github.com/mvdan/sh)
* C
+ * [astyle](http://astyle.sourceforge.net/)
* [ccls](https://github.com/MaskRay/ccls)
* [clang](http://clang.llvm.org/)
* [clangd](https://clang.llvm.org/extra/clangd.html)
@@ -68,6 +72,7 @@ formatting.
* [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) :floppy_disk: see:`help ale-cs-mcsc` for details and configuration
* [uncrustify](https://github.com/uncrustify/uncrustify)
* C++ (filetype cpp)
+ * [astyle](http://astyle.sourceforge.net/)
* [ccls](https://github.com/MaskRay/ccls)
* [clang](http://clang.llvm.org/)
* [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) :floppy_disk:
@@ -171,6 +176,7 @@ formatting.
* [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) :warning: :floppy_disk:
* [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) :warning: :floppy_disk:
* [go vet](https://golang.org/cmd/vet/) :floppy_disk:
+ * [revive](https://github.com/mgechev/revive) :warning: :floppy_disk:
* [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) :warning: :floppy_disk:
* GraphQL
* [eslint](http://eslint.org/)
@@ -293,6 +299,7 @@ formatting.
* Nim
* [nim check](https://nim-lang.org/docs/nimc.html) :floppy_disk:
* [nimlsp](https://github.com/PMunch/nimlsp)
+ * nimpretty
* nix
* [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate)
* [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt)
@@ -374,6 +381,7 @@ formatting.
* [pylint](https://www.pylint.org/) :floppy_disk:
* [pyls](https://github.com/palantir/python-language-server) :warning:
* [pyre](https://github.com/facebook/pyre-check) :warning:
+ * [pyright](https://github.com/microsoft/pyright)
* [reorder-python-imports](https://github.com/asottile/reorder_python_imports)
* [vulture](https://github.com/jendrikseipp/vulture) :warning: :floppy_disk:
* [yapf](https://github.com/google/yapf)
@@ -416,6 +424,7 @@ formatting.
* Rust
* [cargo](https://github.com/rust-lang/cargo) :floppy_disk: (see `:help ale-integration-rust` for configuration instructions)
* [rls](https://github.com/rust-lang-nursery/rls) :warning:
+ * [rust-analyzer](https://github.com/rust-analyzer/rust-analyzer) :warning:
* [rustc](https://www.rust-lang.org/) :warning:
* [rustfmt](https://github.com/rust-lang-nursery/rustfmt)
* Sass
@@ -477,12 +486,14 @@ formatting.
* [eslint](http://eslint.org/)
* [fecs](http://fecs.baidu.com/)
* [prettier](https://github.com/prettier/prettier)
+ * [standard](http://standardjs.com/)
* [tslint](https://github.com/palantir/tslint)
* [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29)
* typecheck
* VALA
* [uncrustify](https://github.com/uncrustify/uncrustify)
* Verilog
+ * [hdl-checker](https://pypi.org/project/hdl-checker)
* [iverilog](https://github.com/steveicarus/iverilog)
* [verilator](http://www.veripool.org/projects/verilator/wiki/Intro)
* [vlog](https://www.mentor.com/products/fv/questa/)
@@ -492,6 +503,7 @@ formatting.
* [vcom](https://www.mentor.com/products/fv/questa/)
* [xvhdl](https://www.xilinx.com/products/design-tools/vivado.html)
* Vim
+ * [vimls](https://github.com/iamcco/vim-language-server)
* [vint](https://github.com/Kuniwak/vint)
* Vim help
* [alex](https://github.com/wooorm/alex) :warning: :floppy_disk:
@@ -512,3 +524,5 @@ formatting.
* [yamllint](https://yamllint.readthedocs.io/)
* YANG
* [yang-lsp](https://github.com/theia-ide/yang-lsp)
+* Zig
+ * [zls](https://github.com/zigtools/zls)
diff --git a/test/command_callback/ccls_paths/with_build_dir/unusual_build_dir_name/compile_commands.json b/test/command_callback/ccls_paths/with_build_dir/unusual_build_dir_name/compile_commands.json
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/ccls_paths/with_build_dir/unusual_build_dir_name/compile_commands.json
diff --git a/test/command_callback/hdl_server/foo.vhd b/test/command_callback/hdl_server/foo.vhd
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/hdl_server/foo.vhd
diff --git a/test/command_callback/hdl_server/with_config_file/.hdl_checker.config b/test/command_callback/hdl_server/with_config_file/.hdl_checker.config
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/hdl_server/with_config_file/.hdl_checker.config
diff --git a/test/command_callback/hdl_server/with_config_file/_hdl_checker.config b/test/command_callback/hdl_server/with_config_file/_hdl_checker.config
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/hdl_server/with_config_file/_hdl_checker.config
diff --git a/test/command_callback/hdl_server/with_config_file/foo.vhd b/test/command_callback/hdl_server/with_config_file/foo.vhd
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/hdl_server/with_config_file/foo.vhd
diff --git a/test/command_callback/hdl_server/with_git/files/foo.vhd b/test/command_callback/hdl_server/with_git/files/foo.vhd
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/test/command_callback/hdl_server/with_git/files/foo.vhd
@@ -0,0 +1 @@
+
diff --git a/test/command_callback/java_paths/build/gen/main/java/com/something/dummy b/test/command_callback/java_paths/build/gen/main/java/com/something/dummy
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/java_paths/build/gen/main/java/com/something/dummy
diff --git a/test/command_callback/java_paths/build/gen2/main/java/com/something/dummy b/test/command_callback/java_paths/build/gen2/main/java/com/something/dummy
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/java_paths/build/gen2/main/java/com/something/dummy
diff --git a/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/mypy.ini b/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/mypy.ini
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/mypy.ini
diff --git a/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/tests/pytest.ini b/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/tests/pytest.ini
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/tests/pytest.ini
diff --git a/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py b/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py
diff --git a/test/command_callback/test_bashate_command_callback.vader b/test/command_callback/test_bashate_command_callback.vader
new file mode 100644
index 00000000..714cf690
--- /dev/null
+++ b/test/command_callback/test_bashate_command_callback.vader
@@ -0,0 +1,15 @@
+Before:
+ call ale#assert#SetUpLinterTest('sh', 'bashate')
+ call ale#test#SetFilename('test.sh')
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The default bashate command should be correct):
+ AssertLinter 'bashate', ale#Escape('bashate') . ' %t'
+
+Execute(The bashate command should accept options):
+ let b:ale_sh_bashate_options = '-i E310 --max-line-length 100'
+
+ AssertLinter 'bashate',
+ \ ale#Escape('bashate') . ' -i E310 --max-line-length 100 %t'
diff --git a/test/command_callback/test_c_ccls_command_callbacks.vader b/test/command_callback/test_c_ccls_command_callbacks.vader
index 43fdb366..04643d02 100644
--- a/test/command_callback/test_c_ccls_command_callbacks.vader
+++ b/test/command_callback/test_c_ccls_command_callbacks.vader
@@ -4,6 +4,10 @@
Before:
call ale#assert#SetUpLinterTest('c', 'ccls')
+ Save b:ale_c_build_dir_names
+ Save b:ale_c_ccls_executable
+ Save b:ale_c_ccls_init_options
+
After:
call ale#assert#TearDownLinterTest()
@@ -47,3 +51,19 @@ Execute(The initialization options should be configurable):
let b:ale_c_ccls_init_options = { 'cacheDirectory': '/tmp/ccls' }
AssertLSPOptions { 'cacheDirectory': '/tmp/ccls' }
+
+Execute(The compile command database should be detected correctly):
+ call ale#test#SetFilename('ccls_paths/with_ccls/dummy.c')
+
+ AssertLSPOptions {}
+
+ call ale#test#SetFilename('ccls_paths/with_compile_commands_json/dummy.c')
+
+ AssertLSPOptions { 'compilationDatabaseDirectory':
+ \ ale#path#Simplify(g:dir . '/ccls_paths/with_compile_commands_json') }
+
+ call ale#test#SetFilename('ccls_paths/with_build_dir/dummy.c')
+ let b:ale_c_build_dir_names = ['unusual_build_dir_name']
+
+ AssertLSPOptions { 'compilationDatabaseDirectory':
+ \ ale#path#Simplify(g:dir . '/ccls_paths/with_build_dir/unusual_build_dir_name') }
diff --git a/test/command_callback/test_c_cppcheck_command_callbacks.vader b/test/command_callback/test_c_cppcheck_command_callbacks.vader
index 3d487a31..b6ea3179 100644
--- a/test/command_callback/test_c_cppcheck_command_callbacks.vader
+++ b/test/command_callback/test_c_cppcheck_command_callbacks.vader
@@ -1,7 +1,6 @@
Before:
call ale#assert#SetUpLinterTest('c', 'cppcheck')
-
- let b:command_tail = ' -q --language=c --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t'
+ let b:command_tail = ' -q --language=c --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'' --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t'
After:
" Remove a test file we might open for some tests.
@@ -10,9 +9,8 @@ After:
set buftype=nofile
endif
- call ale#assert#TearDownLinterTest()
-
unlet! b:command_tail
+ call ale#assert#TearDownLinterTest()
Execute(The executable should be configurable):
AssertLinter 'cppcheck', ale#Escape('cppcheck') . b:command_tail
@@ -28,6 +26,7 @@ Execute(cppcheck for C should detect compile_commands.json files):
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one'))
\ . ale#Escape('cppcheck')
\ . ' -q --language=c'
+ \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
\ . ' --project=' . ale#Escape('compile_commands.json')
\ . ' --enable=style %t'
@@ -38,6 +37,7 @@ Execute(cppcheck for C should detect compile_commands.json files in build direct
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir'))
\ . ale#Escape('cppcheck')
\ . ' -q --language=c'
+ \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
\ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json'))
\ . ' --enable=style %t'
@@ -47,6 +47,7 @@ Execute(cppcheck for C should include file dir if compile_commands.json file is
AssertLinter 'cppcheck',
\ ale#Escape('cppcheck')
\ . ' -q --language=c'
+ \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
\ . ' --enable=style'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths'))
\ . ' %t'
@@ -61,6 +62,7 @@ Execute(cppcheck for C should ignore compile_commands.json file if buffer is mod
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one'))
\ . ale#Escape('cppcheck')
\ . ' -q --language=c'
+ \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
\ . ' --enable=style'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths/one'))
\ . ' %t'
diff --git a/test/command_callback/test_checkstyle_command_callback.vader b/test/command_callback/test_checkstyle_command_callback.vader
index 7a9f26b3..5824df87 100644
--- a/test/command_callback/test_checkstyle_command_callback.vader
+++ b/test/command_callback/test_checkstyle_command_callback.vader
@@ -20,11 +20,11 @@ Execute(The checkstyle executable should be configurable):
\ . ' %s'
Execute(Custom options should be supported):
- let b:ale_java_checkstyle_options = '--foobar'
+ let b:ale_java_checkstyle_options = '--foobar -cp -classpath /path/to/checkstyle-8.7-all.jar'
AssertLinter 'checkstyle',
\ ale#Escape('checkstyle')
- \ . ' --foobar'
+ \ . ' --foobar -cp -classpath /path/to/checkstyle-8.7-all.jar'
\ . ' -c ' . ale#Escape('/google_checks.xml')
\ . ' %s'
diff --git a/test/command_callback/test_cpp_ccls_command_callbacks.vader b/test/command_callback/test_cpp_ccls_command_callbacks.vader
index eece42bc..f603ac07 100644
--- a/test/command_callback/test_cpp_ccls_command_callbacks.vader
+++ b/test/command_callback/test_cpp_ccls_command_callbacks.vader
@@ -4,6 +4,10 @@
Before:
call ale#assert#SetUpLinterTest('cpp', 'ccls')
+ Save b:ale_c_build_dir_names
+ Save b:ale_cpp_ccls_executable
+ Save b:ale_cpp_ccls_init_options
+
After:
call ale#assert#TearDownLinterTest()
@@ -47,3 +51,19 @@ Execute(The initialization options should be configurable):
let b:ale_cpp_ccls_init_options = { 'cacheDirectory': '/tmp/ccls' }
AssertLSPOptions { 'cacheDirectory': '/tmp/ccls' }
+
+Execute(The compile command database should be detected correctly):
+ call ale#test#SetFilename('ccls_paths/with_ccls/dummy.c')
+
+ AssertLSPOptions {}
+
+ call ale#test#SetFilename('ccls_paths/with_compile_commands_json/dummy.c')
+
+ AssertLSPOptions { 'compilationDatabaseDirectory':
+ \ ale#path#Simplify(g:dir . '/ccls_paths/with_compile_commands_json') }
+
+ call ale#test#SetFilename('ccls_paths/with_build_dir/dummy.c')
+ let b:ale_c_build_dir_names = ['unusual_build_dir_name']
+
+ AssertLSPOptions { 'compilationDatabaseDirectory':
+ \ ale#path#Simplify(g:dir . '/ccls_paths/with_build_dir/unusual_build_dir_name') }
diff --git a/test/command_callback/test_cpp_cppcheck_command_callbacks.vader b/test/command_callback/test_cpp_cppcheck_command_callbacks.vader
index 02bdf748..b19c09b1 100644
--- a/test/command_callback/test_cpp_cppcheck_command_callbacks.vader
+++ b/test/command_callback/test_cpp_cppcheck_command_callbacks.vader
@@ -1,6 +1,6 @@
Before:
call ale#assert#SetUpLinterTest('cpp', 'cppcheck')
- let b:command_tail = ' -q --language=c++ --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t'
+ let b:command_tail = ' -q --language=c++ --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'' --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t'
After:
" Remove a test file we might open for some tests.
@@ -26,6 +26,7 @@ Execute(cppcheck for C++ should detect compile_commands.json files):
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one'))
\ . ale#Escape('cppcheck')
\ . ' -q --language=c++'
+ \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
\ . ' --project=' . ale#Escape('compile_commands.json')
\ . ' --enable=style %t'
@@ -36,6 +37,7 @@ Execute(cppcheck for C++ should detect compile_commands.json files in build dire
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir'))
\ . ale#Escape('cppcheck')
\ . ' -q --language=c++'
+ \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
\ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json'))
\ . ' --enable=style %t'
@@ -45,6 +47,7 @@ Execute(cppcheck for C++ should include file dir if compile_commands.json file i
AssertLinter 'cppcheck',
\ ale#Escape('cppcheck')
\ . ' -q --language=c++'
+ \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
\ . ' --enable=style'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths'))
\ . ' %t'
@@ -59,6 +62,7 @@ Execute(cppcheck for C++ should ignore compile_commands.json file if buffer is m
\ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one'))
\ . ale#Escape('cppcheck')
\ . ' -q --language=c++'
+ \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'''
\ . ' --enable=style'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths/one'))
\ . ' %t'
diff --git a/test/command_callback/test_eclipselsp_command_callback.vader b/test/command_callback/test_eclipselsp_command_callback.vader
index f25ed5fc..6bbc4053 100644
--- a/test/command_callback/test_eclipselsp_command_callback.vader
+++ b/test/command_callback/test_eclipselsp_command_callback.vader
@@ -54,6 +54,7 @@ Execute(VersionCheck should return correct version):
Execute(The eclipselsp callback should return the correct default value):
let cmd = [ ale#Escape('java'),
+ \ '',
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
@@ -72,6 +73,7 @@ Execute(The eclipselsp callback should return the correct default value):
Execute(The eclipselsp callback should allow custom executable):
let b:ale_java_eclipselsp_executable='/bin/foobar'
let cmd = [ ale#Escape('/bin/foobar'),
+ \ '',
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
@@ -87,9 +89,12 @@ Execute(The eclipselsp callback should allow custom executable):
\]
AssertLinter '/bin/foobar', join(cmd, ' ')
-Execute(The eclipselsp callback should allow custom configuration path):
+Execute(The eclipselsp callback should allow custom configuration path and javaagent):
let b:ale_java_eclipselsp_config_path = '/home/config'
+ let b:ale_java_eclipselsp_javaagent = '/home/lombok.jar /home/lombok2.jar'
let cmd = [ ale#Escape('java'),
+ \ ale#Escape('-javaagent:/home/lombok.jar'),
+ \ ale#Escape('-javaagent:/home/lombok2.jar'),
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
diff --git a/test/command_callback/test_gopls_command_callback.vader b/test/command_callback/test_gopls_command_callback.vader
index 92b20b18..73fcbf03 100644
--- a/test/command_callback/test_gopls_command_callback.vader
+++ b/test/command_callback/test_gopls_command_callback.vader
@@ -49,7 +49,10 @@ Execute(Should return directory for 'go.mod' if found in parent directory):
Execute(Should return nearest directory with '.git' if found in parent directory):
call ale#test#SetFilename('test.go')
- call mkdir(g:dir . '/.git')
+
+ if !isdirectory(g:dir . '/.git')
+ call mkdir(g:dir . '/.git')
+ endif
AssertLSPProject g:dir
diff --git a/test/command_callback/test_javac_command_callback.vader b/test/command_callback/test_javac_command_callback.vader
index 42c64e54..d2eebf7a 100644
--- a/test/command_callback/test_javac_command_callback.vader
+++ b/test/command_callback/test_javac_command_callback.vader
@@ -31,7 +31,7 @@ After:
Execute(The javac callback should return the correct default value):
AssertLinter 'javac', g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
-Execute(The javac callback should use g:ale_java_javac_classpath correctly):
+Execute(The javac callback should use string type g:ale_java_javac_classpath correctly):
let g:ale_java_javac_classpath = 'foo.jar'
AssertLinter 'javac',
@@ -39,6 +39,14 @@ Execute(The javac callback should use g:ale_java_javac_classpath correctly):
\ . ' -cp ' . ale#Escape('foo.jar')
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
+Execute(The javac callback should use list type g:ale_java_javac_classpath correctly):
+ let g:ale_java_javac_classpath = ['foo.jar']
+
+ AssertLinter 'javac',
+ \ g:prefix
+ \ . ' -cp ' . ale#Escape('foo.jar')
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
+
Execute(The executable should be configurable):
let g:ale_java_javac_executable = 'foobar'
@@ -108,6 +116,137 @@ Execute(The javac callback should combine discovered classpaths and manual ones)
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
+ let g:ale_java_javac_classpath = ['configured.jar']
+ let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [
+ \ '[DEBUG] Ignore this.',
+ \ '[INFO] Something we should ignore.',
+ \ '/foo/bar.jar',
+ \ '/xyz/abc.jar',
+ \], {})
+
+ AssertEqual
+ \ g:prefix
+ \ . ' -cp '
+ \ . ale#Escape(join(
+ \ [
+ \ '/foo/bar.jar',
+ \ '/xyz/abc.jar',
+ \ 'configured.jar',
+ \ ],
+ \ g:cp_sep
+ \ ))
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
+ \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
+
+ let g:ale_java_javac_classpath = ['configured.jar', 'configured2.jar']
+ let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [
+ \ '[DEBUG] Ignore this.',
+ \ '[INFO] Something we should ignore.',
+ \ '/foo/bar.jar',
+ \ '/xyz/abc.jar',
+ \], {})
+
+ AssertEqual
+ \ g:prefix
+ \ . ' -cp '
+ \ . ale#Escape(join(
+ \ [
+ \ '/foo/bar.jar',
+ \ '/xyz/abc.jar',
+ \ 'configured.jar',
+ \ 'configured2.jar',
+ \ ],
+ \ g:cp_sep
+ \ ))
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
+ \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
+
+Execute(The javac callback should use string type g:ale_java_javac_sourcepath correctly):
+ let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main'
+
+ AssertLinter 'javac',
+ \ g:prefix
+ \ . ' -sourcepath ' . ale#Escape(
+ \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/')
+ \ )
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
+
+Execute(The javac callback should use list type g:ale_java_javac_sourcepath correctly):
+ let g:ale_java_javac_sourcepath = ['java_paths/build/gen/main']
+
+ AssertLinter 'javac',
+ \ g:prefix
+ \ . ' -sourcepath ' . ale#Escape(
+ \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/')
+ \ )
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
+
+Execute(The javac callback shouldn't add -sourcepath when g:ale_java_javac_sourcepath variable path doesn't exist):
+ let g:ale_java_javac_sourcepath = 'java_paths/build/gen3/main'
+
+ AssertLinter 'javac',
+ \ g:prefix
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
+
+Execute(The javac callback should combine discovered sourcepath and manual ones):
+ call ale#engine#Cleanup(bufnr(''))
+ call ale#test#SetFilename('java_paths/src/main/java/com/something/dummy.java')
+ call ale#engine#InitBufferInfo(bufnr(''))
+
+ let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main'
+ let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
+
+ AssertEqual
+ \ 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/build/gen/main/'),
+ \ ], g:cp_sep))
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
+ \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
+
+ let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main'
+ \ . g:cp_sep . 'java_paths/build/gen2/main'
+ let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
+
+ AssertEqual
+ \ 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/build/gen/main/'),
+ \ ale#path#Simplify(g:dir . '/java_paths/build/gen2/main/')
+ \ ], g:cp_sep))
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
+ \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
+
+ let g:ale_java_javac_sourcepath = ['java_paths/build/gen/main']
+ let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
+
+ AssertEqual
+ \ 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/build/gen/main/')
+ \ ], g:cp_sep))
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
+ \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
+
+ let g:ale_java_javac_sourcepath = [
+ \ 'java_paths/build/gen/main',
+ \ 'java_paths/build/gen2/main'
+ \ ]
+ let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
+
+ AssertEqual
+ \ 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/build/gen/main/'),
+ \ ale#path#Simplify(g:dir . '/java_paths/build/gen2/main/')
+ \ ], g:cp_sep))
+ \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
+ \ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
+
Execute(The javac callback should detect source directories):
call ale#engine#Cleanup(bufnr(''))
noautocmd e! java_paths/src/main/java/com/something/dummy
diff --git a/test/command_callback/test_mypy_command_callback.vader b/test/command_callback/test_mypy_command_callback.vader
index 8ca35207..afa9f9af 100644
--- a/test/command_callback/test_mypy_command_callback.vader
+++ b/test/command_callback/test_mypy_command_callback.vader
@@ -52,6 +52,15 @@ Execute(The mypy callbacks should detect virtualenv directories and switch to th
\ . ' --show-column-numbers '
\ . '--shadow-file %s %t %s'
+Execute(The mypy callbacks should cd to directory containing mypy.ini if found):
+ silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py')
+
+ AssertLinter 'mypy',
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini'))
+ \ . ale#Escape('mypy')
+ \ . ' --show-column-numbers '
+ \ . '--shadow-file %s %t %s'
+
Execute(You should able able to use the global mypy instead):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
let g:ale_python_mypy_use_global = 1
diff --git a/test/command_callback/test_objc_ccls_command_callbacks.vader b/test/command_callback/test_objc_ccls_command_callbacks.vader
index 5aa69d6a..34b8539e 100644
--- a/test/command_callback/test_objc_ccls_command_callbacks.vader
+++ b/test/command_callback/test_objc_ccls_command_callbacks.vader
@@ -1,6 +1,10 @@
Before:
call ale#assert#SetUpLinterTest('objc', 'ccls')
+ Save b:ale_c_build_dir_names
+ Save b:ale_objc_ccls_executable
+ Save b:ale_objc_ccls_init_options
+
After:
call ale#assert#TearDownLinterTest()
@@ -44,3 +48,19 @@ Execute(The initialization options should be configurable):
let b:ale_objc_ccls_init_options = { 'cacheDirectory': '/tmp/ccls' }
AssertLSPOptions { 'cacheDirectory': '/tmp/ccls' }
+
+Execute(The compile command database should be detected correctly):
+ call ale#test#SetFilename('ccls_paths/with_ccls/dummy.c')
+
+ AssertLSPOptions {}
+
+ call ale#test#SetFilename('ccls_paths/with_compile_commands_json/dummy.c')
+
+ AssertLSPOptions { 'compilationDatabaseDirectory':
+ \ ale#path#Simplify(g:dir . '/ccls_paths/with_compile_commands_json') }
+
+ call ale#test#SetFilename('ccls_paths/with_build_dir/dummy.c')
+ let b:ale_c_build_dir_names = ['unusual_build_dir_name']
+
+ AssertLSPOptions { 'compilationDatabaseDirectory':
+ \ ale#path#Simplify(g:dir . '/ccls_paths/with_build_dir/unusual_build_dir_name') }
diff --git a/test/command_callback/test_pyright_command_callback.vader b/test/command_callback/test_pyright_command_callback.vader
new file mode 100644
index 00000000..3e421bd9
--- /dev/null
+++ b/test/command_callback/test_pyright_command_callback.vader
@@ -0,0 +1,116 @@
+Before:
+ call ale#assert#SetUpLinterTest('python', 'pyright')
+
+ let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
+
+After:
+ unlet! b:bin_dir
+ unlet! b:executable
+
+ call ale#assert#TearDownLinterTest()
+
+Execute(The command callback should return the correct default string):
+ AssertLinter
+ \ 'pyright-langserver',
+ \ ale#Escape('pyright-langserver') . ' --stdio'
+
+Execute(The executable should be configurable):
+ let g:ale_python_pyright_executable = '/bin/foo-bar'
+
+ AssertLinter
+ \ '/bin/foo-bar',
+ \ ale#Escape('/bin/foo-bar') . ' --stdio'
+
+Execute(The default configuration should be mostly empty):
+ " The default configuration needs to have at least one key in it,
+ " or the server won't start up properly.
+ AssertLSPConfig {'python': {}}
+
+ let b:ale_python_pyright_config = {}
+
+ AssertLSPConfig {'python': {}}
+
+Execute(virtualenv paths should be set in configuration by default):
+ call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
+
+ AssertLSPConfig {
+ \ 'python': {
+ \ 'pythonPath': ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/python'),
+ \ 'venvPath': ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env'),
+ \ },
+ \}
+
+Execute(The pythonPath should be set based on whatever the ovveride for the venvPath is set to):
+ call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
+
+ " This overrides the default detection of the path.
+ let b:ale_python_pyright_config = {
+ \ 'python': {
+ \ 'venvPath': '/foo/bar',
+ \ },
+ \}
+
+ AssertLSPConfig {
+ \ 'python': {
+ \ 'pythonPath': ale#path#Simplify('/foo/bar/' . b:bin_dir . '/python'),
+ \ 'venvPath': '/foo/bar',
+ \ },
+ \}
+
+Execute(You should be able to override pythonPath when venvPath is detected):
+ call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
+
+ " This overrides the default detection of the path.
+ let b:ale_python_pyright_config = {
+ \ 'python': {
+ \ 'pythonPath': '/bin/python',
+ \ },
+ \}
+
+ AssertLSPConfig {
+ \ 'python': {
+ \ 'pythonPath': '/bin/python',
+ \ 'venvPath': ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env'),
+ \ },
+ \}
+
+Execute(You should be able to override both pythonPath and venvPath):
+ call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
+
+ " This overrides the default detection of the path.
+ let b:ale_python_pyright_config = {
+ \ 'python': {
+ \ 'pythonPath': '/bin/python',
+ \ 'venvPath': '/other/dir',
+ \ },
+ \}
+
+ AssertLSPConfig {
+ \ 'python': {
+ \ 'pythonPath': '/bin/python',
+ \ 'venvPath': '/other/dir',
+ \ },
+ \}
+
+Execute(You should be able to define other settings):
+ call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py')
+
+ let b:ale_python_pyright_config = {
+ \ 'python': {
+ \ 'analysis': {'logLevel': 'warning'},
+ \ },
+ \ 'pyright': {
+ \ 'disableLanguageServices': v:true,
+ \ },
+ \}
+
+ AssertLSPConfig {
+ \ 'python': {
+ \ 'analysis': {'logLevel': 'warning'},
+ \ 'pythonPath': ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/python'),
+ \ 'venvPath': ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env'),
+ \ },
+ \ 'pyright': {
+ \ 'disableLanguageServices': v:true,
+ \ },
+ \}
diff --git a/test/command_callback/test_revive_command_callbacks.vader b/test/command_callback/test_revive_command_callbacks.vader
new file mode 100644
index 00000000..172294f3
--- /dev/null
+++ b/test/command_callback/test_revive_command_callbacks.vader
@@ -0,0 +1,30 @@
+Before:
+ Save g:ale_go_go111module
+
+ call ale#assert#SetUpLinterTest('go', 'revive')
+
+After:
+ Restore
+
+ unlet! b:ale_go_go111module
+
+ call ale#assert#TearDownLinterTest()
+
+Execute(The default revive command should be correct):
+ AssertLinter 'revive', ale#Escape('revive') . ' %t'
+
+Execute(The revive executable should be configurable):
+ let b:ale_go_revive_executable = 'foobar'
+
+ AssertLinter 'foobar', ale#Escape('foobar') . ' %t'
+
+Execute(The revive options should be configurable):
+ let b:ale_go_revive_options = '--foo'
+
+ AssertLinter 'revive', ale#Escape('revive') . ' --foo %t'
+
+Execute(The revive command should support Go environment variables):
+ let b:ale_go_go111module = 'on'
+
+ AssertLinter 'revive',
+ \ ale#Env('GO111MODULE', 'on') . ale#Escape('revive') . ' %t'
diff --git a/test/command_callback/test_rust_analyzer_callbacks.vader b/test/command_callback/test_rust_analyzer_callbacks.vader
new file mode 100644
index 00000000..95866076
--- /dev/null
+++ b/test/command_callback/test_rust_analyzer_callbacks.vader
@@ -0,0 +1,20 @@
+Before:
+ call ale#assert#SetUpLinterTest('rust', 'analyzer')
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The default executable path should be correct):
+ AssertLinter 'rust-analyzer', ale#Escape('rust-analyzer')
+
+Execute(The project root should be detected correctly):
+ AssertLSPProject ''
+
+ call ale#test#SetFilename('rust-rls-project/test.rs')
+
+ AssertLSPProject ale#path#Simplify(g:dir . '/rust-rls-project')
+
+Execute(Should accept configuration settings):
+ AssertLSPConfig {}
+ let b:ale_rust_analyzer_config = {'rust': {'clippy_preference': 'on'}}
+ AssertLSPConfig {'rust': {'clippy_preference': 'on'}}
diff --git a/test/command_callback/test_standardts_command_callback.vader b/test/command_callback/test_standardts_command_callback.vader
new file mode 100644
index 00000000..d769e712
--- /dev/null
+++ b/test/command_callback/test_standardts_command_callback.vader
@@ -0,0 +1,43 @@
+Before:
+ call ale#assert#SetUpLinterTest('typescript', 'standard')
+ call ale#test#SetFilename('testfile.js')
+ unlet! b:executable
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(bin/cmd.js paths should be preferred):
+ call ale#test#SetFilename('standard-test-files/with-cmd/testfile.js')
+
+ let b:executable = ale#path#Simplify(
+ \ g:dir
+ \ . '/standard-test-files/with-cmd/node_modules/standard/bin/cmd.js'
+ \)
+
+ AssertLinter b:executable,
+ \ (has('win32') ? 'node.exe ' : '')
+ \ . ale#Escape(b:executable)
+ \ . ' --stdin %s'
+
+Execute(.bin directories should be used too):
+ call ale#test#SetFilename('standard-test-files/with-bin/testfile.js')
+
+ let b:executable = ale#path#Simplify(
+ \ g:dir
+ \ . '/standard-test-files/with-bin/node_modules/.bin/standard'
+ \)
+
+ AssertLinter b:executable, ale#Escape(b:executable) . ' --stdin %s'
+
+Execute(The global executable should be used otherwise):
+ AssertLinter 'standard', ale#Escape('standard') . ' --stdin %s'
+
+Execute(The global executable should be configurable):
+ let b:ale_typescript_standard_executable = 'foobar'
+
+ AssertLinter 'foobar', ale#Escape('foobar') . ' --stdin %s'
+
+Execute(The options should be configurable):
+ let b:ale_typescript_standard_options = '--wat'
+
+ AssertLinter 'standard', ale#Escape('standard') . ' --wat --stdin %s'
diff --git a/test/command_callback/test_terraform_lsp_command_callback.vader b/test/command_callback/test_terraform_lsp_command_callback.vader
new file mode 100644
index 00000000..7a491d54
--- /dev/null
+++ b/test/command_callback/test_terraform_lsp_command_callback.vader
@@ -0,0 +1,48 @@
+Before:
+ call ale#assert#SetUpLinterTest('terraform', 'terraform_lsp')
+
+After:
+ if isdirectory(g:dir . '/.terraform')
+ call delete(g:dir . '/.terraform', 'd')
+ endif
+
+ unlet! b:ale_terraform_langserver_executable
+ unlet! b:ale_terraform_langserver_options
+
+ call ale#assert#TearDownLinterTest()
+
+Execute(Should send correct LSP language):
+ AssertLSPLanguage 'terraform'
+
+Execute(Should load default executable):
+ AssertLinter 'terraform-lsp', ale#Escape('terraform-lsp')
+
+Execute(Should configure custom executable):
+ let b:ale_terraform_langserver_executable = 'foo'
+ AssertLinter 'foo', ale#Escape('foo')
+
+Execute(Should set custom options):
+ let b:ale_terraform_langserver_options = '--bar'
+
+ AssertLinter 'terraform-lsp',
+ \ ale#Escape('terraform-lsp') . ' --bar'
+
+Execute(Should return current directory if it contains .terraform directory):
+ call mkdir(g:dir . '/.terraform')
+ AssertLSPProject g:dir
+
+Execute(Should return nearest directory with .terraform if found in parent directory):
+ call ale#test#SetFilename('../terraform_files/main.tf')
+
+ let b:parent_dir = ale#path#Simplify(g:dir . '/..')
+ let b:tf_dir = b:parent_dir . '/.terraform'
+
+ if !isdirectory(b:tf_dir)
+ call mkdir(b:tf_dir)
+ endif
+
+ AssertLSPProject b:parent_dir
+
+ call delete(b:tf_dir, 'd')
+ unlet!b:parent_dir
+ unlet!b:tf_dir
diff --git a/test/command_callback/test_vim_vimls.vader b/test/command_callback/test_vim_vimls.vader
new file mode 100644
index 00000000..ab12b637
--- /dev/null
+++ b/test/command_callback/test_vim_vimls.vader
@@ -0,0 +1,76 @@
+" Author: Jeffrey Lau https://github.com/zoonfafer
+" Description: Tests for the Vim vimls linter
+
+Before:
+ call ale#assert#SetUpLinterTest('vim', 'vimls')
+
+After:
+ if isdirectory(g:dir . '/.git')
+ call delete(g:dir . '/.git', 'd')
+ endif
+
+ call ale#assert#TearDownLinterTest()
+
+Execute(should set correct defaults):
+ AssertLinter 'vim-language-server', ale#Escape('vim-language-server') . ' --stdio'
+
+Execute(should set correct LSP values):
+ call ale#test#SetFilename('vim_fixtures/path_with_autoload/test.vim')
+ AssertLSPLanguage 'vim'
+ AssertLSPOptions {}
+ AssertLSPConfig {}
+ AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_autoload')
+
+Execute(should set correct project for .git/):
+ let b:parent_dir = ale#path#Simplify(g:dir . '/..')
+ let b:git_dir = b:parent_dir . '/.git'
+
+ call ale#test#SetFilename('vim_fixtures/test.vim')
+
+ if !isdirectory(b:git_dir)
+ call mkdir(b:git_dir)
+ endif
+
+ AssertLSPProject ale#path#Simplify(b:parent_dir)
+
+ call delete(b:git_dir, 'd')
+ unlet! b:git_dir
+
+Execute(should set correct project for plugin/):
+ call ale#test#SetFilename('vim_fixtures/path_with_plugin/test.vim')
+
+ AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_plugin')
+
+Execute(should accept configuration settings):
+ AssertLSPConfig {}
+
+ let b:ale_vim_vimls_config = {'vim': {'foobar': v:true}}
+ AssertLSPConfig {'vim': {'foobar': v:true}}
+
+Execute(should set correct project for .vimrc):
+ call ale#test#SetFilename('vim_fixtures/path_with_vimrc/.vimrc')
+
+ AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_vimrc')
+
+Execute(should set correct project for init.vim):
+ call ale#test#SetFilename('vim_fixtures/path_with_initvim/init.vim')
+
+ AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_initvim')
+
+Execute(should use the local executable when available):
+ call ale#test#SetFilename('vim_fixtures/file.vim')
+
+ AssertLinter ale#path#Simplify(g:dir . '/vim_fixtures/node_modules/.bin/vim-language-server'),
+ \ ale#Escape(ale#path#Simplify(g:dir . '/vim_fixtures/node_modules/.bin/vim-language-server')) . ' --stdio'
+
+Execute(should let the global executable to be used):
+ let g:ale_vim_vimls_use_global = 1
+ call ale#test#SetFilename('vim_fixtures/file.vim')
+
+ AssertLinter 'vim-language-server',
+ \ ale#Escape('vim-language-server') . ' --stdio'
+
+Execute(should let the executable to be configured):
+ let g:ale_vim_vimls_executable = 'foobar'
+
+ AssertLinter 'foobar', ale#Escape('foobar') . ' --stdio'
diff --git a/test/command_callback/test_zig_zls_callbacks.vader b/test/command_callback/test_zig_zls_callbacks.vader
new file mode 100644
index 00000000..6e42cc4b
--- /dev/null
+++ b/test/command_callback/test_zig_zls_callbacks.vader
@@ -0,0 +1,15 @@
+Before:
+ call ale#assert#SetUpLinterTest('zig', 'zls')
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The default executable path should be correct):
+ AssertLinter 'zls', ale#Escape('zls')
+
+Execute(The project root should be detected correctly):
+ AssertLSPProject ''
+
+ call ale#test#SetFilename('zig-zls-project/main.zig')
+
+ AssertLSPProject ale#path#Simplify(g:dir . '/zig-zls-project')
diff --git a/test/command_callback/vim_fixtures/invalid_vim_project/test.vim b/test/command_callback/vim_fixtures/invalid_vim_project/test.vim
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/vim_fixtures/invalid_vim_project/test.vim
diff --git a/test/command_callback/vim_fixtures/node_modules/.bin/vim-language-server b/test/command_callback/vim_fixtures/node_modules/.bin/vim-language-server
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/vim_fixtures/node_modules/.bin/vim-language-server
diff --git a/test/command_callback/vim_fixtures/path_with_autoload/autoload/test.vim b/test/command_callback/vim_fixtures/path_with_autoload/autoload/test.vim
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/vim_fixtures/path_with_autoload/autoload/test.vim
diff --git a/test/command_callback/vim_fixtures/path_with_autoload/test.vim b/test/command_callback/vim_fixtures/path_with_autoload/test.vim
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/vim_fixtures/path_with_autoload/test.vim
diff --git a/test/command_callback/vim_fixtures/path_with_initvim/init.vim b/test/command_callback/vim_fixtures/path_with_initvim/init.vim
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/vim_fixtures/path_with_initvim/init.vim
diff --git a/test/command_callback/vim_fixtures/path_with_plugin/plugin/test.vim b/test/command_callback/vim_fixtures/path_with_plugin/plugin/test.vim
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/vim_fixtures/path_with_plugin/plugin/test.vim
diff --git a/test/command_callback/vim_fixtures/path_with_plugin/test.vim b/test/command_callback/vim_fixtures/path_with_plugin/test.vim
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/vim_fixtures/path_with_plugin/test.vim
diff --git a/test/command_callback/vim_fixtures/path_with_vimrc/.vimrc b/test/command_callback/vim_fixtures/path_with_vimrc/.vimrc
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/vim_fixtures/path_with_vimrc/.vimrc
diff --git a/test/command_callback/zig-zls-project/build.zig b/test/command_callback/zig-zls-project/build.zig
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/zig-zls-project/build.zig
diff --git a/test/completion/test_completion_events.vader b/test/completion/test_completion_events.vader
index d70fefeb..3a7a31d0 100644
--- a/test/completion/test_completion_events.vader
+++ b/test/completion/test_completion_events.vader
@@ -50,7 +50,8 @@ Before:
let g:handle_code_action_called = 0
function! MockHandleCodeAction() abort
" delfunction! ale#code_action#HandleCodeAction
- function! ale#code_action#HandleCodeAction(action) abort
+ function! ale#code_action#HandleCodeAction(action, should_save) abort
+ AssertEqual v:false, a:should_save
let g:handle_code_action_called += 1
endfunction
endfunction
@@ -233,7 +234,7 @@ Execute(ale#completion#Show() should make the correct feedkeys() call for manual
AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls
Execute(ale#completion#Show() should not call feedkeys() for other sources):
- let b:ale_completion_info = {'source': 'deoplete'}
+ let b:ale_completion_info = {'source': 'other-source'}
call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
sleep 1ms
@@ -334,7 +335,7 @@ Execute(b:ale_completion_info should be set up correctly when requesting complet
Execute(b:ale_completion_info should be set up correctly for other sources):
let b:ale_completion_result = []
call setpos('.', [bufnr(''), 3, 14, 0])
- call ale#completion#GetCompletions('deoplete')
+ call ale#completion#GetCompletions('ale-callback')
AssertEqual
\ {
@@ -344,7 +345,7 @@ Execute(b:ale_completion_info should be set up correctly for other sources):
\ 'line_length': 14,
\ 'line': 3,
\ 'prefix': 'ab',
- \ 'source': 'deoplete',
+ \ 'source': 'ale-callback',
\ },
\ b:ale_completion_info
Assert !exists('b:ale_completion_result')
diff --git a/test/completion/test_lsp_completion_parsing.vader b/test/completion/test_lsp_completion_parsing.vader
index ef954564..e233c955 100644
--- a/test/completion/test_lsp_completion_parsing.vader
+++ b/test/completion/test_lsp_completion_parsing.vader
@@ -17,17 +17,17 @@ Execute(Should handle Rust completion results correctly):
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a str>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = Cow<''a, str>>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Searcher', 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 'f', 'icase': 1},
+ \ {'word': 'Searcher', 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1},
\ {'word': 'default', 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = String;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Err', 'menu': 'type Err = ParseError;', 'info': '', 'kind': 'f', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1},
+ \ {'word': 'Err', 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1},
\ {'word': 'from_str', 'menu': 'fn from_str(s: &str) -> Result<String, ParseError>', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'from', 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'from', 'menu': 'fn from(s: Box<str>) -> String', 'info': '', 'kind': 'f', 'icase': 1},
@@ -526,3 +526,73 @@ Execute(Should handle completion messages with the deprecated insertText attribu
\ ],
\ },
\ })
+
+Execute(Should handle completion messages with additionalTextEdits):
+ AssertEqual
+ \ [
+ \ {
+ \ 'word': 'next_callback',
+ \ 'menu': 'PlayTimeCallback',
+ \ 'info': '',
+ \ 'kind': 'v',
+ \ 'icase': 1,
+ \ 'user_data': json_encode({
+ \ 'codeActions': [
+ \ {
+ \ 'description': 'completion',
+ \ 'changes': [
+ \ {
+ \ 'fileName': expand('#' . bufnr('') . ':p'),
+ \ 'textChanges': [
+ \ {
+ \ 'start': {
+ \ 'line': 11,
+ \ 'offset': 2,
+ \ },
+ \ 'end': {
+ \ 'line': 13,
+ \ 'offset': 4,
+ \ },
+ \ 'newText': 'from "module" import next_callback',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ }),
+ \ },
+ \ ],
+ \ ale#completion#ParseLSPCompletions({
+ \ 'id': 226,
+ \ 'jsonrpc': '2.0',
+ \ 'result': {
+ \ 'isIncomplete': v:false,
+ \ 'items': [
+ \ {
+ \ 'detail': 'PlayTimeCallback',
+ \ 'filterText': 'next_callback',
+ \ 'insertText': 'next_callback',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' next_callback',
+ \ 'sortText': '3ee19999next_callback',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {
+ \ 'line': 10,
+ \ 'character': 1,
+ \ },
+ \ 'end': {
+ \ 'line': 12,
+ \ 'character': 3,
+ \ },
+ \ },
+ \ 'newText': 'from "module" import next_callback',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ },
+ \ })
diff --git a/test/completion/test_public_completion_api.vader b/test/completion/test_public_completion_api.vader
index c3cd42b8..f26fdc12 100644
--- a/test/completion/test_public_completion_api.vader
+++ b/test/completion/test_public_completion_api.vader
@@ -37,6 +37,7 @@ Execute(ale#completion#GetCompletionPositionForDeoplete() should return the posi
AssertEqual 4, ale#completion#GetCompletionPositionForDeoplete('foo bar')
Execute(ale#completion#CanProvideCompletions should return 0 when no completion sources are available):
+ let b:ale_linters = ['flake8']
AssertEqual 0, ale#completion#CanProvideCompletions()
Execute(ale#completion#CanProvideCompletions should return 1 when at least one completion source is available):
diff --git a/test/completion/test_tsserver_completion_parsing.vader b/test/completion/test_tsserver_completion_parsing.vader
index 5dfef531..58b56ce6 100644
--- a/test/completion/test_tsserver_completion_parsing.vader
+++ b/test/completion/test_tsserver_completion_parsing.vader
@@ -81,7 +81,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'abc',
\ 'menu': '(property) Foo.abc: number',
\ 'info': '',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -89,7 +89,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'def',
\ 'menu': '(property) Foo.def: number',
\ 'info': 'foo bar baz',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -97,7 +97,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'ghi',
\ 'menu': '(class) Foo',
\ 'info': '',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -169,7 +169,7 @@ Execute(Entries without details should be included in the responses):
\ 'word': 'abc',
\ 'menu': 'import { def } from "./Foo"; (property) Foo.abc: number',
\ 'info': '',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'user_data': json_encode({
\ 'codeActions': [{
@@ -183,7 +183,7 @@ Execute(Entries without details should be included in the responses):
\ 'word': 'def',
\ 'menu': '(property) Foo.def: number',
\ 'info': 'foo bar baz',
- \ 'kind': 'f',
+ \ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
diff --git a/test/eslint-test-files/react-app/subdir-with-package-json/node_modules/.gitkeep b/test/eslint-test-files/react-app/subdir-with-package-json/node_modules/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/eslint-test-files/react-app/subdir-with-package-json/node_modules/.gitkeep
diff --git a/test/fixers/test_astyle_fixer_callback.vader b/test/fixers/test_astyle_fixer_callback.vader
new file mode 100644
index 00000000..ac756870
--- /dev/null
+++ b/test/fixers/test_astyle_fixer_callback.vader
@@ -0,0 +1,96 @@
+Before:
+ Save g:ale_c_astyle_executable
+ Save g:ale_c_astyle_project_options
+ Save g:ale_cpp_astyle_project_options
+
+ " Use an invalid global executable, so we don't match it.
+ let g:ale_c_astyle_executable = 'xxxinvalid'
+ let g:ale_cpp_astyle_executable = 'invalidpp'
+ let g:ale_c_astyle_project_options = ''
+ let g:ale_cpp_astyle_project_options = ''
+
+ call ale#test#SetDirectory('/testplugin/test/fixers')
+
+After:
+ Restore
+
+ call ale#test#RestoreDirectory()
+
+Execute(The astyle callback should return the correct default values):
+ " Because this file doesn't exist, no astylrc config
+ " exists near it. Therefore, project_options is empty.
+ call ale#test#SetFilename('../c_files/testfile.c')
+ let targetfile = bufname(bufnr('%'))
+
+ AssertEqual
+ \ {
+ \ 'command': ale#Escape(g:ale_c_astyle_executable)
+ \ . ' --stdin=' . ale#Escape(targetfile)
+ \ },
+ \ ale#fixers#astyle#Fix(bufnr(''))
+
+Execute(The astyle callback should support cpp files):
+ " Because this file doesn't exist, no astylrc config
+ " exists near it. Therefore, project_options is empty.
+ call ale#test#SetFilename('../cpp_files/dummy.cpp')
+ set filetype=cpp " The test fails without this
+ let targetfile = bufname(bufnr('%'))
+
+ AssertEqual
+ \ {
+ \ 'command': ale#Escape(g:ale_cpp_astyle_executable)
+ \ . ' --stdin=' . ale#Escape(targetfile)
+ \ },
+ \ ale#fixers#astyle#Fix(bufnr(''))
+
+Execute(The astyle callback should support cpp files with option file set):
+ call ale#test#SetFilename('../cpp_files/dummy.cpp')
+ let g:ale_cpp_astyle_project_options = '.astylerc_cpp'
+ let targetfile = bufname(bufnr('%'))
+ set filetype=cpp " The test fails without this
+
+ AssertEqual
+ \ {
+ \ 'command': ale#Escape('invalidpp')
+ \ . ' --project=' . g:ale_cpp_astyle_project_options
+ \ . ' --stdin=' . ale#Escape(targetfile)
+ \ },
+ \ ale#fixers#astyle#Fix(bufnr(''))
+
+Execute(The astyle callback should return the correct default values with a specified option file):
+ call ale#test#SetFilename('../c_files/testfile.c')
+ let g:ale_c_astyle_project_options = '.astylerc_c'
+ let targetfile = bufname(bufnr('%'))
+
+ AssertEqual
+ \ {
+ \ 'command': ale#Escape('xxxinvalid')
+ \ . ' --project=' . g:ale_c_astyle_project_options
+ \ . ' --stdin=' . ale#Escape(targetfile)
+ \ },
+ \ ale#fixers#astyle#Fix(bufnr(''))
+
+Execute(The astyle callback should find nearest default option file _astylrc):
+ call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.c')
+ let targetfile = bufname(bufnr('%'))
+
+ AssertEqual
+ \ {
+ \ 'command': ale#Escape('xxxinvalid')
+ \ . ' --project=_astylerc'
+ \ . ' --stdin=' . ale#Escape(targetfile)
+ \ },
+ \ ale#fixers#astyle#Fix(bufnr(''))
+
+Execute(The astyle callback should find .astylrc in the same directory as src):
+ call ale#test#SetFilename('../test_cpp_project/dummy.cpp')
+ set filetype=cpp " The test fails without this
+ let targetfile = bufname(bufnr('%'))
+
+ AssertEqual
+ \ {
+ \ 'command': ale#Escape('invalidpp')
+ \ . ' --project=.astylerc'
+ \ . ' --stdin=' . ale#Escape(targetfile)
+ \ },
+ \ ale#fixers#astyle#Fix(bufnr(''))
diff --git a/test/fixers/test_eslint_fixer_callback.vader b/test/fixers/test_eslint_fixer_callback.vader
index ad80bdd5..400267ac 100644
--- a/test/fixers/test_eslint_fixer_callback.vader
+++ b/test/fixers/test_eslint_fixer_callback.vader
@@ -13,7 +13,9 @@ Execute(The executable path should be correct):
AssertFixer
\ {
\ 'read_temporary_file': 1,
- \ 'command': (has('win32') ? 'node.exe ' : '')
+ \ 'command':
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
+ \ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
\ . ' --fix %t',
@@ -150,7 +152,9 @@ Execute(The lower priority configuration file in a nested directory should be pr
AssertFixer
\ {
\ 'read_temporary_file': 1,
- \ 'command': (has('win32') ? 'node.exe ' : '')
+ \ 'command':
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
+ \ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/subdir-with-config/.eslintrc'))
\ . ' --fix %t',
@@ -164,7 +168,9 @@ Execute(--config in options should override configuration file detection for old
AssertFixer
\ {
\ 'read_temporary_file': 1,
- \ 'command': (has('win32') ? 'node.exe ' : '')
+ \ 'command':
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
+ \ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --config /foo.cfg'
\ . ' --fix %t',
@@ -175,7 +181,9 @@ Execute(--config in options should override configuration file detection for old
AssertFixer
\ {
\ 'read_temporary_file': 1,
- \ 'command': (has('win32') ? 'node.exe ' : '')
+ \ 'command':
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
+ \ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -c /foo.cfg'
\ . ' --fix %t',
@@ -187,7 +195,9 @@ Execute(package.json should be used as a last resort):
AssertFixer
\ {
\ 'read_temporary_file': 1,
- \ 'command': (has('win32') ? 'node.exe ' : '')
+ \ 'command':
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
+ \ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
\ . ' --fix %t',
@@ -199,7 +209,8 @@ Execute(package.json should be used as a last resort):
\ {
\ 'read_temporary_file': 1,
\ 'command':
- \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint'))
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files'))
+ \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json'))
\ . ' --fix %t',
\ }
@@ -214,7 +225,9 @@ Execute(The version check should be correct):
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --version',
\ {
- \ 'command': (has('win32') ? 'node.exe ' : '')
+ \ 'command':
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
+ \ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@@ -223,7 +236,9 @@ Execute(The version check should be correct):
AssertFixer [
\ {
- \ 'command': (has('win32') ? 'node.exe ' : '')
+ \ 'command':
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
+ \ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@@ -236,7 +251,9 @@ Execute(--fix-dry-run should be used for 4.9.0 and up):
GivenCommandOutput ['4.9.0']
AssertFixer
\ {
- \ 'command': (has('win32') ? 'node.exe ' : '')
+ \ 'command':
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
+ \ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@@ -249,7 +266,8 @@ Execute(--fix-to-stdout should be used for eslint_d):
\ {
\ 'read_temporary_file': 1,
\ 'command':
- \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d'))
+ \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json'))
\ . ' --fix %t',
\ }
@@ -260,7 +278,8 @@ Execute(--fix-to-stdout should be used for eslint_d):
AssertFixer
\ {
\ 'command':
- \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d'))
+ \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
\ }
@@ -270,7 +289,8 @@ Execute(--fix-to-stdout should be used for eslint_d):
AssertFixer
\ {
\ 'command':
- \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d'))
+ \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
\ }
diff --git a/test/fixers/test_ktlint_fixer_callback.vader b/test/fixers/test_ktlint_fixer_callback.vader
index 47b37788..ba01a409 100644
--- a/test/fixers/test_ktlint_fixer_callback.vader
+++ b/test/fixers/test_ktlint_fixer_callback.vader
@@ -21,9 +21,8 @@ Execute(The ktlint callback should return the correct default values):
AssertEqual
\ {
\ 'command': ale#Escape('xxxinvalid')
- \ . ' %t'
+ \ . ' --stdin'
\ . ' --format',
- \ 'read_temporary_file': 1,
\ },
\ ale#fixers#ktlint#Fix(bufnr(''))
@@ -37,8 +36,7 @@ Execute(The ktlint callback should include custom ktlint options):
\ 'command': ale#Escape('xxxinvalid')
\ . ' ' . g:ale_kotlin_ktlint_options
\ . ' --ruleset /path/to/custom/ruleset.jar'
- \ . ' %t'
+ \ . ' --stdin'
\ . ' --format',
- \ 'read_temporary_file': 1,
\ },
\ ale#fixers#ktlint#Fix(bufnr(''))
diff --git a/test/fixers/test_nimpretty_fixer_callback.vader b/test/fixers/test_nimpretty_fixer_callback.vader
new file mode 100644
index 00000000..a26f649a
--- /dev/null
+++ b/test/fixers/test_nimpretty_fixer_callback.vader
@@ -0,0 +1,23 @@
+Before:
+ call ale#assert#SetUpFixerTest('nim', 'nimpretty')
+
+After:
+ call ale#assert#TearDownFixerTest()
+
+Execute(The nimpretty callback should return the correct default values):
+ AssertEqual
+ \ {
+ \ 'read_temporary_file': 1,
+ \ 'command': ale#Escape('nimpretty') . ' %t --maxLineLen:80'
+ \ },
+ \ ale#fixers#nimpretty#Fix(bufnr(''))
+
+Execute(The nimpretty callback should include any additional options):
+ let g:ale_nim_nimpretty_options = '--some-option'
+
+ AssertEqual
+ \ {
+ \ 'read_temporary_file': 1,
+ \ 'command': ale#Escape('nimpretty') . ' %t --some-option'
+ \ },
+ \ ale#fixers#nimpretty#Fix(bufnr(''))
diff --git a/test/fixers/test_tslint_fixer_callback.vader b/test/fixers/test_tslint_fixer_callback.vader
index aa9c0322..a88992fa 100644
--- a/test/fixers/test_tslint_fixer_callback.vader
+++ b/test/fixers/test_tslint_fixer_callback.vader
@@ -27,7 +27,7 @@ Execute(The tslint callback should return the correct default values):
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('tslint')
\ . ' -c ' . ale#Escape('tslint.json')
- \ . ' --fix %t',
+ \ . ' --outputAbsolutePaths --fix %t',
\ },
\ ale#fixers#tslint#Fix(bufnr(''))
@@ -40,6 +40,6 @@ Execute(The tslint callback should include custom tslint config option):
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('tslint')
\ . ' -c ' . ale#Escape('.tslintrc')
- \ . ' --fix %t',
+ \ . ' --outputAbsolutePaths --fix %t',
\ },
\ ale#fixers#tslint#Fix(bufnr(''))
diff --git a/test/handler/test_bashate_handler.vader b/test/handler/test_bashate_handler.vader
new file mode 100644
index 00000000..b61bb956
--- /dev/null
+++ b/test/handler/test_bashate_handler.vader
@@ -0,0 +1,36 @@
+Before:
+ runtime ale_linters/sh/bashate.vim
+
+After:
+ call ale#linter#Reset()
+
+Execute(The bashate handler should handle basic errors):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 777,
+ \ 'col': 1,
+ \ 'text': 'E003 Indent not multiple of 4',
+ \ },
+ \ {
+ \ 'lnum': 783,
+ \ 'col': 1,
+ \ 'text': 'E020 Function declaration not in format ^function name {$',
+ \ },
+ \ {
+ \ 'lnum': 786,
+ \ 'col': 1,
+ \ 'text': 'E010 The "do" should be on same line as for',
+ \ },
+ \ {
+ \ 'lnum': 791,
+ \ 'col': 1,
+ \ 'text': 'E006 Line too long',
+ \ },
+ \ ],
+ \ ale_linters#sh#bashate#Handle(bufnr(''), [
+ \ 'run:777:1: E003 Indent not multiple of 4',
+ \ 'run:783:1: E020 Function declaration not in format ^function name {$',
+ \ 'run:786:1: E010 The "do" should be on same line as for',
+ \ 'run:791:1: E006 Line too long',
+ \ ])
diff --git a/test/handler/test_cppcheck_handler.vader b/test/handler/test_cppcheck_handler.vader
index f153b9b5..55a5d29b 100644
--- a/test/handler/test_cppcheck_handler.vader
+++ b/test/handler/test_cppcheck_handler.vader
@@ -10,19 +10,29 @@ Execute(Basic errors should be handled by cppcheck):
AssertEqual
\ [
\ {
- \ 'lnum': 5,
+ \ 'lnum': 974,
+ \ 'col' : 6,
\ 'type': 'E',
- \ 'text': 'Array ''a[10]'' accessed at index 10, which is out of bounds',
+ \ 'sub_type': '',
+ \ 'text': 'Array ''n[3]'' accessed at index 3, which is out of bounds.',
+ \ 'code': 'arrayIndexOutOfBounds'
\ },
\ {
- \ 'lnum': 7,
+ \ 'lnum': 1185,
+ \ 'col' : 10,
\ 'type': 'W',
- \ 'text': 'Some other problem',
+ \ 'sub_type': 'style',
+ \ 'text': 'The scope of the variable ''indxStr'' can be reduced.',
+ \ 'code': 'variableScope'
\ },
\ ],
\ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [
- \ '[test.cpp:5]: (error) Array ''a[10]'' accessed at index 10, which is out of bounds',
- \ '[test.cpp:7]: (warning) Some other problem',
+ \ 'test.cpp:974:6: error: Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\',
+ \ ' n[3]=3;',
+ \ ' ^',
+ \ 'test.cpp:1185:10: style: The scope of the variable ''indxStr'' can be reduced. [variableScope]\',
+ \ ' char indxStr[16];',
+ \ ' ^',
\ ])
Execute(Problems from other files should be ignored by cppcheck):
@@ -32,5 +42,7 @@ Execute(Problems from other files should be ignored by cppcheck):
\ [
\ ],
\ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [
- \ '[bar.cpp:5]: (error) Array ''a[10]'' accessed at index 10, which is out of bounds',
+ \ 'bar.cpp:974:6: error: Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\',
+ \ ' n[3]=3;',
+ \ ' ^',
\ ])
diff --git a/test/handler/test_dockerfile_lint_handler.vader b/test/handler/test_dockerfile_lint_handler.vader
index 619b7bde..a73db8cd 100644
--- a/test/handler/test_dockerfile_lint_handler.vader
+++ b/test/handler/test_dockerfile_lint_handler.vader
@@ -26,21 +26,25 @@ Execute(The dockerfile_lint handler should handle a normal example):
\ 'lnum': -1,
\ 'type': 'E',
\ 'text': "Required LABEL name/key 'Name' is not defined",
+ \ 'detail': "Required LABEL name/key 'Name' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project",
\ },
\ {
\ 'lnum': -1,
\ 'type': 'E',
\ 'text': "Required LABEL name/key 'Version' is not defined",
+ \ 'detail': "Required LABEL name/key 'Version' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project",
\ },
\ {
\ 'lnum': 3,
\ 'type': 'I',
- \ 'text': "the MAINTAINER command is deprecated. MAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0",
+ \ 'text': "the MAINTAINER command is deprecated",
+ \ 'detail': "the MAINTAINER command is deprecated\n\nMAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0\n\nhttps://github.com/docker/cli/blob/master/docs/deprecated.md#maintainer-in-dockerfile",
\ },
\ {
\ 'lnum': -1,
\ 'type': 'I',
\ 'text': "There is no 'CMD' instruction",
+ \ 'detail': "There is no 'CMD' instruction\n\nhttps://docs.docker.com/engine/reference/builder/#cmd",
\ },
\ ],
\ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), [
diff --git a/test/handler/test_eslint_json_handler.vader b/test/handler/test_eslint_json_handler.vader
index 8e07bd80..6235794a 100644
--- a/test/handler/test_eslint_json_handler.vader
+++ b/test/handler/test_eslint_json_handler.vader
@@ -21,6 +21,7 @@ After:
unlet! g:config_error_lines
Execute(The eslint handler should parse json correctly):
+ call ale#test#SetFilename('foo.js')
AssertEqual
\ [
\ {
@@ -53,6 +54,21 @@ Execute(The eslint handler should parse json correctly):
\ '[{"filePath":"foo.js","messages":[{"ruleId":"no-unused-vars","severity":1,"message":"''variable'' is assigned a value but never used.","line":1,"column":7,"nodeType":"Identifier","endLine":1,"endColumn":15},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":15,"nodeType":"ExpressionStatement","fix":{"range":[46,46],"text":";"}},{"ruleId":"no-redeclare","severity":2,"message":"''variable'' is already defined.","line":7,"column":7,"nodeType":"Identifier","endLine":7,"endColumn":15}],"errorCount":1,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":1,"source":"const variable = {\n a: 3\n};\n\nconsole.log(1)\n\nclass variable {\n}\n"}]'
\ ])
+Execute(The eslint handler should suppress deprecation warnings):
+ call ale#test#SetFilename('foo.js')
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 1,
+ \ 'col': 9,
+ \ 'text': 'Parsing error: Unexpected token Controller',
+ \ 'type': 'E',
+ \ }
+ \ ],
+ \ ale#handlers#eslint#HandleJSON(bufnr(''), [
+ \ '[{"filePath":"foo.js","messages":[{"ruleId":null,"fatal":true,"severity":2 ,"message":"Parsing error: Unexpected token Controller","line":1,"column":9}],"errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount": 0,"source":"i:mport Controller from \"@ember/controller\";\nimport listViewControllerMixin from \"elearning/mixins/list-view-controller\";\nimport { inject as service } from \"@ember/service\";\n\nexport default Controller.extend(listViewControllerMixin(), {\n modelName: \"notification\",\n intl: service(),\n\n flatpickrLocale: computed(\"intl.locale\", function() {\n return this.intl.locale.firstObject.split(\"-\")[0];\n })\n});\n"}]', '(node:616989) [ESLINT_LEGACY_OBJECT_REST_SPREAD] DeprecationWarning: The ''parserOptions.ecmaFeatures.experimentalObjectRestSpread'' option is deprecated. Use ''parser Options.ecmaVersion'' instead. (found in "node_modules/eslint-plugin-ember/lib/config/base.js")]'
+ \ ])
+
Execute(The eslint handler should print a message about a missing configuration file):
let g:config_error_lines = [
\ '',
@@ -262,7 +278,7 @@ Execute(Suppressing missing configs shouldn't suppress module import errors):
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should hint about using typescript-eslint-parser):
- silent! noautocmd file foo.ts
+ call ale#test#SetFilename('foo.ts')
AssertEqual
\ [
@@ -326,7 +342,7 @@ Execute(Failing to connect to eslint_d should be handled correctly):
\ ])
Execute(Disabling warnings about trailing spaces should work):
- silent! noautocmd file foo.ts
+ call ale#test#SetFilename('foo.js')
AssertEqual
\ [
diff --git a/test/handler/test_go_generic_handler.vader b/test/handler/test_go_generic_handler.vader
index 624e56c1..2b17fdcb 100644
--- a/test/handler/test_go_generic_handler.vader
+++ b/test/handler/test_go_generic_handler.vader
@@ -15,8 +15,24 @@ Execute(The golang handler should return the correct filenames):
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/other.go'),
\ },
+ \ {
+ \ 'lnum': 18,
+ \ 'col': 0,
+ \ 'text': 'random error',
+ \ 'type': 'E',
+ \ 'filename': ale#path#Simplify(expand('%:p:h') . '/go1.14.go'),
+ \ },
+ \ {
+ \ 'lnum': 36,
+ \ 'col': 2,
+ \ 'text': 'another random error',
+ \ 'type': 'E',
+ \ 'filename': ale#path#Simplify(expand('%:p:h') . '/anothergo1.14.go'),
+ \ },
\ ],
\ ale#handlers#go#Handler(bufnr(''), [
\ 'test.go:27: some error',
\ 'other.go:27:5: some error with a column',
+ \ 'vet: go1.14.go:18:0: random error',
+ \ 'vet: anothergo1.14.go:36:2: another random error',
\ ])
diff --git a/test/handler/test_markdownlint_handler.vader b/test/handler/test_markdownlint_handler.vader
index db6acc66..f2e6e328 100644
--- a/test/handler/test_markdownlint_handler.vader
+++ b/test/handler/test_markdownlint_handler.vader
@@ -4,21 +4,88 @@ Before:
After:
call ale#linter#Reset()
-Execute(The Markdownlint handler should parse output correctly):
+Execute(The Markdownlint handler should parse pre v0.19.0 output with single digit line correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
- \ 'text': '(MD002/first-header-h1) First header should be a top level header [Expected: h1; Actual: h2]',
+ \ 'code': 'MD013/line-length',
+ \ 'text': 'Line length [Expected: 80; Actual: 114]',
\ 'type': 'W'
- \ },
+ \ }
+ \ ],
+ \ ale#handlers#markdownlint#Handle(0, [
+ \ 'README.md: 1: MD013/line-length Line length [Expected: 80; Actual: 114]'
+ \ ])
+
+Execute(The Markdownlint handler should parse pre v0.19.0 output with multi digit line correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 100,
+ \ 'code': 'MD013/line-length',
+ \ 'text': 'Line length [Expected: 80; Actual: 114]',
+ \ 'type': 'W'
+ \ }
+ \ ],
+ \ ale#handlers#markdownlint#Handle(0, [
+ \ 'README.md: 100: MD013/line-length Line length [Expected: 80; Actual: 114]'
+ \ ])
+
+Execute(The Markdownlint handler should parse post v0.19.0 output with single digit line correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 1,
+ \ 'code': 'MD013/line-length',
+ \ 'text': 'Line length [Expected: 80; Actual: 114]',
+ \ 'type': 'W'
+ \ }
+ \ ],
+ \ ale#handlers#markdownlint#Handle(0, [
+ \ 'README.md:1 MD013/line-length Line length [Expected: 80; Actual: 114]'
+ \ ])
+
+Execute(The Markdownlint handler should parse post v0.19.0 output with multi digit line correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 100,
+ \ 'code': 'MD013/line-length',
+ \ 'text': 'Line length [Expected: 80; Actual: 114]',
+ \ 'type': 'W'
+ \ }
+ \ ],
+ \ ale#handlers#markdownlint#Handle(0, [
+ \ 'README.md:100 MD013/line-length Line length [Expected: 80; Actual: 114]'
+ \ ])
+
+
+Execute(The Markdownlint handler should parse post v0.22.0 output with column correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 10,
+ \ 'col': 20,
+ \ 'code': 'MD013/line-length',
+ \ 'text': 'Line length [Expected: 80; Actual: 114]',
+ \ 'type': 'W'
+ \ }
+ \ ],
+ \ ale#handlers#markdownlint#Handle(0, [
+ \ 'README.md:10:20 MD013/line-length Line length [Expected: 80; Actual: 114]'
+ \ ])
+
+Execute(The Markdownlint handler should parse output with multiple slashes in rule name correctly):
+ AssertEqual
+ \ [
\ {
- \ 'lnum': 298,
- \ 'text': '(MD033/no-inline-html) Inline HTML [Element: p]',
+ \ 'lnum': 10,
+ \ 'code': 'MD022/blanks-around-headings/blanks-around-headers',
+ \ 'text': 'Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Above] [Context: "### something"]',
\ 'type': 'W'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
- \ 'README.md: 1: MD002/first-header-h1 First header should be a top level header [Expected: h1; Actual: h2]',
- \ 'README.md: 298: MD033/no-inline-html Inline HTML [Element: p]'
+ \ 'README.md:10 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Above] [Context: "### something"]'
\ ])
diff --git a/test/handler/test_mypy_handler.vader b/test/handler/test_mypy_handler.vader
index 6e96f3f3..039155a2 100644
--- a/test/handler/test_mypy_handler.vader
+++ b/test/handler/test_mypy_handler.vader
@@ -1,6 +1,8 @@
Before:
Save g:ale_python_mypy_ignore_invalid_syntax
+ Save g:ale_python_mypy_show_notes
+ unlet! g:ale_python_mypy_show_notes
unlet! g:ale_python_mypy_ignore_invalid_syntax
runtime ale_linters/python/mypy.vim
@@ -16,6 +18,8 @@ After:
Execute(The mypy handler should parse lines correctly):
call ale#test#SetFilename('__init__.py')
+ let g:ale_python_mypy_show_notes = 0
+
AssertEqual
\ [
\ {
@@ -69,6 +73,31 @@ Execute(The mypy handler should parse lines correctly):
\ '__init__.py:72:1: warning: Some warning',
\ ])
+Execute(The mypy handler should show notes if enabled):
+ call ale#test#SetFilename('__init__.py')
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 72,
+ \ 'col': 1,
+ \ 'filename': ale#path#Simplify(g:dir . '/__init__.py'),
+ \ 'type': 'I',
+ \ 'text': 'A note',
+ \ },
+ \ ],
+ \ ale_linters#python#mypy#Handle(bufnr(''), [
+ \ '__init__.py:72:1: note: A note',
+ \ ])
+
+ let g:ale_python_mypy_show_notes = 0
+
+ AssertEqual
+ \ [],
+ \ ale_linters#python#mypy#Handle(bufnr(''), [
+ \ '__init__.py:72:1: note: A note',
+ \ ])
+
Execute(The mypy handler should handle Windows names with spaces):
" This test works on Unix, where this is seen as a single filename
silent file C:\\something\\with\ spaces.py
diff --git a/test/handler/test_puppet_handler.vader b/test/handler/test_puppet_handler.vader
index e73c9dc7..03adc9f0 100644
--- a/test/handler/test_puppet_handler.vader
+++ b/test/handler/test_puppet_handler.vader
@@ -49,3 +49,29 @@ Execute(The puppet handler should parse lines and column correctly):
\ "Error: Could not parse for environment production: Syntax error at ':' at C:/puppet/modules/nginx/manifests/init.pp:54:9",
\ "Error: Could not parse for environment production: Syntax error at 'parameter1' (file: /tmp/modules/mariadb/manifests/slave.pp, line: 45, column: 12)",
\ ])
+
+Execute(The puppet handler should correctly parse errors that are reported before even trying to parse for an environment):
+ " Line Error
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 5,
+ \ 'col': 11,
+ \ 'text': "Illegal attempt to assign to 'a Name'. Not an assignable reference"
+ \ },
+ \ ],
+ \ ale_linters#puppet#puppet#Handle(255, [
+ \ "Error: Illegal attempt to assign to 'a Name'. Not an assignable reference (file: /tmp/modules/waffles/manifests/syrup.pp, line: 5, column: 11)",
+ \ ])
+Execute(The puppet handler should parse lines when end of input is the location):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 0,
+ \ 'col': 0,
+ \ 'text': "Syntax error at end of input"
+ \ },
+ \ ],
+ \ ale_linters#puppet#puppet#Handle(255, [
+ \ "Error: Could not parse for environment production: Syntax error at end of input (file: /tmp//modules/test/manifests/init.pp)",
+ \ ])
diff --git a/test/handler/test_shellcheck_handler.vader b/test/handler/test_shellcheck_handler.vader
index bfb73ffa..33f12989 100644
--- a/test/handler/test_shellcheck_handler.vader
+++ b/test/handler/test_shellcheck_handler.vader
@@ -22,7 +22,7 @@ Execute(The shellcheck handler should handle basic errors or warnings):
\ 'code': 'SC1068',
\ },
\ ],
- \ ale_linters#sh#shellcheck#Handle(bufnr(''), [
+ \ ale#handlers#shellcheck#Handle(bufnr(''), [
\ '-:2:1: warning: In POSIX sh, ''let'' is not supported. [SC2039]',
\ '-:2:3: error: Don''t put spaces around the = in assignments. [SC1068]',
\ ])
@@ -38,6 +38,6 @@ Execute(The shellcheck handler should handle notes):
\ 'code': 'SC2086',
\ },
\ ],
- \ ale_linters#sh#shellcheck#Handle(bufnr(''), [
+ \ ale#handlers#shellcheck#Handle(bufnr(''), [
\ '-:3:3: note: Double quote to prevent globbing and word splitting. [SC2086]',
\ ])
diff --git a/test/handler/test_verilator_handler.vader b/test/handler/test_verilator_handler.vader
new file mode 100644
index 00000000..5e51b5c9
--- /dev/null
+++ b/test/handler/test_verilator_handler.vader
@@ -0,0 +1,48 @@
+Before:
+ runtime ale_linters/verilog/verilator.vim
+
+After:
+ call ale#linter#Reset()
+
+
+Execute (The verilator handler should parse legacy messages with only line numbers):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 3,
+ \ 'type': 'E',
+ \ 'text': 'syntax error, unexpected IDENTIFIER'
+ \ },
+ \ {
+ \ 'lnum': 10,
+ \ 'type': 'W',
+ \ 'text': 'Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).'
+ \ },
+ \ ],
+ \ ale_linters#verilog#verilator#Handle(bufnr(''), [
+ \ '%Error: foo_verilator_linted.v:3: syntax error, unexpected IDENTIFIER',
+ \ '%Warning-BLKSEQ: bar_verilator_linted.v:10: Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).',
+ \ ])
+
+
+Execute (The verilator handler should parse new format messages with line and column numbers):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 3,
+ \ 'col' : 1,
+ \ 'type': 'E',
+ \ 'text': 'syntax error, unexpected endmodule, expecting ;'
+ \ },
+ \ {
+ \ 'lnum': 4,
+ \ 'col' : 6,
+ \ 'type': 'W',
+ \ 'text': 'Signal is not used: r'
+ \ },
+ \ ],
+ \ ale_linters#verilog#verilator#Handle(bufnr(''), [
+ \ '%Error: bar_verilator_linted.v:3:1: syntax error, unexpected endmodule, expecting ;',
+ \ '%Warning-UNUSED: foo_verilator_linted.v:4:6: Signal is not used: r',
+ \ ])
+
diff --git a/test/lsp/test_other_initialize_message_handling.vader b/test/lsp/test_other_initialize_message_handling.vader
index 6473e283..b6ef852a 100644
--- a/test/lsp/test_other_initialize_message_handling.vader
+++ b/test/lsp/test_other_initialize_message_handling.vader
@@ -131,7 +131,7 @@ Execute(Disabled capabilities should be recognised correctly):
\ },
\ 'definitionProvider': v:false,
\ 'experimental': {},
- \ 'documentHighlightProvider': v:true
+ \ 'documentHighlightProvider': v:true,
\ },
\ },
\})
@@ -150,6 +150,57 @@ Execute(Disabled capabilities should be recognised correctly):
\ b:conn.capabilities
AssertEqual [[1, 'initialized', {}]], g:message_list
+Execute(Capabilities should be enabled when send as Dictionaries):
+ call ale#lsp#HandleInitResponse(b:conn, {
+ \ 'jsonrpc': '2.0',
+ \ 'id': 1,
+ \ 'result': {
+ \ 'capabilities': {
+ \ 'renameProvider': {},
+ \ 'executeCommandProvider': {
+ \ 'commands': [],
+ \ },
+ \ 'hoverProvider': {},
+ \ 'documentSymbolProvider': v:true,
+ \ 'documentRangeFormattingProvider': v:true,
+ \ 'codeLensProvider': {
+ \ 'resolveProvider': v:false
+ \ },
+ \ 'completionProvider': {
+ \ 'triggerCharacters': ['.'],
+ \ 'resolveProvider': v:false
+ \ },
+ \ 'referencesProvider': {},
+ \ 'textDocumentSync': 2,
+ \ 'documentFormattingProvider': v:true,
+ \ 'codeActionProvider': v:true,
+ \ 'signatureHelpProvider': {
+ \ 'triggerCharacters': ['(', ','],
+ \ },
+ \ 'definitionProvider': {},
+ \ 'typeDefinitionProvider': {},
+ \ 'experimental': {},
+ \ 'documentHighlightProvider': v:true,
+ \ 'workspaceSymbolProvider': {}
+ \ },
+ \ },
+ \})
+
+ AssertEqual 1, b:conn.initialized
+ AssertEqual
+ \ {
+ \ 'completion_trigger_characters': ['.'],
+ \ 'completion': 1,
+ \ 'references': 1,
+ \ 'hover': 1,
+ \ 'definition': 1,
+ \ 'typeDefinition': 1,
+ \ 'symbol_search': 1,
+ \ 'rename': 1,
+ \ },
+ \ b:conn.capabilities
+ AssertEqual [[1, 'initialized', {}]], g:message_list
+
Execute(Results that are not dictionaries should be handled correctly):
call ale#lsp#HandleInitResponse(b:conn, {
\ 'jsonrpc': '2.0',
diff --git a/test/python/test_deoplete_source.py b/test/python/test_deoplete_source.py
index 9e56a10d..8304fa25 100644
--- a/test/python/test_deoplete_source.py
+++ b/test/python/test_deoplete_source.py
@@ -8,15 +8,20 @@ ale_module = imp.load_source(
class VimMock(object):
- def __init__(self, call_list, call_results):
+ def __init__(self, call_list, call_results, commands):
self.__call_list = call_list
self.__call_results = call_results
+ self.__commands = commands
+
def call(self, function, *args):
self.__call_list.append((function, args))
return self.__call_results.get(function, 0)
+ def command(self, command):
+ self.__commands.append(command)
+
class DeopleteSourceTest(unittest.TestCase):
def setUp(self):
@@ -24,8 +29,10 @@ class DeopleteSourceTest(unittest.TestCase):
self.call_list = []
self.call_results = {'ale#completion#CanProvideCompletions': 1}
+ self.commands = []
self.source = ale_module.Source('vim')
- self.source.vim = VimMock(self.call_list, self.call_results)
+ self.source.vim = VimMock(
+ self.call_list, self.call_results, self.commands)
def test_attributes(self):
"""
@@ -48,6 +55,7 @@ class DeopleteSourceTest(unittest.TestCase):
'cpp': r'(\.|::|->)\w*$',
},
'is_bytepos': True,
+ 'is_volatile': True,
'mark': '[L]',
'min_pattern_length': 1,
'name': 'ale',
@@ -64,70 +72,28 @@ class DeopleteSourceTest(unittest.TestCase):
])
def test_request_completion_results(self):
- context = {'is_async': False}
+ context = {'event': 'TextChangedI', 'is_refresh': True}
self.assertEqual(self.source.gather_candidates(context), [])
- self.assertEqual(context, {'is_async': True})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
- ('ale#completion#GetCompletions', ('deoplete',)),
+ ])
+ self.assertEqual(self.commands, [
+ "call ale#completion#GetCompletions('ale-callback', " + \
+ "{'callback': {completions -> deoplete#auto_complete() }})"
])
def test_request_completion_results_from_buffer_without_providers(self):
self.call_results['ale#completion#CanProvideCompletions'] = 0
- context = {'is_async': False}
+ context = {'event': 'TextChangedI', 'is_refresh': True}
self.assertIsNone(self.source.gather_candidates(context), [])
- self.assertEqual(context, {'is_async': False})
- self.assertEqual(self.call_list, [
- ('ale#completion#CanProvideCompletions', ()),
- ])
-
- def test_refresh_completion_results(self):
- context = {'is_async': False}
-
- self.assertEqual(self.source.gather_candidates(context), [])
- self.assertEqual(context, {'is_async': True})
- self.assertEqual(self.call_list, [
- ('ale#completion#CanProvideCompletions', ()),
- ('ale#completion#GetCompletions', ('deoplete',)),
- ])
-
- context = {'is_async': True, 'is_refresh': True}
-
- self.assertEqual(self.source.gather_candidates(context), [])
- self.assertEqual(context, {'is_async': True, 'is_refresh': True})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
- ('ale#completion#GetCompletions', ('deoplete',)),
- ('ale#completion#CanProvideCompletions', ()),
- ('ale#completion#GetCompletions', ('deoplete',)),
])
- def test_poll_no_result(self):
- context = {'is_async': True}
- self.call_results['ale#completion#GetCompletionResult'] = None
-
- self.assertEqual(self.source.gather_candidates(context), [])
- self.assertEqual(context, {'is_async': True})
- self.assertEqual(self.call_list, [
- ('ale#completion#CanProvideCompletions', ()),
- ('ale#completion#GetCompletionResult', ()),
- ])
-
- def test_poll_empty_result_ready(self):
- context = {'is_async': True}
- self.call_results['ale#completion#GetCompletionResult'] = []
-
- self.assertEqual(self.source.gather_candidates(context), [])
- self.assertEqual(context, {'is_async': False})
- self.assertEqual(self.call_list, [
- ('ale#completion#CanProvideCompletions', ()),
- ('ale#completion#GetCompletionResult', ()),
- ])
-
- def test_poll_non_empty_result_ready(self):
- context = {'is_async': True}
+ def test_async_event(self):
+ context = {'event': 'Async', 'is_refresh': True}
self.call_results['ale#completion#GetCompletionResult'] = [
{
'word': 'foobar',
@@ -147,7 +113,7 @@ class DeopleteSourceTest(unittest.TestCase):
'info': '',
},
])
- self.assertEqual(context, {'is_async': False})
+
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
('ale#completion#GetCompletionResult', ()),
diff --git a/test/sign/test_linting_sets_signs.vader b/test/sign/test_linting_sets_signs.vader
index 60ae0a83..1d1f9802 100644
--- a/test/sign/test_linting_sets_signs.vader
+++ b/test/sign/test_linting_sets_signs.vader
@@ -32,7 +32,7 @@ Before:
function! CollectSigns()
redir => l:output
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
silent exec 'sign place group=ale'
else
silent exec 'sign place'
diff --git a/test/sign/test_sign_parsing.vader b/test/sign/test_sign_parsing.vader
index 157ff2f4..c0967f43 100644
--- a/test/sign/test_sign_parsing.vader
+++ b/test/sign/test_sign_parsing.vader
@@ -1,5 +1,5 @@
Execute (Parsing English signs should work):
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[9, 1000001, 'ALEWarningSign']]],
\ ale#sign#ParseSigns([
@@ -16,7 +16,7 @@ Execute (Parsing English signs should work):
endif
Execute (Parsing Russian signs should work):
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[1, 1000001, 'ALEErrorSign']]],
\ ale#sign#ParseSigns([' строка=1 id=1000001 группа=ale имя=ALEErrorSign'])
@@ -27,7 +27,7 @@ Execute (Parsing Russian signs should work):
endif
Execute (Parsing Japanese signs should work):
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[1, 1000001, 'ALEWarningSign']]],
\ ale#sign#ParseSigns([' 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign'])
@@ -38,7 +38,7 @@ Execute (Parsing Japanese signs should work):
endif
Execute (Parsing Spanish signs should work):
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[12, 1000001, 'ALEWarningSign']]],
\ ale#sign#ParseSigns([' línea=12 id=1000001 grupo=ale nombre=ALEWarningSign'])
@@ -49,7 +49,7 @@ Execute (Parsing Spanish signs should work):
endif
Execute (Parsing Italian signs should work):
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[1, 1000001, 'ALEWarningSign']]],
\ ale#sign#ParseSigns([' riga=1 id=1000001, gruppo=ale nome=ALEWarningSign'])
@@ -60,7 +60,7 @@ Execute (Parsing Italian signs should work):
endif
Execute (Parsing German signs should work):
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[235, 1000001, 'ALEErrorSign']]],
\ ale#sign#ParseSigns([' Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign'])
@@ -71,7 +71,7 @@ Execute (Parsing German signs should work):
endif
Execute (The sign parser should indicate if the dummy sign is set):
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [1, [[1, 1000001, 'ALEErrorSign']]],
\ ale#sign#ParseSigns([
diff --git a/test/sign/test_sign_placement.vader b/test/sign/test_sign_placement.vader
index 80153b22..d8d05b28 100644
--- a/test/sign/test_sign_placement.vader
+++ b/test/sign/test_sign_placement.vader
@@ -68,7 +68,7 @@ Before:
function! ParseSigns()
redir => l:output
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
silent sign place group=ale
else
silent sign place
@@ -152,7 +152,7 @@ Execute(The current signs should be set for running a job):
\ ParseSigns()
Execute(Loclist items with sign_id values should be kept):
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
exec 'sign place 1000347 group=ale line=3 name=ALEErrorSign buffer=' . bufnr('')
exec 'sign place 1000348 group=ale line=15 name=ALEErrorSign buffer=' . bufnr('')
exec 'sign place 1000349 group=ale line=16 name=ALEWarningSign buffer=' . bufnr('')
@@ -297,7 +297,7 @@ Execute(No exceptions should be thrown when setting signs for invalid buffers):
Execute(Signs should be removed when lines have multiple sign IDs on them):
" We can fail to remove signs if there are multiple signs on one line,
" say after deleting lines in Vim, etc.
- if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
+ if has('nvim-0.4.2') || has('patch-8.1.614')
exec 'sign place 1000347 group=ale line=3 name=ALEErrorSign buffer=' . bufnr('')
exec 'sign place 1000348 group=ale line=3 name=ALEWarningSign buffer=' . bufnr('')
exec 'sign place 1000349 group=ale line=10 name=ALEErrorSign buffer=' . bufnr('')
diff --git a/test/terraform_files/main.tf b/test/terraform_files/main.tf
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/terraform_files/main.tf
diff --git a/test/test_ale_has.vader b/test/test_ale_has.vader
index b8a99103..633c7186 100644
--- a/test/test_ale_has.vader
+++ b/test/test_ale_has.vader
@@ -1,4 +1,5 @@
Execute(Checks for versions below the current version should succeed):
+ AssertEqual 1, ale#Has('ale-2.7.0')
AssertEqual 1, ale#Has('ale-2.6.0')
AssertEqual 1, ale#Has('ale-2.5.0')
AssertEqual 1, ale#Has('ale-2.4.0')
diff --git a/test/test_autocmd_commands.vader b/test/test_autocmd_commands.vader
index 355b4c77..a69333d4 100644
--- a/test/test_autocmd_commands.vader
+++ b/test/test_autocmd_commands.vader
@@ -49,6 +49,7 @@ Before:
Save g:ale_lint_on_save
Save g:ale_lint_on_text_changed
Save g:ale_pattern_options_enabled
+ Save g:ale_hover_cursor
" Turn everything on by defaul for these tests.
let g:ale_completion_enabled = 1
@@ -61,6 +62,7 @@ Before:
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 1
let g:ale_pattern_options_enabled = 1
+ let g:ale_hover_cursor = 1
After:
delfunction CheckAutocmd
@@ -84,6 +86,7 @@ Execute (All events should be set up when everything is on):
\ 'BufWinEnter * call ale#events#LintOnEnter(str2nr(expand(''<abuf>'')))',
\ 'BufWritePost * call ale#events#SaveEvent(str2nr(expand(''<abuf>'')))',
\ 'CursorHold * if exists(''*ale#engine#Cleanup'') | call ale#cursor#EchoCursorWarningWithDelay() | endif',
+ \ 'CursorHold if exists(''*ale#lsp#Send'') | call ale#hover#ShowTruncatedMessageAtCursor() | endif',
\ 'CursorMoved * if exists(''*ale#engine#Cleanup'') | call ale#cursor#EchoCursorWarningWithDelay() | endif',
\ 'FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand(''<abuf>'')))',
\ 'FileType * call ale#events#FileTypeEvent( str2nr(expand(''<abuf>'')), expand(''<amatch>''))',
@@ -95,9 +98,30 @@ Execute (All events should be set up when everything is on):
\ CheckAutocmd('ALEEvents')
Execute (Only the required events should be bound even if various settings are off):
+ let g:ale_enabled = 1
+ let g:ale_completion_enabled = 0
+ let g:ale_echo_cursor = 0
+ let g:ale_fix_on_save = 0
+ let g:ale_lint_on_enter = 0
+ let g:ale_lint_on_filetype_changed = 0
+ let g:ale_lint_on_insert_leave = 0
+ let g:ale_lint_on_save = 0
+ let g:ale_lint_on_text_changed = 0
+ let g:ale_pattern_options_enabled = 0
+ let g:ale_hover_cursor = 0
+
+ AssertEqual
+ \ [
+ \ 'BufEnter * call ale#events#ReadOrEnterEvent(str2nr(expand(''<abuf>'')))',
+ \ 'BufReadPost * call ale#events#ReadOrEnterEvent(str2nr(expand(''<abuf>'')))',
+ \ 'BufWritePost * call ale#events#SaveEvent(str2nr(expand(''<abuf>'')))',
+ \ ],
+ \ CheckAutocmd('ALEEvents')
+
+Execute (The cursor hoever event should be enabled with g:ale_hover_cursor = 1):
+ let g:ale_enabled = 1
let g:ale_completion_enabled = 0
let g:ale_echo_cursor = 0
- let g:ale_enabled = 0
let g:ale_fix_on_save = 0
let g:ale_lint_on_enter = 0
let g:ale_lint_on_filetype_changed = 0
@@ -105,12 +129,14 @@ Execute (Only the required events should be bound even if various settings are o
let g:ale_lint_on_save = 0
let g:ale_lint_on_text_changed = 0
let g:ale_pattern_options_enabled = 0
+ let g:ale_hover_cursor = 1
AssertEqual
\ [
\ 'BufEnter * call ale#events#ReadOrEnterEvent(str2nr(expand(''<abuf>'')))',
\ 'BufReadPost * call ale#events#ReadOrEnterEvent(str2nr(expand(''<abuf>'')))',
\ 'BufWritePost * call ale#events#SaveEvent(str2nr(expand(''<abuf>'')))',
+ \ 'CursorHold * if exists(''*ale#lsp#Send'') | call ale#hover#ShowTruncatedMessageAtCursor() | endif',
\ ],
\ CheckAutocmd('ALEEvents')
diff --git a/test/test_c_projects/makefile_project/_astylerc b/test/test_c_projects/makefile_project/_astylerc
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/test_c_projects/makefile_project/_astylerc
diff --git a/test/test_code_action.vader b/test/test_code_action.vader
index ffaca630..b47f24ff 100644
--- a/test/test_code_action.vader
+++ b/test/test_code_action.vader
@@ -37,10 +37,10 @@ Before:
After:
" Close the extra buffers if we opened it.
if bufnr(g:file1) != -1
- execute ':bp | :bd ' . bufnr(g:file1)
+ execute ':bp! | :bd! ' . bufnr(g:file1)
endif
if bufnr(g:file2) != -1
- execute ':bp | :bd ' . bufnr(g:file2)
+ execute ':bp! | :bd! ' . bufnr(g:file2)
endif
if filereadable(g:file1)
@@ -116,7 +116,7 @@ Execute(It should modify and save multiple files):
\ 'newText': "import {A, B} from 'module'\n\n",
\ }]
\ }],
- \})
+ \}, v:true)
AssertEqual [
\ 'class Value {',
@@ -161,7 +161,7 @@ Execute(Beginning of file can be modified):
\ 'newText': "type A: string\ntype B: number\n",
\ }],
\ }]
- \})
+ \}, v:true)
AssertEqual [
\ 'type A: string',
@@ -192,7 +192,7 @@ Execute(End of file can be modified):
\ 'newText': "type A: string\ntype B: number\n",
\ }],
\ }]
- \})
+ \}, v:true)
AssertEqual g:test.text + [
\ 'type A: string',
@@ -227,7 +227,7 @@ Execute(Current buffer contents will be reloaded):
\ 'newText': "type A: string\ntype B: number\n",
\ }],
\ }]
- \})
+ \}, v:true)
AssertEqual [
\ 'type A: string',
@@ -249,11 +249,11 @@ Execute(Cursor will not move when it is before text change):
let g:test.changes = g:test.create_change(2, 3, 2, 8, 'value2')
call setpos('.', [0, 1, 1, 0])
- call ale#code_action#HandleCodeAction(g:test.changes)
+ call ale#code_action#HandleCodeAction(g:test.changes, v:true)
AssertEqual [1, 1], getpos('.')[1:2]
call setpos('.', [0, 2, 2, 0])
- call ale#code_action#HandleCodeAction(g:test.changes)
+ call ale#code_action#HandleCodeAction(g:test.changes, v:true)
AssertEqual [2, 2], getpos('.')[1:2]
# ====C====
@@ -264,7 +264,7 @@ Execute(Cursor column will move to the change end when cursor between start/end)
call WriteFileAndEdit()
call setpos('.', [0, 2, r, 0])
AssertEqual ' value: string', getline('.')
- call ale#code_action#HandleCodeAction(g:test.changes)
+ call ale#code_action#HandleCodeAction(g:test.changes, v:true)
AssertEqual ' value2: string', getline('.')
AssertEqual [2, 9], getpos('.')[1:2]
endfor
@@ -275,7 +275,8 @@ Execute(Cursor column will move back when new text is shorter):
call WriteFileAndEdit()
call setpos('.', [0, 2, 8, 0])
AssertEqual ' value: string', getline('.')
- call ale#code_action#HandleCodeAction(g:test.create_change(2, 3, 2, 8, 'val'))
+ call ale#code_action#HandleCodeAction(
+ \ g:test.create_change(2, 3, 2, 8, 'val'), v:true)
AssertEqual ' val: string', getline('.')
AssertEqual [2, 6], getpos('.')[1:2]
@@ -286,7 +287,8 @@ Execute(Cursor column will move forward when new text is longer):
call setpos('.', [0, 2, 8, 0])
AssertEqual ' value: string', getline('.')
- call ale#code_action#HandleCodeAction(g:test.create_change(2, 3, 2, 8, 'longValue'))
+ call ale#code_action#HandleCodeAction(
+ \ g:test.create_change(2, 3, 2, 8, 'longValue'), v:true)
AssertEqual ' longValue: string', getline('.')
AssertEqual [2, 12], getpos('.')[1:2]
@@ -297,7 +299,8 @@ Execute(Cursor line will move when updates are happening on lines above):
call WriteFileAndEdit()
call setpos('.', [0, 3, 1, 0])
AssertEqual '}', getline('.')
- call ale#code_action#HandleCodeAction(g:test.create_change(1, 1, 2, 1, "test\ntest\n"))
+ call ale#code_action#HandleCodeAction(
+ \ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), v:true)
AssertEqual '}', getline('.')
AssertEqual [4, 1], getpos('.')[1:2]
@@ -308,7 +311,8 @@ Execute(Cursor line and column will move when change on lines above and just bef
call WriteFileAndEdit()
call setpos('.', [0, 2, 2, 0])
AssertEqual ' value: string', getline('.')
- call ale#code_action#HandleCodeAction(g:test.create_change(1, 1, 2, 1, "test\ntest\n123"))
+ call ale#code_action#HandleCodeAction(
+ \ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), v:true)
AssertEqual '123 value: string', getline('.')
AssertEqual [3, 5], getpos('.')[1:2]
@@ -319,7 +323,8 @@ Execute(Cursor line and column will move at the end of changes):
call WriteFileAndEdit()
call setpos('.', [0, 2, 10, 0])
AssertEqual ' value: string', getline('.')
- call ale#code_action#HandleCodeAction(g:test.create_change(1, 1, 3, 1, "test\n"))
+ call ale#code_action#HandleCodeAction(
+ \ g:test.create_change(1, 1, 3, 1, "test\n"), v:true)
AssertEqual '}', getline('.')
AssertEqual [2, 1], getpos('.')[1:2]
@@ -329,6 +334,19 @@ Execute(Cursor will not move when changes happening on lines >= cursor, but afte
call WriteFileAndEdit()
call setpos('.', [0, 2, 3, 0])
AssertEqual ' value: string', getline('.')
- call ale#code_action#HandleCodeAction(g:test.create_change(2, 10, 3, 1, "number\n"))
+ call ale#code_action#HandleCodeAction(
+ \ g:test.create_change(2, 10, 3, 1, "number\n"), v:true)
AssertEqual ' value: number', getline('.')
AssertEqual [2, 3], getpos('.')[1:2]
+
+Execute(It should just modify file when should_save is set to v:false):
+ call WriteFileAndEdit()
+ let g:test.change = g:test.create_change(1, 1, 1, 1, "import { writeFile } from 'fs';\n")
+ call ale#code_action#HandleCodeAction(g:test.change, v:false)
+ AssertEqual 1, getbufvar(bufnr(''), '&modified')
+ AssertEqual [
+ \ 'import { writeFile } from ''fs'';',
+ \ 'class Name {',
+ \ ' value: string',
+ \ '}',
+ \], getline(1, '$')
diff --git a/test/test_cpp_project/.astylerc b/test/test_cpp_project/.astylerc
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/test_cpp_project/.astylerc
diff --git a/test/test_cpp_project/dummy.cpp b/test/test_cpp_project/dummy.cpp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/test_cpp_project/dummy.cpp
diff --git a/test/test_cursor_warnings.vader b/test/test_cursor_warnings.vader
index 2a6156f0..339cd71e 100644
--- a/test/test_cursor_warnings.vader
+++ b/test/test_cursor_warnings.vader
@@ -15,7 +15,7 @@ Before:
\ 'col': 10,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
- \ 'linter_name': 'eslint',
+ \ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'W',
\ 'code': 'semi',
@@ -26,7 +26,7 @@ Before:
\ 'col': 10,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
- \ 'linter_name': 'eslint',
+ \ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'E',
\ 'code': 'semi',
@@ -38,7 +38,7 @@ Before:
\ 'col': 14,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
- \ 'linter_name': 'eslint',
+ \ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'I',
\ 'text': 'Some information',
@@ -48,7 +48,7 @@ Before:
\ 'col': 10,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
- \ 'linter_name': 'eslint',
+ \ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'W',
\ 'code': 'space-infix-ops',
@@ -59,7 +59,7 @@ Before:
\ 'col': 15,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
- \ 'linter_name': 'eslint',
+ \ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'E',
\ 'code': 'radix',
@@ -70,7 +70,7 @@ Before:
\ 'col': 1,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
- \ 'linter_name': 'eslint',
+ \ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'E',
\ 'text': 'lowercase error',
@@ -196,7 +196,7 @@ Execute(The linter name should be formatted into the message correctly):
call ale#cursor#EchoCursorWarning()
AssertEqual
- \ 'eslint: Infix operators must be spaced.',
+ \ 'bettercode: Infix operators must be spaced.',
\ GetLastMessage()
Execute(The severity should be formatted into the message correctly):
diff --git a/test/test_eslint_executable_detection.vader b/test/test_eslint_executable_detection.vader
index 64383dcb..3fed63da 100644
--- a/test/test_eslint_executable_detection.vader
+++ b/test/test_eslint_executable_detection.vader
@@ -57,13 +57,44 @@ Execute(eslint.js executables should be run with node on Windows):
" We have to execute the file with node.
if has('win32')
AssertEqual
- \ ale#Escape('node.exe') . ' '
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app'))
+ \ . ale#Escape('node.exe') . ' '
\ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -f json --stdin --stdin-filename %s',
\ ale#handlers#eslint#GetCommand(bufnr(''))
else
AssertEqual
- \ ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app'))
+ \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
+ \ . ' -f json --stdin --stdin-filename %s',
+ \ ale#handlers#eslint#GetCommand(bufnr(''))
+ endif
+
+Execute(eslint.js should be run from containing project with eslint):
+ call ale#test#SetFilename('eslint-test-files/react-app/subdir-with-package-json/testfile.js')
+
+ " We have to execute the file with node.
+ if has('win32')
+ AssertEqual
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app'))
+ \ . ale#Escape('node.exe') . ' '
+ \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
+ \ . ' -f json --stdin --stdin-filename %s',
+ \ ale#handlers#eslint#GetCommand(bufnr(''))
+ else
+ AssertEqual
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app'))
+ \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -f json --stdin --stdin-filename %s',
\ ale#handlers#eslint#GetCommand(bufnr(''))
endif
+
+Execute(eslint.js executables can be run outside project dir):
+ " Set filename above eslint-test-files (which contains node_modules)
+ call ale#test#SetFilename('testfile.js')
+
+ " cd "..." not present, since project root not found (from node_modules)
+ AssertEqual
+ \ ale#Escape(ale#handlers#eslint#GetExecutable(bufnr('')))
+ \ . ' -f json --stdin --stdin-filename %s',
+ \ ale#handlers#eslint#GetCommand(bufnr(''))
diff --git a/test/test_filetype_linter_defaults.vader b/test/test_filetype_linter_defaults.vader
index 9c40cb23..842cc394 100644
--- a/test/test_filetype_linter_defaults.vader
+++ b/test/test_filetype_linter_defaults.vader
@@ -32,7 +32,7 @@ Execute(The defaults for the help filetype should be correct):
AssertEqual [], GetLinterNames('help')
Execute(The defaults for the python filetype should be correct):
- AssertEqual ['flake8', 'mypy', 'pylint'], GetLinterNames('python')
+ AssertEqual ['flake8', 'mypy', 'pylint', 'pyright'], GetLinterNames('python')
let g:ale_linters_explicit = 1
@@ -61,7 +61,7 @@ Execute(The defaults for the zsh filetype should be correct):
Execute(The defaults for the verilog filetype should be correct):
" This filetype isn't configured with default, so we can test loading all
" available linters with this.
- AssertEqual ['iverilog', 'verilator', 'vlog', 'xvlog'], GetLinterNames('verilog')
+ AssertEqual ['hdl-checker', 'iverilog', 'verilator', 'vlog', 'xvlog'], GetLinterNames('verilog')
let g:ale_linters_explicit = 1
diff --git a/test/test_find_references.vader b/test/test_find_references.vader
index 1a147849..9949362a 100644
--- a/test/test_find_references.vader
+++ b/test/test_find_references.vader
@@ -2,6 +2,8 @@ Before:
call ale#test#SetDirectory('/testplugin/test')
call ale#test#SetFilename('dummy.txt')
+ Save g:ale_default_navigation
+
let g:old_filename = expand('%:p')
let g:Callback = ''
let g:expr_list = []
@@ -12,6 +14,7 @@ Before:
let g:capability_checked = ''
let g:conn_id = v:null
let g:InitCallback = v:null
+ let g:ale_default_navigation = 'buffer'
runtime autoload/ale/lsp_linter.vim
runtime autoload/ale/lsp.vim
@@ -63,6 +66,8 @@ Before:
endfunction
After:
+ Restore
+
if g:conn_id isnot v:null
call ale#lsp#RemoveConnectionWithID(g:conn_id)
endif
@@ -152,6 +157,20 @@ Execute(Results should be shown for tsserver responses):
\ g:item_list
AssertEqual {}, ale#references#GetMap()
+ " We should be able to repeat selections with ALERepeatSelection
+ let g:ale_item_list = []
+
+ ALERepeatSelection
+
+ AssertEqual
+ \ [
+ \ {'filename': '/foo/bar/app.ts', 'column': 9, 'line': 9, 'match': 'import {doSomething} from ''./whatever'''},
+ \ {'filename': '/foo/bar/app.ts', 'column': 3, 'line': 804, 'match': 'doSomething()'},
+ \ {'filename': '/foo/bar/other/app.ts', 'column': 3, 'line': 51, 'match': 'doSomething()'},
+ \ ],
+ \ g:item_list
+ AssertEqual {}, ale#references#GetMap()
+
Execute(The preview window should not be opened for empty tsserver responses):
call ale#references#SetMap({3: {}})
call ale#references#HandleTSServerResponse(1, {
@@ -195,7 +214,7 @@ Execute(tsserver reference requests should be sent):
\ [0, 'ts@references', {'file': expand('%:p'), 'line': 2, 'offset': 5}]
\ ],
\ g:message_list
- AssertEqual {'42': {'use_relative_paths': 0}}, ale#references#GetMap()
+ AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 0}}, ale#references#GetMap()
Execute('-relative' argument should enable 'use_relative_paths' in HandleTSServerResponse):
runtime ale_linters/typescript/tsserver.vim
@@ -205,7 +224,48 @@ Execute('-relative' argument should enable 'use_relative_paths' in HandleTSServe
call g:InitCallback()
- AssertEqual {'42': {'use_relative_paths': 1}}, ale#references#GetMap()
+ AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 1}}, ale#references#GetMap()
+
+Execute(`-tab` should display results in tabs):
+ runtime ale_linters/typescript/tsserver.vim
+ call setpos('.', [bufnr(''), 2, 5, 0])
+
+ ALEFindReferences -tab
+
+ call g:InitCallback()
+
+ AssertEqual {'42': {'open_in': 'tab', 'use_relative_paths': 0}}, ale#references#GetMap()
+
+Execute(The default navigation type should be used):
+ runtime ale_linters/typescript/tsserver.vim
+ call setpos('.', [bufnr(''), 2, 5, 0])
+
+ let g:ale_default_navigation = 'tab'
+ ALEFindReferences
+
+ call g:InitCallback()
+
+ AssertEqual {'42': {'open_in': 'tab', 'use_relative_paths': 0}}, ale#references#GetMap()
+
+Execute(`-split` should display results in splits):
+ runtime ale_linters/typescript/tsserver.vim
+ call setpos('.', [bufnr(''), 2, 5, 0])
+
+ ALEFindReferences -split
+
+ call g:InitCallback()
+
+ AssertEqual {'42': {'open_in': 'split', 'use_relative_paths': 0}}, ale#references#GetMap()
+
+Execute(`-vsplit` should display results in vsplits):
+ runtime ale_linters/typescript/tsserver.vim
+ call setpos('.', [bufnr(''), 2, 5, 0])
+
+ ALEFindReferences -vsplit
+
+ call g:InitCallback()
+
+ AssertEqual {'42': {'open_in': 'vsplit', 'use_relative_paths': 0}}, ale#references#GetMap()
Given python(Some Python file):
foo
@@ -302,7 +362,7 @@ Execute(LSP reference requests should be sent):
\ ],
\ g:message_list
- AssertEqual {'42': {'use_relative_paths': 0}}, ale#references#GetMap()
+ AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 0}}, ale#references#GetMap()
Execute('-relative' argument should enable 'use_relative_paths' in HandleLSPResponse):
runtime ale_linters/python/pyls.vim
@@ -313,4 +373,4 @@ Execute('-relative' argument should enable 'use_relative_paths' in HandleLSPResp
call g:InitCallback()
- AssertEqual {'42': {'use_relative_paths': 1}}, ale#references#GetMap()
+ AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 1}}, ale#references#GetMap()
diff --git a/test/test_go_to_definition.vader b/test/test_go_to_definition.vader
index 3479d7b5..a517bd54 100644
--- a/test/test_go_to_definition.vader
+++ b/test/test_go_to_definition.vader
@@ -2,6 +2,8 @@ Before:
call ale#test#SetDirectory('/testplugin/test')
call ale#test#SetFilename('dummy.txt')
+ Save g:ale_default_navigation
+
let g:old_filename = expand('%:p')
let g:Callback = ''
let g:message_list = []
@@ -9,6 +11,7 @@ Before:
let g:capability_checked = ''
let g:conn_id = v:null
let g:InitCallback = v:null
+ let g:ale_default_navigation = 'buffer'
runtime autoload/ale/linter.vim
runtime autoload/ale/lsp_linter.vim
@@ -54,6 +57,8 @@ Before:
endfunction
After:
+ Restore
+
if g:conn_id isnot v:null
call ale#lsp#RemoveConnectionWithID(g:conn_id)
endif
@@ -164,7 +169,7 @@ Execute(Other files should be jumped to for definition responses in tabs too):
AssertEqual {}, ale#definition#GetMap()
Execute(Other files should be jumped to for definition responses in splits too):
- call ale#definition#SetMap({3: {'open_in': 'horizontal-split'}})
+ call ale#definition#SetMap({3: {'open_in': 'split'}})
call ale#definition#HandleTSServerResponse(
\ 1,
\ {
@@ -189,7 +194,7 @@ Execute(Other files should be jumped to for definition responses in splits too):
AssertEqual {}, ale#definition#GetMap()
Execute(Other files should be jumped to for definition responses in vsplits too):
- call ale#definition#SetMap({3: {'open_in': 'vertical-split'}})
+ call ale#definition#SetMap({3: {'open_in': 'vsplit'}})
call ale#definition#HandleTSServerResponse(
\ 1,
\ {
@@ -241,7 +246,32 @@ Execute(tsserver tab definition requests should be sent):
runtime ale_linters/typescript/tsserver.vim
call setpos('.', [bufnr(''), 2, 5, 0])
- ALEGoToDefinitionInTab
+ ALEGoToDefinition -tab
+
+ " We shouldn't register the callback yet.
+ AssertEqual '''''', string(g:Callback)
+
+ AssertEqual type(function('type')), type(g:InitCallback)
+ call g:InitCallback()
+
+ AssertEqual 'definition', g:capability_checked
+ AssertEqual
+ \ 'function(''ale#definition#HandleTSServerResponse'')',
+ \ string(g:Callback)
+ AssertEqual
+ \ [
+ \ ale#lsp#tsserver_message#Change(bufnr('')),
+ \ [0, 'ts@definition', {'file': expand('%:p'), 'line': 2, 'offset': 5}]
+ \ ],
+ \ g:message_list
+ AssertEqual {'42': {'open_in': 'tab'}}, ale#definition#GetMap()
+
+Execute(The default navigation type should be used):
+ runtime ale_linters/typescript/tsserver.vim
+ call setpos('.', [bufnr(''), 2, 5, 0])
+
+ let g:ale_default_navigation = 'tab'
+ ALEGoToDefinition
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
@@ -448,7 +478,7 @@ Execute(LSP tab definition requests should be sent):
let b:ale_linters = ['pyls']
call setpos('.', [bufnr(''), 1, 5, 0])
- ALEGoToDefinitionInTab
+ ALEGoToDefinition -tab
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
diff --git a/test/test_hdl_checker_options.vader b/test/test_hdl_checker_options.vader
new file mode 100644
index 00000000..4bee0f55
--- /dev/null
+++ b/test/test_hdl_checker_options.vader
@@ -0,0 +1,78 @@
+Before:
+ call ale#assert#SetUpLinterTest('vhdl', 'hdl_checker')
+
+ Save g:ale_hdl_checker_config_file
+ Save g:ale_hdl_checker_options
+
+ let g:default_config_file = has('unix') ? '.hdl_checker.config' : '_hdl_checker.config'
+
+After:
+ Restore
+ call ale#assert#TearDownLinterTest()
+ unlet! g:default_config_file
+
+Execute(Get default initialization dict):
+ AssertEqual
+ \ {'project_file': g:default_config_file},
+ \ ale#handlers#hdl_checker#GetInitOptions(bufnr(''))
+
+Execute(Get custom initialization dict):
+ let g:ale_hdl_checker_config_file = 'some_file_name'
+
+ AssertEqual
+ \ {'project_file': 'some_file_name'},
+ \ ale#handlers#hdl_checker#GetInitOptions(bufnr(''))
+
+Execute(Get the checker command without extra user parameters):
+ AssertEqual
+ \ ale#Escape('hdl_checker') . ' --lsp',
+ \ ale#handlers#hdl_checker#GetCommand(bufnr(''))
+
+Execute(Get the checker command with user configured parameters):
+ let g:ale_hdl_checker_options = '--log-level DEBUG'
+
+ AssertEqual
+ \ ale#Escape('hdl_checker') . ' --lsp --log-level DEBUG',
+ \ ale#handlers#hdl_checker#GetCommand(bufnr(''))
+
+Execute(Customize executable):
+ let g:ale_hdl_checker_executable = '/some/other/path'
+ AssertEqual
+ \ ale#Escape('/some/other/path') . ' --lsp',
+ \ ale#handlers#hdl_checker#GetCommand(bufnr(''))
+
+Execute(Get project root based on .git):
+ call ale#test#SetFilename('hdl_server/with_git/files/foo.vhd')
+ " Create .git file
+ silent! call mkdir(g:dir . '/hdl_server/with_git/.git')
+ AssertNotEqual '', glob(g:dir . '/hdl_server/with_git/.git')
+
+ AssertEqual
+ \ ale#path#Simplify(g:dir . '/hdl_server/with_git'),
+ \ ale#handlers#hdl_checker#GetProjectRoot(bufnr(''))
+
+Execute(Get project root based on config file):
+ call ale#test#SetFilename('hdl_server/with_config_file/foo.vhd')
+
+ AssertEqual
+ \ ale#path#Simplify(g:dir . '/hdl_server/with_config_file'),
+ \ ale#handlers#hdl_checker#GetProjectRoot(bufnr(''))
+
+Execute(Return no project root if neither .git or config file are found):
+ let g:call_count = 0
+
+ " Mock this command to avoid the test to find ale's own .git folder
+ function! ale#handlers#hdl_checker#IsDotGit(path) abort
+ let g:call_count += 1
+ return 0
+ endfunction
+
+ call ale#test#SetFilename('hdl_server/foo.vhd')
+
+ AssertEqual
+ \ '',
+ \ ale#handlers#hdl_checker#GetProjectRoot(bufnr(''))
+
+ AssertEqual g:call_count, 1
+
+ unlet! g:call_count
diff --git a/test/test_highlight_placement.vader b/test/test_highlight_placement.vader
index 3b259655..dab73073 100644
--- a/test/test_highlight_placement.vader
+++ b/test/test_highlight_placement.vader
@@ -7,6 +7,8 @@ Before:
Save g:ale_set_loclist
Save g:ale_set_quickfix
Save g:ale_set_signs
+ Save g:ale_exclude_highlights
+ Save b:ale_exclude_highlights
runtime autoload/ale/highlight.vim
@@ -20,6 +22,8 @@ Before:
let g:ale_set_quickfix = 0
let g:ale_set_loclist = 0
let g:ale_echo_cursor = 0
+ let g:ale_exclude_highlights = []
+ let b:ale_exclude_highlights = []
function! GenerateResults(buffer, output)
return [
@@ -363,6 +367,23 @@ Execute(Highlights should always be cleared when the buffer highlight list is em
\ GetMatchesWithoutIDs()
endif
+Execute(Highlights should be hidden when excluded):
+ let b:ale_exclude_highlights = ['ig.*ore', 'nope']
+
+ call ale#highlight#SetHighlights(bufnr('%'), [
+ \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 1, 'col': 1, 'text': 'hello'},
+ \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 2, 'col': 1, 'text': 'ignore'},
+ \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 1, 'text': 'nope'},
+ \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 4, 'col': 1, 'text': 'world'},
+ \])
+
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]},
+ \ {'group': 'ALEError', 'priority': 10, 'pos1': [4, 1, 1]},
+ \ ],
+ \ GetMatchesWithoutIDs()
+
Execute(Highlights should be cleared when ALE is disabled):
let g:ale_enabled = 1
call ale#highlight#SetHighlights(bufnr(''), [
diff --git a/test/test_hover.vader b/test/test_hover.vader
index 917694a2..8b4cf7bd 100644
--- a/test/test_hover.vader
+++ b/test/test_hover.vader
@@ -133,6 +133,12 @@ Execute(LSP hover responses with markup content should be handled):
AssertEqual ['markup'], g:echo_list
AssertEqual {}, ale#hover#GetMap()
+Execute(LSP hover responses with markup content missing values should be handled):
+ call HandleValidLSPResult({'contents': {'kind': 'something'}})
+
+ AssertEqual [], g:echo_list
+ AssertEqual {}, ale#hover#GetMap()
+
Execute(LSP hover response with lists of strings should be handled):
call HandleValidLSPResult({'contents': [
\ "foo\n",
@@ -145,6 +151,7 @@ Execute(LSP hover response with lists of strings should be handled):
Execute(LSP hover response with lists of strings and marked strings should be handled):
call HandleValidLSPResult({'contents': [
\ {'language': 'rust', 'value': 'foo'},
+ \ {'language': 'foobar'},
\ "bar\n",
\]})
diff --git a/test/test_organize_imports.vader b/test/test_organize_imports.vader
index 137326a9..c51ff1c0 100644
--- a/test/test_organize_imports.vader
+++ b/test/test_organize_imports.vader
@@ -57,8 +57,9 @@ Before:
call add(g:expr_list, a:expr)
endfunction
- function! ale#code_action#HandleCodeAction(code_action) abort
+ function! ale#code_action#HandleCodeAction(code_action, should_save) abort
let g:handle_code_action_called = 1
+ AssertEqual v:false, a:should_save
call add(g:code_actions, a:code_action)
endfunction
diff --git a/test/test_rename.vader b/test/test_rename.vader
index 98e3ef30..34d9e32e 100644
--- a/test/test_rename.vader
+++ b/test/test_rename.vader
@@ -57,8 +57,9 @@ Before:
call add(g:expr_list, a:expr)
endfunction
- function! ale#code_action#HandleCodeAction(code_action) abort
+ function! ale#code_action#HandleCodeAction(code_action, should_save) abort
let g:handle_code_action_called = 1
+ AssertEqual v:true, a:should_save
call add(g:code_actions, a:code_action)
endfunction
@@ -326,6 +327,115 @@ Execute(Code actions from LSP should be handled):
\ ],
\ g:code_actions
+Execute(DocumentChanges from LSP should be handled):
+ call ale#rename#HandleLSPResponse(1, {
+ \ 'id': 3,
+ \ 'result': {
+ \ 'documentChanges': [
+ \ {
+ \ 'textDocument': {
+ \ 'version': 1.0,
+ \ 'uri': 'file:///foo/bar/file1.ts',
+ \ },
+ \ 'edits': [
+ \ {
+ \ 'range': {
+ \ 'start': {
+ \ 'line': 1,
+ \ 'character': 2,
+ \ },
+ \ 'end': {
+ \ 'line': 3,
+ \ 'character': 4,
+ \ },
+ \ },
+ \ 'newText': 'bla123',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ },
+ \})
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'rename',
+ \ 'changes': [
+ \ {
+ \ 'fileName': '/foo/bar/file1.ts',
+ \ 'textChanges': [
+ \ {
+ \ 'start': {
+ \ 'line': 2,
+ \ 'offset': 3,
+ \ },
+ \ 'end': {
+ \ 'line': 4,
+ \ 'offset': 5,
+ \ },
+ \ 'newText': 'bla123',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ }
+ \ ],
+ \ g:code_actions
+
+Execute(Single DocumentChange from LSP should be handled):
+ call ale#rename#HandleLSPResponse(1, {
+ \ 'id': 3,
+ \ 'result': {
+ \ 'documentChanges': {
+ \ 'textDocument': {
+ \ 'version': 1.0,
+ \ 'uri': 'file:///foo/bar/file1.ts',
+ \ },
+ \ 'edits': [
+ \ {
+ \ 'range': {
+ \ 'start': {
+ \ 'line': 1,
+ \ 'character': 2,
+ \ },
+ \ 'end': {
+ \ 'line': 3,
+ \ 'character': 4,
+ \ },
+ \ },
+ \ 'newText': 'bla123',
+ \ },
+ \ ],
+ \ },
+ \ },
+ \})
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'rename',
+ \ 'changes': [
+ \ {
+ \ 'fileName': '/foo/bar/file1.ts',
+ \ 'textChanges': [
+ \ {
+ \ 'start': {
+ \ 'line': 2,
+ \ 'offset': 3,
+ \ },
+ \ 'end': {
+ \ 'line': 4,
+ \ 'offset': 5,
+ \ },
+ \ 'newText': 'bla123',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ }
+ \ ],
+ \ g:code_actions
Execute(LSP should perform no action when no result):
call ale#rename#HandleLSPResponse(1, {
\ 'id': 3,
diff --git a/test/test_shell_detection.vader b/test/test_shell_detection.vader
index 88ee462d..6452287f 100644
--- a/test/test_shell_detection.vader
+++ b/test/test_shell_detection.vader
@@ -15,7 +15,7 @@ Given(A file with a Bash hashbang):
Execute(/bin/bash should be detected appropriately):
AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with /bin/sh):
#!/usr/bin/env sh -eu --foobar
@@ -23,7 +23,7 @@ Given(A file with /bin/sh):
Execute(/bin/sh should be detected appropriately):
AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with bash as an argument to env):
#!/usr/bin/env bash
@@ -31,7 +31,7 @@ Given(A file with bash as an argument to env):
Execute(/usr/bin/env bash should be detected appropriately):
AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a tcsh hash bang and arguments):
#!/usr/bin/env tcsh -eu --foobar
@@ -39,7 +39,7 @@ Given(A file with a tcsh hash bang and arguments):
Execute(tcsh should be detected appropriately):
AssertEqual 'tcsh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'tcsh', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'tcsh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'tcsh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a zsh hash bang and arguments):
#!/usr/bin/env zsh -eu --foobar
@@ -47,7 +47,7 @@ Given(A file with a zsh hash bang and arguments):
Execute(zsh should be detected appropriately):
AssertEqual 'zsh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'zsh', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'zsh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'zsh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a csh hash bang and arguments):
#!/usr/bin/env csh -eu --foobar
@@ -55,7 +55,7 @@ Given(A file with a csh hash bang and arguments):
Execute(csh should be detected appropriately):
AssertEqual 'csh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'csh', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'csh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'csh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a ksh hashbang):
#!/bin/ksh
@@ -63,7 +63,7 @@ Given(A file with a ksh hashbang):
Execute(/bin/ksh should be detected appropriately):
AssertEqual 'ksh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'ksh', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a ksh as an argument to env):
#!/usr/bin/env ksh
@@ -71,7 +71,7 @@ Given(A file with a ksh as an argument to env):
Execute(ksh should be detected appropriately):
AssertEqual 'ksh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'ksh', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a sh hash bang and arguments):
#!/usr/bin/env sh -eu --foobar
@@ -79,24 +79,24 @@ Given(A file with a sh hash bang and arguments):
Execute(sh should be detected appropriately):
AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr(''))
- AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file without a hashbang):
Execute(The bash dialect should be used for shellcheck if b:is_bash is 1):
let b:is_bash = 1
- AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Execute(The sh dialect should be used for shellcheck if b:is_sh is 1):
let b:is_sh = 1
- AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Execute(The ksh dialect should be used for shellcheck if b:is_kornshell is 1):
let b:is_kornshell = 1
- AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with /bin/ash):
#!/bin/ash
@@ -106,7 +106,7 @@ Execute(The ash dialect should be used for the shell and the base function):
AssertEqual 'ash', ale_linters#sh#shell#GetExecutable(bufnr(''))
Execute(dash should be used for shellcheck, which has no ash dialect):
- AssertEqual 'dash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with /bin/dash):
#!/bin/dash
@@ -116,4 +116,4 @@ Execute(The dash dialect should be used for the shell and the base function):
AssertEqual 'dash', ale_linters#sh#shell#GetExecutable(bufnr(''))
Execute(dash should be used for shellcheck):
- AssertEqual 'dash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
+ AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))