Compare commits

...

171 Commits

Author SHA1 Message Date
w0rp
80ab12c7b6 Bump the ALE version 2019-06-10 23:53:42 +01:00
w0rp
ce91972c94 Fix #1727 - Replace previoulsy defined linters with matching names 2019-06-10 22:41:20 +01:00
w0rp
168768b326 Lint on InsertLeave, not in insert mode by default
b:ale_lint_on_insert_leave is now supported as tests need it.

These defaults are saner and cause fewer issues for users by default.
2019-06-10 20:54:38 +01:00
w0rp
8b46fa3ee7 Merge pull request #2567 from theevocater/add_reorder_python_imports
Add support for reorder-python-imports fixer
2019-06-10 19:33:00 +01:00
Thibault Vatter
22e7a6f6c2 Make rmarkdown files work with styler and lintr (#2564)
* add R markdown as filetype for styler
* Add rmarkdown as an alias for R
2019-06-10 19:27:42 +01:00
w0rp
1ba1a9ef0e Merge pull request #2558 from hsanson/fix-javalsp-command-callback
Fix javalsp command callback.
2019-06-10 19:15:15 +01:00
w0rp
fea666bd27 Move images to a GitHub issue 2019-06-10 13:43:53 +01:00
w0rp
730752523b Merge pull request #2574 from enterprisey/patch-1
In README, more efficient git clones
2019-06-10 13:33:54 +01:00
w0rp
d9bad6c0b8 Merge pull request #2568 from h-michael/fix-reasonml-doc
Remove unnecessary asterisk from doc/ale-reasonml
2019-06-10 09:06:43 +01:00
enterprisey
b41eecd31b In README, more efficient git clones
Users don't need the entire git history to use the plugin, so don't download it
2019-06-09 22:12:29 -07:00
Horacio Sanson
e84c9b300b Do not set default binary.
The default binary "launcher" is too generic and can get mixed with
other tools. To use this linter user must explicitly set the absolute
path of the launcher path.
2019-06-09 14:02:50 +09:00
Hirokazu Hata
efa95e2657 Remove unnecessary asterisk from doc/ale-reasonml 2019-06-09 12:08:10 +09:00
Jake Kaufman
56641e0230 Add support for reorder-python-imports fixer
isort is great, but I've come to prefer reorder-python-imports. The tool
has a focus on smaller diffs than isort. reorder-python-imports is also
a little smarter than isort which is nice.
2019-06-08 19:22:50 -04:00
w0rp
507f164a09 Document and test reason-language-server 2019-06-09 00:12:11 +01:00
David Buchan-Swanson
92d515c211 Add support for reason-language-server 2019-06-08 23:50:41 +01:00
w0rp
59829bc194 Merge pull request #2253 from jj-kim/master
Improve location list behavior on split windows of same buffer.
2019-06-08 23:25:02 +01:00
w0rp
d9931b9891 Merge pull request #2559 from nerdrew/rust-cargo-rendered-detail
show rendered cargo error in detail for clippy errors
2019-06-08 23:20:18 +01:00
w0rp
3aa58ca179 Merge pull request #2565 from Tharre/master
Run xml linters on xsd and xslt files
2019-06-08 23:09:09 +01:00
w0rp
5826b4927c Merge pull request #2551 from laino/eslint-json
Use JSON output for ESLint and fix tsserver column
2019-06-08 23:05:35 +01:00
w0rp
6eb68b4507 Merge pull request #2566 from grimmn/extend-clangtidy-options
Add additional options setting for clang-tidy linter
2019-06-08 22:45:39 +01:00
Jonathan Vander Mey
3c799abb44 Add additional option setting for clangtidy linter
The existing option setting handles setting additional compile flags to
pass to clang-tidy. The new option setting added here allows setting
additional clang-tidy specific flags to be passed as well.
Fixes #2324
2019-06-08 15:35:08 -04:00
Tharre
3b8fb39b4a Run xml linters on xsd and xslt files
Both xsd and xslt are by definition written in XML, and thus the same
linter(s) can be run to check them for well-formedness.
2019-06-06 23:46:43 +02:00
w0rp
7b78f2b846 Fix #2525 - Convert Windows paths in a Unix environment 2019-06-05 14:16:43 +01:00
Andrew Lazarus
e7317e05ea show rendered cargo error in detail 2019-06-04 22:20:57 -07:00
w0rp
381fff0e4c Make ale_lint_on_save work with b:ale_fix_on_save = 1 2019-06-04 21:51:53 +01:00
Horacio Sanson
5ce97f8cdb Fix javalsp command callback.
The command used to invoke the language server is missing some options
to include additional java modules. Without these modules the server
was not working properly.

The correct command can be found in a `launcher` script on the same
directory the `java` executable for the language server is found.

This commit changes the docs to prefer the launcher script over the java
executable. For backward compatibility it also fixes the command
invocation in case the java executable is configured.
2019-06-05 00:50:23 +09:00
w0rp
42a1fc2d29 Merge pull request #2557 from hy2k/update-doc
Change ALE integration with Deoplete in README
2019-06-04 16:18:43 +01:00
hy2k
bb7481effb Update README deoplete completion source section 2019-06-04 22:35:29 +09:00
Nils Kuhnhenn
7d4a83ecd4 Use correct handler for 'xo' linter 2019-06-04 13:14:08 +02:00
w0rp
eb6015c6fd #2542 - Improve checkstyle project configuration 2019-06-03 23:40:22 +01:00
w0rp
4496c9b3c1 Fix tests on Windows 2019-06-03 22:14:18 +01:00
Christoph Koehler
4129c356e8 Fix #1279 - Run cppcheck differently when modified
cppcheck is now run without the --project option and from the buffer's
directory instead when the buffer has been modified. Saving the buffer
will get results by linting the project instead.
2019-06-03 21:54:23 +01:00
Andrew Lee
c6a5cbb3c7 Feature/add ant support (#2539)
Use ant files to load Java settings too.
2019-06-03 20:30:18 +01:00
w0rp
a76f056bd9 Fix #2555 - Remove highlights in lowercase, etc 2019-06-03 20:16:49 +01:00
w0rp
a730a6d5d5 Update the license year 2019-06-03 09:19:11 +01:00
Nils Kuhnhenn
79d1b99067 Use JSON output for eslint and fix tsserver column 2019-06-02 14:39:03 +02:00
w0rp
135de34d22 Merge pull request #2549 from m-pilia/custom-lsp-requests
Add API for custom LSP requests
2019-06-01 16:48:04 +01:00
Martino Pilia
5542db1507 Support custom LSP notifications
Allow to send custom notification mesages, that expect no response from
the server.
2019-06-01 16:27:44 +02:00
Martino Pilia
3321685940 Refactor LSP custom request handling 2019-05-31 21:56:38 +02:00
Martino Pilia
7053d468cc Add API for custom LSP requests
Implement a function `ale#lsp_linter#SendRequest` that allows to send
custom LSP requests to an enabled LSP linter.

Resolves #2474
2019-05-31 17:58:27 +02:00
w0rp
27146ade32 Fix #2544 - Completion positions are off by one 2019-05-30 10:26:17 +01:00
w0rp
4f02edc3f8 Merge pull request #2529 from maxwell-k/terraform_linter
Add a terraform linter
2019-05-29 23:28:50 +01:00
w0rp
166435dbf1 #2533 - Run phpcs in the directory the file is in 2019-05-29 23:17:14 +01:00
w0rp
ca0cdd26fc Merge pull request #2540 from sijad/pgformatter
add pgformatter fixer
2019-05-29 21:26:01 +01:00
w0rp
6b819dd74a Merge pull request #2543 from hsanson/fix-checkstyle-handler
Fix java checkstyle handler.
2019-05-29 20:16:51 +01:00
w0rp
90b1ea230d Fix #2438 - Print a friendly message when the clipboard is not available 2019-05-28 20:27:10 +01:00
w0rp
67d7caee30 Fix #2535 - Automatically emit <C-x><C-o> less to prevent <C-o> issues 2019-05-28 20:03:35 +01:00
w0rp
bc0abc3b96 Merge pull request #2541 from jwkvam/neovim-bufline
fix neovim missing setbufline
2019-05-28 09:55:08 +01:00
Horacio Sanson
181bc69c8c Fix java checkstyle handler.
The checkstyle handler is capable of parsing the new and old output
formats. Unfortunately there are some particular output messages that
matched both the new and old regular expressions:

   [WARN] whatever:11:7: WhitespaceAround: ''if'' is not followed by whitespace. [WhitespaceAround]

This caused ALE to report extra errors since the message was being
matched twice, once as a warning and another (incorrect) old formatted
error.

This MR fixes this by stopping any parsing using the old format regexp
is any errors of the new format are correcly parsed. There is no reason
to expect checkstyle to output both styles in the same report.
2019-05-28 17:48:27 +09:00
Jacques Kvam
47ad24c221 fix neovim missing setbufline 2019-05-27 20:12:24 -07:00
Sajjad Hashemian
8d8b295ef5 add pgformatter 2019-05-27 09:00:11 +04:30
w0rp
bb08b81bf7 Merge pull request #2524 from hsanson/2521-fix-lsp-diagnostics-buffer-match
WIP Fix HandleLSPDiagnostics buffer match logic.
2019-05-24 01:21:02 +01:00
w0rp
36c35d840b Fix LSP tests 2019-05-24 01:13:52 +01:00
Keith Maxwell
88fa0b9294 Add a terraform linter
This linter uses the check functionality built into terraform. ALE
already has a fixer using `terraform fmt` but this doesn't provide error
messages. ALE already has a linter using `tflint` but this requires an
extra application to be installed.

For example this linter will give a warning that ! is an illegal
character in the line below:

    variable "example" !{}

This linter runs the buffer through the command below and parses the
output:

    terraform fmt -no-color -check=true -

This commit includes a basic implementation, documentation and tests.
The only option is to control which executable is run.

Tested with:

    $ terraform -version
    Terraform v0.11.13
2019-05-23 15:49:02 +01:00
w0rp
1a9b8a58c7 Merge pull request #2520 from hsanson/fix-eclipselsp-workspace-config
Fix eclipselsp workspace config
2019-05-23 12:05:21 +01:00
Horacio Sanson
33b4a90507 Add tests for LSP responses 2019-05-23 10:19:50 +09:00
Horacio Sanson
85b3a4a5c6 Add exact file match test to TSServer response handler 2019-05-23 10:19:07 +09:00
w0rp
092748caac Update the README to use travis-ci.com 2019-05-22 22:27:10 +01:00
Horacio Sanson
2f13c2d263 Add fix to HandleTSServerDiagnostics function. 2019-05-22 20:19:45 +09:00
Horacio Sanson
b41836130c Fix HandleLSPDiagnostics buffer match logic.
To find the buffer corresponding to URIs reported by LSP the
HandleLSPDiagnostics() method uses the built-in bufnr() function. From
the documentation we learn that the first parameter of bufnr() is
an expression, not a path.

EclipseLSP will report project wide errors (e.g. gradle errors) that are
not related to any actual source file with an URI that corresponds to the
project root folder, e.g:

   file:///home/username/Projects/gradle-simple

This URI will match any open buffer of files within the project root
hiearchy, thus project-wide errors appear as part of every file within
the project, e.g:

   file:///home/username/Projects/gradle-simple/src/main/java/Hello.java

To fix this, this MR adds '^' to the beginning and '$' at the end of the
URI path to force an exact match. This is how is recommended in vim
help (see :h bufname).
2019-05-22 10:30:24 +09:00
Horacio Sanson
5a8ba75265 Fix eclipse.jdt.ls workspace data path.
We were setting the -data parameter to the project root but this caused
the language server to fail initialization and synch of gradle
dependencies. As consequence ALE failed to work fully on gradle
projects.

This fix sets the workspace to the parent folder of the project root.
Normally this corresponds to the correct Eclipse workspace path.

When this is not the case, this fix also allows users to explicitly set
the absolute path to the workspace via configuration variable.
2019-05-22 09:23:03 +09:00
w0rp
67d49c75a8 Fix the eclipselsp tests 2019-05-21 21:23:21 +01:00
Grim Kriegor
0427ee84b4 Allow running eclipselsp as installed by system package on GNU/Linux (#2523)
* Search eclipselsp jar and config files within system package path
* Allow setting an alternate eclipselsp configuration directory
* Add test for ale_java_eclipselsp_config_path
2019-05-21 21:13:06 +01:00
w0rp
f6ae056d02 Stop a test from failing randomly 2019-05-21 14:01:58 +01:00
w0rp
3e3801e81e Revert "Fix #2492 - Remove all Deoplete support for now"
This reverts commit 975cc7af8f.
2019-05-21 13:53:09 +01:00
w0rp
89db85121c Merge pull request #2502 from ericvw/flake8-config
Change Python project root dir detection for flake8 configuration
2019-05-21 00:15:12 +01:00
w0rp
26e5948617 Close #2516 - Handle problems with inlined functions 2019-05-20 23:50:38 +01:00
w0rp
42f5e8c62c Fix a test on Windows 2019-05-20 22:11:49 +01:00
w0rp
28819eedd3 Close #2359 - Find compile_commands.json in build dirs for cppcheck 2019-05-20 22:08:03 +01:00
w0rp
937138dad4 Try to fix the tests 2019-05-20 20:06:44 +01:00
w0rp
143af2b9fd Fix #2421 - Use compile_commands.json in build dirs to find roots 2019-05-20 19:57:08 +01:00
w0rp
781bf1502f Make a test fail less 2019-05-20 19:27:47 +01:00
w0rp
5e64acc6ab Fix #2512 - Use -o /dev/null for gcc linting 2019-05-20 13:00:32 +01:00
w0rp
4ee28d3129 Fix #2515 - Send client capabilities to LSP servers 2019-05-20 09:40:06 +01:00
w0rp
9d908ecc66 Close #1739 - Use deletebufline() for fixing files were available 2019-05-20 02:06:25 +01:00
Antoine Gagné
3b7c86e401 Add support for Erlang dialyzer (#2509)
* Add support for Erlang dialyzer
* Add an option to specify rebar3 profile

In doing so, the use of the `**` wildcard becomes unnecessary.
2019-05-19 21:16:17 +01:00
Eric N. Vander Weele
57736cdccc Change Python project root dir detection for flake8 configuration
The official configuration files for `flake8` are `.flake8`, `tox.ini`,
and `setup.cfg`.

After investigation, it is safe to remove `flake8.cfg` as it appears to
only exist as a typo in other tooling documentation (e.g.,
`python-language-server`).

Even though no linters automatically read `.flake8rc`, it is kept in
case projects may be using it for detecting the projects root directory.
2019-05-19 09:51:26 -04:00
Eric N. Vander Weele
57b9d8bc0e Test for Python project root directory
Add test files and a new test suite for detecting a Python project's
root directory.
2019-05-19 09:51:26 -04:00
w0rp
652d991077 Fix #1317 - Jump to column 1 for problems at column 0 2019-05-17 22:08:03 +01:00
w0rp
e6745a3811 Fix #1989 - Use ESlint options for fixers too 2019-05-17 20:45:25 +01:00
w0rp
e5ea809094 Close #2285 - Add a function for use with omnifunc 2019-05-17 00:57:52 +01:00
w0rp
8cb6d043b4 Use the updated Docker image 2019-05-16 22:22:47 +01:00
w0rp
8c76b88392 Update the Dockerfile with newer Vim versions 2019-05-16 21:36:05 +01:00
w0rp
975cc7af8f Fix #2492 - Remove all Deoplete support for now 2019-05-16 20:11:42 +01:00
w0rp
d0f2a0ae94 Fix #2505 - Remove NeoVim highlight support for now 2019-05-16 20:04:18 +01:00
w0rp
9b89ec3d86 #2505 Try to fix NeoVim highlighting out of range errors 2019-05-16 13:44:40 +01:00
w0rp
4234d39d87 Close #908 - Report phpcs problems as style problems 2019-05-14 22:58:58 +01:00
w0rp
381fe1badf Close #829 - Close LSP documents when buffers are deleted 2019-05-14 00:21:58 +01:00
w0rp
07b596efb5 Close #791 - Handle exceptions for puglint 2019-05-13 21:57:44 +01:00
w0rp
70604828fa Merge pull request #2500 from rliang/texlab
[lsp] Add Texlab support
2019-05-13 20:17:35 +01:00
rliang
ab7e5b264f [linter] Add LSP support for LaTeX via texlab 2019-05-13 15:50:03 -03:00
w0rp
c88ebc5e70 Make phpstan tests fail less 2019-05-13 14:00:12 +01:00
w0rp
42cbff29f8 Fix #2497 - ALE should not lint on save when disabled after fixing 2019-05-13 13:44:29 +01:00
w0rp
bf17bbf898 Merge pull request #2496 from liskin/sort-locale
Force sort locale in check-supported-tools-tables
2019-05-13 09:11:55 +01:00
w0rp
aa047b5ba3 Merge pull request #2491 from mpesari/phpstan-autoload-option
Add phpstan autoload option
2019-05-12 21:32:57 +01:00
Mikko Pesari
6b919e88be Add test to verify phpstan autoload parameter 2019-05-12 23:12:52 +03:00
w0rp
bfc79bd2aa #2492 - Try to fix a deoplete bug again 2019-05-12 19:35:10 +01:00
Tomas Janousek
fb6fd80bd2 Force sort locale in check-supported-tools-tables
Otherwise it reports that the list isn't sorted properly if user's LANG
is different.
2019-05-12 18:49:20 +02:00
w0rp
7943bfab96 Make eslint respect the ale_warn_about_trailing_whitespace setting 2019-05-12 15:49:16 +01:00
w0rp
3303f596e5 Fix #2490 - Kill other processes when the test script is interrupted 2019-05-12 15:42:09 +01:00
w0rp
df90725c85 Support b:ale_completion_enabled for disabling it for some buffers 2019-05-11 17:19:45 +01:00
w0rp
edd3114394 Make it less likely people will do the wrong thing
Make it very clear in every single place that the setting for ALE's own
completion implementation is mentioned that you should not enable it if
you want to use ALE as a completion source for other plugins like
Deoplete.
2019-05-11 17:06:32 +01:00
w0rp
f0152bca98 #2492 - Try to fix a bug with ALE's deoplete source 2019-05-11 16:40:26 +01:00
Mikko Pesari
afa20d96ca Add phpstan autoload option 2019-05-10 18:28:32 +03:00
w0rp
79e42fed14 #2403 - Make ale_disable_lsp apply consistently, and document it better 2019-05-10 13:42:41 +01:00
Katsuya Horiuchi
f444abdfe6 Add option to show msg id when pylint is used (#2445)
* Add python_pylint_use_msg_id to tweak output of pylint
* Add test for ale_python_pylint_use_msg_id
* Add doc on ale_python_pylint_use_msg_id
2019-05-09 17:28:18 +01:00
w0rp
722c3e8dae #2481 - Use text to insert from insertText 2019-05-09 17:26:33 +01:00
w0rp
bff3d253e9 Merge pull request #2486 from Sh3Rm4n/doc-typo-fix
Fix typos in documentation
2019-05-09 17:01:46 +01:00
Sh3Rm4n
77c5802fc7 Fix typos in documentation 2019-05-09 13:49:44 +02:00
w0rp
a223253f35 Merge pull request #2134 from oaue/master
javac linter: fix handling of error messages containing ':' character
2019-05-08 09:50:12 +01:00
w0rp
d390abd721 Merge pull request #2479 from hsanson/288-fix-eclipse-jar-path-docs
Fix eclipselsp path documentation.
2019-05-08 09:17:57 +01:00
Horacio Sanson
53db52e713 Improve eclipselsp jar search logic.
- Set default value to $HOME/eclipse.jdt.ls
 - Make JAR search regexp more specific.
 - Allow to set the VSCode extensions folder as ale_java_eclipselsp_path.
2019-05-08 13:24:34 +09:00
Horacio Sanson
63abd2dfef Fix eclipselsp path documentation.
Closes #2468
2019-05-08 11:48:44 +09:00
w0rp
5f64f8dc57 Escape phpstan arguments, and update documentation 2019-05-07 19:38:38 +01:00
Kanenobu Mitsuru
c10da0e390 Add fixer for OCaml ocp-indent (#2436) 2019-05-07 18:50:26 +01:00
w0rp
548ee56f40 Merge pull request #2475 from andreypopp/andreypopp/fix-nvim-hl
Fix off by one error line highlight w/ nvim api
2019-05-07 10:47:20 +01:00
Andrey Popp
e6ba936a0c Fix off by one error line highlight w/ nvim api 2019-05-05 19:14:40 +03:00
Alvin Chan
7f0954b89e Add XO as a linter/fixer for TypeScript files (#2453) 2019-05-02 11:59:18 +01:00
Julien Deniau
c6aae3bcfc Better phpstan default configuration (#2444)
* Use phpstan config file as default whenever possible + report as error
2019-05-01 23:14:39 +01:00
w0rp
4c6f67a3d0 Merge pull request #2446 from fnichol/add-var-sh-shellcheck-change-directory
Add g:ale_sh_shellcheck_change_directory
2019-05-01 22:47:08 +01:00
w0rp
5d65f93033 Merge pull request #2437 from robertjlooby/add-floskell
Add floskell for Haskell formatting
2019-05-01 22:43:44 +01:00
w0rp
eae124e8ce Fix #2460 - Do not track when LSP linters are busy 2019-05-01 20:49:03 +01:00
Andrey Popp
114198e082 Optionally use neovim's api-highlights (#2169) 2019-05-01 19:35:15 +01:00
w0rp
2f3bce5a1d Merge pull request #2448 from reedriley/master
Add support for Vim's tagstack to ALEGoToDefinition
2019-04-29 20:55:45 +01:00
w0rp
b34274ab10 Merge pull request #2466 from alerque/patch-1
Include plugin description in local help line
2019-04-29 10:17:38 +01:00
Caleb Maclennan
69b7ec1c4c Include plugin description in local help line
The recommended format for _vim's internal help files_ is "<tag> <for vim version> <last change>", (see `:help help-writing` but this format is not parsed the same way for plugins. For plugins the recommended format includes a description of the plugin such as "<tag> <description>". See `:help write-local-help` for the different template.
2019-04-29 09:48:48 +03:00
w0rp
737ed31de5 Disable fsync for writefile() calls for performance 2019-04-26 20:17:33 +01:00
Reed Riley
46c743a247 Updated Vim version in Dockerfile and made UpdateTagStack clearer
The `settagstack` and `gettagstack` functions don't exist prior to Vim
8.1.0519.  And the function definition was unclear whether it intended
  to grab the *old* or the *new* file/line/col.
2019-04-24 09:58:13 -04:00
w0rp
01331266a8 Close #1753 - Implement minimum viable integration with Deoplete 2019-04-23 21:26:25 +01:00
Thibault Vatter
ce0b14979e Add a fixer for r based on the styler package (#2401)
* Add styler as a new fixer for R files
* Add to the list of supported tools
* Add documentation
2019-04-23 19:44:26 +01:00
w0rp
893ac34cca Fix #2452 - Strip trailing spaces off sign text automatically 2019-04-23 15:58:10 +01:00
Reed Riley
c36f3e78e4 Add support for Vim's tagstack to ALEGoToDefinition
fixes 1236
2019-04-19 23:10:55 -04:00
Fletcher Nichol
2303b05baa Add g:ale_sh_shellcheck_change_directory 2019-04-18 16:48:10 -06:00
w0rp
fcc2c3ba71 Fix #2415 - Mark tsserver and LSP linters inactive again 2019-04-17 18:12:50 +01:00
Ian Shipman
2eb68f6d23 #1791 Set the working directory for cabal and stack 2019-04-17 14:26:09 +01:00
w0rp
104980e40b Merge pull request #2443 from JulioJu/patch-1
Documentation: ale-java eclipselsp customization
2019-04-17 11:57:14 +01:00
Julio
5bbce34605 Documentation: ale-java eclipselsp customization
See also https://github.com/w0rp/ale/pull/2121
2019-04-17 11:49:35 +02:00
Jethro Shuwen Sun
9e95032b30 fix 2434: use text field instead of the detail field for virtualtext (#2441)
* use text field instead of the detail field for virtualtext

*  make the change simpler
2019-04-16 14:40:39 +01:00
w0rp
59f8c35a2f Fix #1930 - Finish ale_fix_on_save_ignore
* Implementation had a bug
* Documentation added
* Tests added
2019-04-16 13:44:43 +01:00
w0rp
24d277384c #1930 - Add ale_fix_on_save_ignore for disabling some fixers on save 2019-04-15 23:15:18 +01:00
w0rp
3a010f68b8 Adjust the README wording slightly 2019-04-15 22:00:57 +01:00
w0rp
23a8208498 #782 - Use compile commands for matching source files for headers 2019-04-15 21:38:11 +01:00
Jethro Shuwen Sun
7f31065fce improve the lsp diagnostic message format (#2425) 2019-04-15 14:36:18 +01:00
w0rp
61c1ddd904 Fix #2440 - Fix the kotlinc command when Maven and Gradle are missing 2019-04-15 13:36:03 +01:00
Rob Looby
99361b2ca9 Add floskell for Haskell formatting 2019-04-14 11:27:48 -05:00
Riley Martine
495bce32e9 Add support for latexindent (#2387) 2019-04-13 13:21:59 +01:00
w0rp
f0f0cc3c18 Merge pull request #2121 from hsanson/1996-add-support-for-eclipse-jdt-ls
WIP Fix 1996 - Add eclipse LSP support.
2019-04-13 12:48:20 +01:00
w0rp
784d1a9a62 Merge pull request #2394 from harttle/master
feat: fecs support for js/html/css lint and format
2019-04-13 12:35:52 +01:00
w0rp
6428162f79 Merge pull request #2433 from belka-ew/bugfix/remove-otherproject-util-double
Remove otherproject#util#Double from d.vim
2019-04-13 12:29:31 +01:00
Jesse Harris
2ed53108c4 Linter for powershell syntax errors (#2413)
* Linter for powershell syntax errors
2019-04-13 12:24:56 +01:00
Eugen Wissner
751838621a Remove otherproject#util#Double from d.vim 2019-04-13 07:59:01 +02:00
w0rp
d7395906ba Merge pull request #2432 from superobertking/master
Let rust rls linter find the default rust toolchain automatically
2019-04-11 17:13:52 +01:00
robertking
fb7099d440 modify rls testcase 2019-04-11 23:38:16 +08:00
robertking
df806c511c change default value of ale_rust_rls_toolchain and update documentation 2019-04-11 23:05:59 +08:00
harttle
4b6691f602 test: unit test for fecs fixer, fecs command 2019-04-11 19:47:31 +08:00
Jun Yang
d4841cedf2 style: fecs related doc and vim scripts 2019-04-11 16:24:59 +08:00
harttle
c820089c44 feat: fecs support for js/html/css lint and format
`fecs` is a lint tool for HTML/CSS/JavaScript,
see http://fecs.baidu.com for more options.
2019-04-11 16:24:58 +08:00
Horacio Sanson
f02e2ec54c Fix 1996 - Add eclipse LSP support. 2019-04-11 08:50:04 +09:00
Masashi Iizuka
4813165614 Add a linter for clojure using clj-kondo (#2377) 2019-04-10 20:59:58 +01:00
w0rp
16b43a5708 Do not complain about generated _callback settings 2019-04-10 19:53:11 +01:00
w0rp
2ef3f9806c #2428 Remove deprecated linter options for psscriptanalyzer 2019-04-10 19:44:57 +01:00
w0rp
2e8c8085a6 Close #2179 - Add support for gopls 2019-04-10 19:23:16 +01:00
w0rp
042b351b7a Merge pull request #2366 from aweis/fixtypo
ruby: fix a typo in a comment
2019-04-10 18:54:43 +01:00
Raphael Hoegger
81423701b0 Adding new linter "cookstyle" for chef recipes (Issue #1187) (#2362) 2019-04-10 18:52:52 +01:00
Dan Loman
abcefe7a6e [doc] Add swift support documentation (#2426)
* [doc] Add swift support documentation
* [doc] Add swift bullets in main help file
* [doc] Add to supported languages and tools txt file as well
* Ensure same name styling for help/readme files
2019-04-08 18:22:59 +01:00
Dan Loman
864d0861e4 [lsp] Add Swift / SourceKit-LSP support (#2420)
* [linter] Add LSP support for Swift via sourcekit-lsp
2019-04-08 16:25:30 +01:00
w0rp
9a0ece1ecb Fix #2399 - Do not check buffers used for displaying diffs 2019-04-08 13:42:09 +01:00
w0rp
6d14dc0ac0 #2417 - Silence errors for shortmess+=T 2019-04-08 11:41:23 +01:00
Adam Weis
1427a090df ruby: fix a typo in a comment 2019-03-15 16:18:57 -07:00
Jason Kim
8b0879212f Improve location list behavior on split windows of same buffer. 2019-01-16 17:15:47 -08:00
David LANDREAU
c7292ce892 javac linter: fix handling of error messages containing ':' character 2018-12-09 18:22:50 +01:00
250 changed files with 6534 additions and 875 deletions

2
.gitignore vendored
View File

@@ -3,6 +3,8 @@
# Ignore all hidden files everywhere.
# Use `git add -f` to add hidden files.
.*
__pycache__
*.pyc
/doc/tags
/init.vim
/test/ale-info-test-file

View File

@@ -1,9 +1,9 @@
FROM tweekmonster/vim-testbed:latest
RUN install_vim -tag v8.0.0027 -build \
-tag v8.1.0204 -build \
-tag v8.1.0519 -build \
-tag neovim:v0.2.0 -build \
-tag neovim:v0.3.0 -build
-tag neovim:v0.3.5 -build
ENV PACKAGES="\
bash \

View File

@@ -1,4 +1,4 @@
Copyright (c) 2016-2018, w0rp <devw0rp@gmail.com>
Copyright (c) 2016-2019, w0rp <devw0rp@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -1,13 +1,13 @@
# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) [![Join the chat at https://gitter.im/vim-ale/Lobby](https://badges.gitter.im/vim-ale/Lobby.svg)](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.com/w0rp/ale.svg?branch=master)](https://travis-ci.com/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) [![Join the chat at https://gitter.im/vim-ale/Lobby](https://badges.gitter.im/vim-ale/Lobby.svg)](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true)
![ALE Logo by Mark Grealish - https://www.bhalash.com/](https://user-images.githubusercontent.com/3518142/59195920-2c339500-8b85-11e9-9c22-f6b7f69637b8.jpg)
ALE (Asynchronous Lint Engine) is a plugin for providing linting (checking
syntax and semantics) in NeoVim 0.2.0+ and Vim 8 while you edit your text files,
ALE (Asynchronous Lint Engine) is a plugin providing linting (syntax checking
and semantic errors) in NeoVim 0.2.0+ and Vim 8 while you edit your text files,
and acts as a Vim [Language Server Protocol](https://langserver.org/) client.
<img src="img/example.gif?raw=true" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim.">
<img src="https://user-images.githubusercontent.com/3518142/59195938-3a81b100-8b85-11e9-8e8d-6a601b1db908.gif" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim.">
ALE makes use of NeoVim and Vim 8 job control functions and timers to
run linters on the contents of text buffers and return errors as
@@ -26,7 +26,7 @@ features, including:
* Diagnostics (via Language Server Protocol linters)
* Go To Definition (`:ALEGoToDefinition`)
* Completion (`let g:ale_completion_enabled = 1` before ALE is loaded)
* Completion (Built in completion support, or with Deoplete)
* Finding references (`:ALEFindReferences`)
* Hover information (`:ALEHover`)
* Symbol search (`:ALESymbolSearch`)
@@ -159,12 +159,36 @@ ALE offers some support for completion via hijacking of omnicompletion while you
type. All of ALE's completion information must come from Language Server
Protocol linters, or from `tsserver` for TypeScript.
ALE integrates with [Deoplete](https://github.com/Shougo/deoplete.nvim) as a
completion source, named `'ale'`. You can configure Deoplete to only use ALE as
the source of completion information, or mix it with other sources.
```vim
" Use ALE and also some plugin 'foobar' as completion sources for all code.
call deoplete#custom#option('sources', {
\ '_': ['ale', 'foobar'],
\})
```
ALE also offers its own automatic completion support, which does not require any
other plugins, and can be enabled by changing a setting before ALE is loaded.
```vim
" Enable completion where available.
" This setting must be set before ALE is loaded.
"
" You should not turn this setting on if you wish to use ALE as a completion
" source for other completion plugins, like Deoplete.
let g:ale_completion_enabled = 1
```
ALE provides an omni-completion function you can use for triggering
completion manually with `<C-x><C-o>`.
```vim
set omnifunc=ale#completion#OmniFunc
```
See `:help ale-completion` for more information.
<a name="usage-go-to-definition"></a>
@@ -234,14 +258,14 @@ any other tools. Simply clone the plugin into your `pack` directory.
```bash
mkdir -p ~/.vim/pack/git-plugins/start
git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale
git clone --depth 1 https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale
```
#### NeoVim on Unix
```bash
mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start
git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
git clone --depth 1 https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
```
#### Vim 8 on Windows
@@ -249,7 +273,7 @@ git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plug
```bash
# Run these commands in the "Git for Windows" Bash terminal
mkdir -p ~/vimfiles/pack/git-plugins/start
git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale
git clone --depth 1 https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale
```
#### Generating Vim help files
@@ -517,7 +541,7 @@ let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
Will give you:
![Echoed message](img/echo.png)
![Echoed message](https://user-images.githubusercontent.com/3518142/59195927-348bd000-8b85-11e9-88b6-508a094f1548.png)
See `:help g:ale_echo_msg_format` for more information.
@@ -698,11 +722,10 @@ 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. Set `g:ale_lint_on_text_changed` to `never` or `normal`. 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.
If you don't wish to run linters while you type, you can disable that behaviour.
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.
If you are still concerned, you can turn the automatic linting off altogether,
including the option `g:ale_lint_on_enter`, and you can run ALE manually with

View File

@@ -5,7 +5,10 @@ call ale#Set('asm_gcc_executable', 'gcc')
call ale#Set('asm_gcc_options', '-Wall')
function! ale_linters#asm#gcc#GetCommand(buffer) abort
return '%e -x assembler -fsyntax-only '
" `-o /dev/null` or `-o null` is needed to catch all errors,
" -fsyntax-only doesn't catch everything.
return '%e -x assembler'
\ . ' -o ' . g:ale#util#nul_file
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
endfunction

View File

@@ -4,12 +4,6 @@
call ale#Set('c_clangd_executable', 'clangd')
call ale#Set('c_clangd_options', '')
function! ale_linters#c#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#c#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
endfunction
@@ -19,5 +13,5 @@ call ale#linter#Define('c', {
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'c_clangd_executable')},
\ 'command': function('ale_linters#c#clangd#GetCommand'),
\ 'project_root': function('ale_linters#c#clangd#GetProjectRoot'),
\ 'project_root': function('ale#c#FindProjectRoot'),
\})

View File

@@ -11,9 +11,12 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy')
" http://clang.llvm.org/extra/clang-tidy/checks/list.html
call ale#Set('c_clangtidy_checks', [])
" Set this option to manually set some options for clang-tidy.
" Set this option to manually set some options for clang-tidy to use as compile
" flags.
" This will disable compile_commands.json detection.
call ale#Set('c_clangtidy_options', '')
" Set this option to manually set options for clang-tidy directly.
call ale#Set('c_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
@@ -25,8 +28,12 @@ function! ale_linters#c#clangtidy#GetCommand(buffer) abort
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
\ : ''
" Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
return '%e'
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
\ . ' %s'
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . (!empty(l:options) ? ' -- ' . l:options : '')

View File

@@ -5,23 +5,17 @@ call ale#Set('c_cppcheck_executable', 'cppcheck')
call ale#Set('c_cppcheck_options', '--enable=style')
function! ale_linters#c#cppcheck#GetCommand(buffer) abort
" Search upwards from the file for compile_commands.json.
"
" If we find it, we'll `cd` to where the compile_commands.json file is,
" then use the file to set up import paths, etc.
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
let l:cd_command = !empty(l:compile_commmands_path)
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
\ : ''
let l:compile_commands_option = !empty(l:compile_commmands_path)
\ ? '--project=compile_commands.json '
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
let l:buffer_path_include = empty(l:compile_commands_option)
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : ''
return l:cd_command
\ . '%e -q --language=c '
\ . l:compile_commands_option
\ . ale#Var(a:buffer, 'c_cppcheck_options')
\ . '%e -q --language=c'
\ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options'))
\ . l:buffer_path_include
\ . ' %t'
endfunction

View File

@@ -5,13 +5,15 @@ call ale#Set('c_cquery_executable', 'cquery')
call ale#Set('c_cquery_cache_directory', expand('~/.cache/cquery'))
function! ale_linters#c#cquery#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
" Try to find cquery configuration files first.
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
if empty(l:project_root)
let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
if !empty(l:config)
return fnamemodify(l:config, ':h')
endif
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
" Fall back on default project root detection.
return ale#c#FindProjectRoot(a:buffer)
endfunction
function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort

View File

@@ -9,7 +9,11 @@ function! ale_linters#c#gcc#GetCommand(buffer, output) abort
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return '%e -S -x c -fsyntax-only'
"
" `-o /dev/null` or `-o null` is needed to catch all errors,
" -fsyntax-only doesn't catch everything.
return '%e -S -x c'
\ . ' -o ' . g:ale#util#nul_file
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(l:cflags)
\ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -'

View File

@@ -0,0 +1,54 @@
" Author: Raphael Hoegger - https://github.com/pfuender
" Description: Cookstyle (RuboCop based), a code style analyzer for Ruby files
call ale#Set('chef_cookstyle_executable', 'cookstyle')
call ale#Set('chef_cookstyle_options', '')
function! ale_linters#chef#cookstyle#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'chef_cookstyle_options')
return '%e' . ale#Pad(escape(l:options, '~')) . ' --force-exclusion --format json --stdin ' . ' %s'
endfunction
function! ale_linters#chef#cookstyle#Handle(buffer, lines) abort
if len(a:lines) == 0
return []
endif
let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], {})
if !has_key(l:errors, 'summary')
\|| l:errors['summary']['offense_count'] == 0
\|| empty(l:errors['files'])
return []
endif
let l:output = []
for l:error in l:errors['files'][0]['offenses']
let l:start_col = str2nr(l:error['location']['start_column'])
let l:end_col = str2nr(l:error['location']['last_column'])
if !l:end_col
let l:end_col = l:start_col + 1
endif
call add(l:output, {
\ 'lnum': str2nr(l:error['location']['line']),
\ 'col': l:start_col,
\ 'end_col': l:end_col,
\ 'code': l:error['cop_name'],
\ 'text': l:error['message'],
\ 'type': l:error['severity'] is? 'convention' ? 'W' : 'E',
\})
endfor
return l:output
endfunction
call ale#linter#Define('chef', {
\ 'name': 'cookstyle',
\ 'executable': {b -> ale#Var(b, 'chef_cookstyle_executable')},
\ 'command': function('ale_linters#chef#cookstyle#GetCommand'),
\ 'callback': 'ale_linters#chef#cookstyle#Handle',
\})

View File

@@ -0,0 +1,34 @@
" Author: Masashi Iizuka <liquidz.uo@gmail.com>
" Description: linter for clojure using clj-kondo https://github.com/borkdude/clj-kondo
function! ale_linters#clojure#clj_kondo#HandleCljKondoFormat(buffer, lines) abort
" output format
" <filename>:<line>:<column>: <issue type>: <message>
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+):? ((Exception|error|warning): ?(.+))$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:type = 'E'
if l:match[4] is? 'warning'
let l:type = 'W'
endif
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'type': l:type,
\})
endfor
return l:output
endfunction
call ale#linter#Define('clojure', {
\ 'name': 'clj-kondo',
\ 'output_stream': 'stdout',
\ 'executable': 'clj-kondo',
\ 'command': 'clj-kondo --lint %t',
\ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat',
\})

View File

@@ -12,7 +12,8 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
if empty(l:build_dir)
let l:build_dir = ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
let l:build_dir = ale#path#Dirname(l:json_file)
endif
" The extra arguments in the command are used to prevent .plist files from

View File

@@ -4,12 +4,6 @@
call ale#Set('cpp_clangd_executable', 'clangd')
call ale#Set('cpp_clangd_options', '')
function! ale_linters#cpp#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#cpp#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
endfunction
@@ -19,5 +13,5 @@ call ale#linter#Define('cpp', {
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')},
\ 'command': function('ale_linters#cpp#clangd#GetCommand'),
\ 'project_root': function('ale_linters#cpp#clangd#GetProjectRoot'),
\ 'project_root': function('ale#c#FindProjectRoot'),
\})

View File

@@ -5,9 +5,12 @@
call ale#Set('cpp_clangtidy_executable', 'clang-tidy')
" Set this option to check the checks clang-tidy will apply.
call ale#Set('cpp_clangtidy_checks', [])
" Set this option to manually set some options for clang-tidy.
" Set this option to manually set some options for clang-tidy to use as compile
" flags.
" This will disable compile_commands.json detection.
call ale#Set('cpp_clangtidy_options', '')
" Set this option to manually set options for clang-tidy directly.
call ale#Set('cpp_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
@@ -19,8 +22,12 @@ function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
\ : ''
" Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
return '%e'
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
\ . ' %s'
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . (!empty(l:options) ? ' -- ' . l:options : '')

View File

@@ -5,23 +5,17 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck')
call ale#Set('cpp_cppcheck_options', '--enable=style')
function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
" Search upwards from the file for compile_commands.json.
"
" If we find it, we'll `cd` to where the compile_commands.json file is,
" then use the file to set up import paths, etc.
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
let l:cd_command = !empty(l:compile_commmands_path)
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
\ : ''
let l:compile_commands_option = !empty(l:compile_commmands_path)
\ ? '--project=compile_commands.json '
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
let l:buffer_path_include = empty(l:compile_commands_option)
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : ''
return l:cd_command
\ . '%e -q --language=c++ '
\ . l:compile_commands_option
\ . ale#Var(a:buffer, 'cpp_cppcheck_options')
\ . '%e -q --language=c++'
\ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options'))
\ . l:buffer_path_include
\ . ' %t'
endfunction

View File

@@ -5,13 +5,15 @@ call ale#Set('cpp_cquery_executable', 'cquery')
call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery'))
function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
" Try to find cquery configuration files first.
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
if empty(l:project_root)
let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
if !empty(l:config)
return fnamemodify(l:config, ':h')
endif
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
" Fall back on default project root detection.
return ale#c#FindProjectRoot(a:buffer)
endfunction
function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort

View File

@@ -9,7 +9,11 @@ function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return '%e -S -x c++ -fsyntax-only'
"
" `-o /dev/null` or `-o null` is needed to catch all errors,
" -fsyntax-only doesn't catch everything.
return '%e -S -x c++'
\ . ' -o ' . g:ale#util#nul_file
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(l:cflags)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -'

9
ale_linters/css/fecs.vim Normal file
View File

@@ -0,0 +1,9 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for CSS files
call ale#linter#Define('css', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View File

@@ -0,0 +1,93 @@
" Author: Autoine Gagne - https://github.com/AntoineGagne
" Description: Define a checker that runs dialyzer on Erlang files.
let g:ale_erlang_dialyzer_executable =
\ get(g:, 'ale_erlang_dialyzer_executable', 'dialyzer')
let g:ale_erlang_dialyzer_plt_file =
\ get(g:, 'ale_erlang_dialyzer_plt_file', '')
let g:ale_erlang_dialyzer_rebar3_profile =
\ get(g:, 'ale_erlang_dialyzer_rebar3_profile', 'default')
function! ale_linters#erlang#dialyzer#GetRebar3Profile(buffer) abort
return ale#Var(a:buffer, 'erlang_dialyzer_rebar3_profile')
endfunction
function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort
let l:plt_file = ''
let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer)
let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile)
if !empty(l:plt_file_directory)
let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n')
endif
if !empty(l:plt_file)
return l:plt_file[0]
endif
if !empty($REBAR_PLT_DIR)
return expand('$REBAR_PLT_DIR/dialyzer/plt')
endif
return expand('$HOME/.dialyzer_plt')
endfunction
function! ale_linters#erlang#dialyzer#GetPlt(buffer) abort
let l:plt_file = ale#Var(a:buffer, 'erlang_dialyzer_plt_file')
if !empty(l:plt_file)
return l:plt_file
endif
return ale_linters#erlang#dialyzer#FindPlt(a:buffer)
endfunction
function! ale_linters#erlang#dialyzer#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'erlang_dialyzer_executable')
endfunction
function! ale_linters#erlang#dialyzer#GetCommand(buffer) abort
let l:command = ale#Escape(ale_linters#erlang#dialyzer#GetExecutable(a:buffer))
\ . ' -n'
\ . ' --plt ' . ale#Escape(ale_linters#erlang#dialyzer#GetPlt(a:buffer))
\ . ' -Wunmatched_returns'
\ . ' -Werror_handling'
\ . ' -Wrace_conditions'
\ . ' -Wunderspecs'
\ . ' %s'
return l:command
endfunction
function! ale_linters#erlang#dialyzer#Handle(buffer, lines) abort
" Match patterns like the following:
"
" erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available
let l:pattern = '^\S\+:\(\d\+\): \(.\+\)$'
let l:output = []
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) != 0
let l:code = l:match[2]
call add(l:output, {
\ 'lnum': str2nr(l:match[1]),
\ 'lcol': 0,
\ 'text': l:code,
\ 'type': 'W'
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('erlang', {
\ 'name': 'dialyzer',
\ 'executable': function('ale_linters#erlang#dialyzer#GetExecutable'),
\ 'command': function('ale_linters#erlang#dialyzer#GetCommand'),
\ 'callback': function('ale_linters#erlang#dialyzer#Handle'),
\ 'lint_file': 1
\})

30
ale_linters/go/gopls.vim Normal file
View File

@@ -0,0 +1,30 @@
" Author: w0rp <devw0rp@gmail.com>
" Author: Jerko Steiner <https://github.com/jeremija>
" Description: https://github.com/saibing/gopls
call ale#Set('go_gopls_executable', 'gopls')
call ale#Set('go_gopls_options', '--mode stdio')
function! ale_linters#go#gopls#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
endfunction
function! ale_linters#go#gopls#FindProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
let l:mods = ':h'
if empty(l:project_root)
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
let l:mods = ':h:h'
endif
return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : ''
endfunction
call ale#linter#Define('go', {
\ 'name': 'gopls',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'go_gopls_executable')},
\ 'command': function('ale_linters#go#gopls#GetCommand'),
\ 'project_root': function('ale_linters#go#gopls#FindProjectRoot'),
\})

View File

@@ -4,7 +4,8 @@
call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0')
function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort
return 'cabal exec -- ghc '
return ale#path#BufferCdString(a:buffer)
\ . 'cabal exec -- ghc '
\ . ale#Var(a:buffer, 'haskell_cabal_ghc_options')
\ . ' %t'
endfunction

View File

@@ -4,7 +4,8 @@
call ale#Set('haskell_stack_ghc_options', '-fno-code -v0')
function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort
return ale#handlers#haskell#GetStackExecutable(a:buffer)
return ale#path#BufferCdString(a:buffer)
\ . ale#handlers#haskell#GetStackExecutable(a:buffer)
\ . ' ghc -- '
\ . ale#Var(a:buffer, 'haskell_stack_ghc_options')
\ . ' %t'

View File

@@ -0,0 +1,9 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for HTMl files
call ale#linter#Define('html', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View File

@@ -1,6 +1,10 @@
" Author: Devon Meunier <devon.meunier@gmail.com>
" Description: checkstyle for Java files
call ale#Set('java_checkstyle_executable', 'checkstyle')
call ale#Set('java_checkstyle_config', 'google_checks.xml')
call ale#Set('java_checkstyle_options', '')
function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
let l:output = []
@@ -17,6 +21,10 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
\})
endfor
if !empty(l:output)
return l:output
endif
" old checkstyle versions
let l:pattern = '\v(.+):(\d+): ([^:]+): (.+)$'
@@ -32,18 +40,21 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
endfunction
function! ale_linters#java#checkstyle#GetCommand(buffer) abort
return 'checkstyle '
\ . ale#Var(a:buffer, 'java_checkstyle_options')
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)
\ ? ale#path#FindNearestFile(a:buffer, l:config_option)
\ : ''
return '%e'
\ . ale#Pad(l:options)
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
\ . ' %s'
endfunction
if !exists('g:ale_java_checkstyle_options')
let g:ale_java_checkstyle_options = '-c /google_checks.xml'
endif
call ale#linter#Define('java', {
\ 'name': 'checkstyle',
\ 'executable': 'checkstyle',
\ 'executable': {b -> ale#Var(b, 'java_checkstyle_executable')},
\ 'command': function('ale_linters#java#checkstyle#GetCommand'),
\ 'callback': 'ale_linters#java#checkstyle#Handle',
\ 'lint_file': 1,

View File

@@ -0,0 +1,161 @@
" Author: Horacio Sanson <https://github.com/hsanson>
" Description: Support for the Eclipse language server https://github.com/eclipse/eclipse.jdt.ls
let s:version_cache = {}
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')
function! ale_linters#java#eclipselsp#Executable(buffer) abort
return ale#Var(a:buffer, 'java_eclipselsp_executable')
endfunction
function! ale_linters#java#eclipselsp#TargetPath(buffer) abort
return ale#Var(a:buffer, 'java_eclipselsp_path')
endfunction
function! ale_linters#java#eclipselsp#JarPath(buffer) abort
let l:path = ale_linters#java#eclipselsp#TargetPath(a:buffer)
" 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)
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)
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
return l:files[0]
endif
return ''
endfunction
function! ale_linters#java#eclipselsp#ConfigurationPath(buffer) abort
let l:path = fnamemodify(ale_linters#java#eclipselsp#JarPath(a:buffer), ':p:h:h')
let l:config_path = ale#Var(a:buffer, 'java_eclipselsp_config_path')
if !empty(l:config_path)
return ale#path#Simplify(l:config_path)
endif
if has('win32')
let l:path = l:path . '/config_win'
elseif has('macunix')
let l:path = l:path . '/config_mac'
else
let l:path = l:path . '/config_linux'
endif
return ale#path#Simplify(l:path)
endfunction
function! ale_linters#java#eclipselsp#VersionCheck(version_lines) abort
return s:GetVersion('', a:version_lines)
endfunction
function! s:GetVersion(executable, version_lines) abort
let l:version = []
for l:line in a:version_lines
let l:match = matchlist(l:line, '\(\d\+\)\.\(\d\+\)\.\(\d\+\)')
if !empty(l:match)
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[3] + 0]
let s:version_cache[a:executable] = l:version
break
endif
endfor
return l:version
endfunction
function! ale_linters#java#eclipselsp#CommandWithVersion(buffer, version_lines, meta) abort
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
let l:version = s:GetVersion(l:executable, a:version_lines)
return ale_linters#java#eclipselsp#Command(a:buffer, l:version)
endfunction
function! ale_linters#java#eclipselsp#WorkspacePath(buffer) abort
let l:wspath = ale#Var(a:buffer, 'java_eclipselsp_workspace_path')
if !empty(l:wspath)
return l:wspath
endif
return ale#path#Dirname(ale#java#FindProjectRoot(a:buffer))
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),
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
\ '-Dlog.level=ALL',
\ '-noverify',
\ '-Xmx1G',
\ '-jar',
\ ale#Escape(ale_linters#java#eclipselsp#JarPath(a:buffer)),
\ '-configuration',
\ ale#Escape(ale_linters#java#eclipselsp#ConfigurationPath(a:buffer)),
\ '-data',
\ ale#Escape(ale_linters#java#eclipselsp#WorkspacePath(a:buffer))
\ ]
if ale#semver#GTE(a:version, [1, 9])
call add(l:cmd, '--add-modules=ALL-SYSTEM')
call add(l:cmd, '--add-opens java.base/java.util=ALL-UNNAMED')
call add(l:cmd, '--add-opens java.base/java.lang=ALL-UNNAMED')
endif
return join(l:cmd, ' ')
endfunction
function! ale_linters#java#eclipselsp#RunWithVersionCheck(buffer) abort
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
if empty(l:executable)
return ''
endif
let l:cache = s:version_cache
if has_key(s:version_cache, l:executable)
return ale_linters#java#eclipselsp#Command(a:buffer, s:version_cache[l:executable])
endif
let l:command = ale#Escape(l:executable) . ' -version'
return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#java#eclipselsp#CommandWithVersion')
\)
endfunction
call ale#linter#Define('java', {
\ 'name': 'eclipselsp',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#java#eclipselsp#Executable'),
\ 'command': function('ale_linters#java#eclipselsp#RunWithVersionCheck'),
\ 'language': 'java',
\ 'project_root': function('ale#java#FindProjectRoot'),
\})

View File

@@ -21,6 +21,11 @@ function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
endif
" Try to use Ant if Gradle and Maven aren't available
if empty(l:command)
let l:command = ale#ant#BuildClasspathCommand(a:buffer)
endif
if empty(l:command)
return ale_linters#java#javac#GetCommand(a:buffer, [], {})
endif
@@ -99,7 +104,7 @@ function! ale_linters#java#javac#Handle(buffer, lines) abort
" Main.java:13: warning: [deprecation] donaught() in Testclass has been deprecated
" Main.java:16: error: ';' expected
let l:directory = expand('#' . a:buffer . ':p:h')
let l:pattern = '\v^(.*):(\d+): (.+):(.+)$'
let l:pattern = '\v^(.*):(\d+): (.{-1,}):(.+)$'
let l:col_pattern = '\v^(\s*\^)$'
let l:symbol_pattern = '\v^ +symbol: *(class|method) +([^ ]+)'
let l:output = []

View File

@@ -1,7 +1,7 @@
" Author: Horacio Sanson <https://github.com/hsanson>
" Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac
call ale#Set('java_javalsp_executable', 'java')
call ale#Set('java_javalsp_executable', '')
function! ale_linters#java#javalsp#Executable(buffer) abort
return ale#Var(a:buffer, 'java_javalsp_executable')
@@ -10,7 +10,25 @@ endfunction
function! ale_linters#java#javalsp#Command(buffer) abort
let l:executable = ale_linters#java#javalsp#Executable(a:buffer)
return ale#Escape(l:executable) . ' -Xverify:none -m javacs/org.javacs.Main'
if fnamemodify(l:executable, ':t') is# 'java'
" For backward compatibility.
let l:cmd = [
\ ale#Escape(l:executable),
\ '--add-exports jdk.compiler/com.sun.tools.javac.api=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.code=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.comp=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.main=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.tree=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.model=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.util=javacs',
\ '--add-opens jdk.compiler/com.sun.tools.javac.api=javacs',
\ '-m javacs/org.javacs.Main',
\]
return join(l:cmd, ' ')
else
return ale#Escape(l:executable)
endif
endfunction
call ale#linter#Define('java', {

View File

@@ -6,5 +6,5 @@ call ale#linter#Define('javascript', {
\ 'output_stream': 'both',
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'command': function('ale#handlers#eslint#GetCommand'),
\ 'callback': 'ale#handlers#eslint#Handle',
\ 'callback': 'ale#handlers#eslint#HandleJSON',
\})

View File

@@ -0,0 +1,10 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for JavaScript files
call ale#linter#Define('javascript', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'read_buffer': 0,
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View File

@@ -14,7 +14,7 @@ endfunction
function! ale_linters#javascript#xo#GetCommand(buffer) abort
return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer))
\ . ' ' . ale#Var(a:buffer, 'javascript_xo_options')
\ . ' --reporter unix --stdin --stdin-filename %s'
\ . ' --reporter json --stdin --stdin-filename %s'
endfunction
" xo uses eslint and the output format is the same
@@ -22,5 +22,5 @@ call ale#linter#Define('javascript', {
\ 'name': 'xo',
\ 'executable': function('ale_linters#javascript#xo#GetExecutable'),
\ 'command': function('ale_linters#javascript#xo#GetCommand'),
\ 'callback': 'ale#handlers#eslint#Handle',
\ 'callback': 'ale#handlers#eslint#HandleJSON',
\})

View File

@@ -12,6 +12,8 @@ let g:ale_kotlin_kotlinc_module_filename = get(g:, 'ale_kotlin_kotlinc_module_fi
let s:classpath_sep = has('unix') ? ':' : ';'
function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort
let l:command = ''
" exec maven/gradle only if classpath is not set
if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# ''
return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {})

View File

@@ -4,12 +4,6 @@
call ale#Set('objc_clangd_executable', 'clangd')
call ale#Set('objc_clangd_options', '')
function! ale_linters#objc#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#objc#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options'))
endfunction
@@ -19,5 +13,5 @@ call ale#linter#Define('objc', {
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'objc_clangd_executable')},
\ 'command': function('ale_linters#objc#clangd#GetCommand'),
\ 'project_root': function('ale_linters#objc#clangd#GetProjectRoot'),
\ 'project_root': function('ale#c#FindProjectRoot'),
\})

View File

@@ -4,12 +4,6 @@
call ale#Set('objcpp_clangd_executable', 'clangd')
call ale#Set('objcpp_clangd_options', '')
function! ale_linters#objcpp#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#objcpp#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options'))
endfunction
@@ -19,5 +13,5 @@ call ale#linter#Define('objcpp', {
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')},
\ 'command': function('ale_linters#objcpp#clangd#GetCommand'),
\ 'project_root': function('ale_linters#objcpp#clangd#GetProjectRoot'),
\ 'project_root': function('ale#c#FindProjectRoot'),
\})

View File

@@ -10,13 +10,13 @@ call ale#Set('php_phpcs_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#php#phpcs#GetCommand(buffer) abort
let l:standard = ale#Var(a:buffer, 'php_phpcs_standard')
let l:standard_option = !empty(l:standard)
\ ? '--standard=' . l:standard
\ ? '--standard=' . ale#Escape(l:standard)
\ : ''
let l:options = ale#Var(a:buffer, 'php_phpcs_options')
return '%e -s --report=emacs --stdin-path=%s'
\ . ale#Pad(l:standard_option)
\ . ale#Pad(l:options)
return ale#path#BufferCdString(a:buffer)
\ . '%e -s --report=emacs --stdin-path=%s'
\ . ale#Pad(l:standard_option)
\ . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options'))
endfunction
function! ale_linters#php#phpcs#Handle(buffer, lines) abort
@@ -36,6 +36,7 @@ function! ale_linters#php#phpcs#Handle(buffer, lines) abort
\ 'col': l:match[2] + 0,
\ 'text': l:text,
\ 'type': l:type is# 'error' ? 'E' : 'W',
\ 'sub_type': 'style',
\})
endfor

View File

@@ -3,23 +3,42 @@
" Set to change the ruleset
let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan')
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4')
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '')
let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '')
let g:ale_php_phpstan_autoload = get(g:, 'ale_php_phpstan_autoload', '')
function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration')
let l:configuration_option = !empty(l:configuration)
\ ? ' -c ' . l:configuration
\ ? ' -c ' . ale#Escape(l:configuration)
\ : ''
let l:autoload = ale#Var(a:buffer, 'php_phpstan_autoload')
let l:autoload_option = !empty(l:autoload)
\ ? ' -a ' . ale#Escape(l:autoload)
\ : ''
let l:level = ale#Var(a:buffer, 'php_phpstan_level')
let l:config_file_exists = ale#path#FindNearestFile(a:buffer, 'phpstan.neon')
if empty(l:level) && empty(l:config_file_exists)
" if no configuration file is found, then use 4 as a default level
let l:level = '4'
endif
let l:level_option = !empty(l:level)
\ ? ' -l ' . ale#Escape(l:level)
\ : ''
let l:error_format = ale#semver#GTE(a:version, [0, 10, 3])
\ ? ' --error-format raw'
\ : ' --errorFormat raw'
return '%e analyze -l'
\ . ale#Var(a:buffer, 'php_phpstan_level')
return '%e analyze --no-progress'
\ . l:error_format
\ . l:configuration_option
\ . l:autoload_option
\ . l:level_option
\ . ' %s'
endfunction
@@ -35,7 +54,7 @@ function! ale_linters#php#phpstan#Handle(buffer, lines) abort
call add(l:output, {
\ 'lnum': l:match[2] + 0,
\ 'text': l:match[3],
\ 'type': 'W',
\ 'type': 'E',
\})
endfor

View File

@@ -0,0 +1,91 @@
" Author: Jesse Harris - https://github.com/zigford
" Description: This file adds support for powershell scripts synatax errors
call ale#Set('powershell_powershell_executable', 'pwsh')
function! ale_linters#powershell#powershell#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'powershell_powershell_executable')
endfunction
" Some powershell magic to show syntax errors without executing the script
" thanks to keith hill:
" 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);
\ trap {$_;continue} & {
\ $Contents = Get-Content -Path $Script;
\ $Contents = [string]::Join([Environment]::NewLine, $Contents);
\ [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Contents);
\ };']
return ale#powershell#RunPowerShell(
\ a:buffer, 'powershell_powershell', l:script)
endfunction
" Parse powershell error output using regex into a list of dicts
function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
let l:output = []
" Our 3 patterns we need to scrape the data for the dicts
let l:patterns = [
\ '\v^At line:(\d+) char:(\d+)',
\ '\v^(At|\+| )@!.*',
\ '\vFullyQualifiedErrorId : (\w+)',
\]
let l:matchcount = 0
for l:match in ale#util#GetMatches(a:lines, l:patterns)
" We want to work with 3 matches per syntax error
let l:matchcount = l:matchcount + 1
if l:matchcount == 1 || str2nr(l:match[1])
" First match consists of 2 capture groups, and
" can capture the line and col
if exists('l:item')
" We may be here because the last syntax
" didn't emit a code, and so only had 2
" matches
call add(l:output, l:item)
let l:matchcount = 1
endif
let l:item = {
\ 'lnum': str2nr(l:match[1]),
\ 'col': str2nr(l:match[2]),
\ 'type': 'E',
\}
elseif l:matchcount == 2
" Second match[0] grabs the full line in order
" to handles the text
let l:item['text'] = l:match[0]
else
" Final match handles the code, however
" powershell only emits 1 code for all errors
" so, we get the final code on the last error
" and loop over the previously added items to
" append the code we now know
call add(l:output, l:item)
unlet l:item
if len(l:match[1]) > 0
for l:i in l:output
let l:i['code'] = l:match[1]
endfor
endif
" Reset the matchcount so we can begin gathering
" matches for the next syntax error
let l:matchcount = 0
endif
endfor
return l:output
endfunction
call ale#linter#Define('powershell', {
\ 'name': 'powershell',
\ 'executable_callback': 'ale_linters#powershell#powershell#GetExecutable',
\ 'command_callback': 'ale_linters#powershell#powershell#GetCommand',
\ 'output_stream': 'stdout',
\ 'callback': 'ale_linters#powershell#powershell#Handle',
\})

View File

@@ -13,37 +13,6 @@ function! ale_linters#powershell#psscriptanalyzer#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'powershell_psscriptanalyzer_executable')
endfunction
" Write a powershell script to a temp file for execution
" return the command used to execute it
function! s:TemporaryPSScript(buffer, input) abort
let l:filename = 'script.ps1'
" Create a temp dir to house our temp .ps1 script
" a temp dir is needed as powershell needs the .ps1
" extension
let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
let l:tempscript = l:tempdir . l:filename
" Create the temporary directory for the file, unreadable by 'other'
" users.
call mkdir(l:tempdir, '', 0750)
" Automatically delete the directory later.
call ale#command#ManageDirectory(a:buffer, l:tempdir)
" Write the script input out to a file.
call ale#util#Writefile(a:buffer, a:input, l:tempscript)
return l:tempscript
endfunction
function! ale_linters#powershell#psscriptanalyzer#RunPowerShell(buffer, command) abort
let l:executable = ale_linters#powershell#psscriptanalyzer#GetExecutable(
\ a:buffer)
let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
return ale#Escape(l:executable)
\ . ' -Exe Bypass -NoProfile -File '
\ . ale#Escape(l:tempscript)
\ . ' %t'
endfunction
" Run Invoke-ScriptAnalyzer and output each linting message as 4 seperate lines
" for each parsing
function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
@@ -60,8 +29,10 @@ function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
\ $_.Message;
\ $_.RuleName}']
return ale_linters#powershell#psscriptanalyzer#RunPowerShell(
\ a:buffer, l:script)
return ale#powershell#RunPowerShell(
\ a:buffer,
\ 'powershell_psscriptanalyzer',
\ l:script)
endfunction
" add every 4 lines to an item(Dict) and every item to a list
@@ -98,8 +69,8 @@ endfunction
call ale#linter#Define('powershell', {
\ 'name': 'psscriptanalyzer',
\ 'executable_callback': 'ale_linters#powershell#psscriptanalyzer#GetExecutable',
\ 'command_callback': 'ale_linters#powershell#psscriptanalyzer#GetCommand',
\ 'executable': function('ale_linters#powershell#psscriptanalyzer#GetExecutable'),
\ 'command': function('ale_linters#powershell#psscriptanalyzer#GetCommand'),
\ 'output_stream': 'stdout',
\ 'callback': 'ale_linters#powershell#psscriptanalyzer#Handle',
\})

View File

@@ -31,6 +31,20 @@ function! ale_linters#pug#puglint#GetCommand(buffer) abort
\ . ' -r inline %t'
endfunction
function! ale_linters#pug#puglint#Handle(buffer, lines) abort
for l:line in a:lines[:10]
if l:line =~# '^SyntaxError: '
return [{
\ 'lnum': 1,
\ 'text': 'puglint configuration error (type :ALEDetail for more information)',
\ 'detail': join(a:lines, "\n"),
\}]
endif
endfor
return ale#handlers#unix#HandleAsError(a:buffer, a:lines)
endfunction
call ale#linter#Define('pug', {
\ 'name': 'puglint',
\ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [
@@ -38,5 +52,5 @@ call ale#linter#Define('pug', {
\ ])},
\ 'output_stream': 'stderr',
\ 'command': function('ale_linters#pug#puglint#GetCommand'),
\ 'callback': 'ale#handlers#unix#HandleAsError',
\ 'callback': 'ale_linters#pug#puglint#Handle',
\})

View File

@@ -6,6 +6,7 @@ call ale#Set('python_pylint_options', '')
call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pylint_change_directory', 1)
call ale#Set('python_pylint_auto_pipenv', 0)
call ale#Set('python_pylint_use_msg_id', 0)
function! ale_linters#python#pylint#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylint_auto_pipenv'))
@@ -64,11 +65,17 @@ function! ale_linters#python#pylint#Handle(buffer, lines) abort
continue
endif
if ale#Var(a:buffer, 'python_pylint_use_msg_id') is# 1
let l:code_out = l:code
else
let l:code_out = l:match[4]
endif
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 1,
\ 'text': l:match[5],
\ 'code': l:match[4],
\ 'code': l:code_out,
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
\})
endfor

23
ale_linters/reason/ls.vim Normal file
View File

@@ -0,0 +1,23 @@
" Author: David Buchan-Swanson <github@deecewan.com>
" Description: Integrate ALE with reason-language-server.
call ale#Set('reason_ls_executable', '')
function! ale_linters#reason#ls#FindProjectRoot(buffer) abort
let l:reason_config = ale#path#FindNearestFile(a:buffer, 'bsconfig.json')
if !empty(l:reason_config)
return fnamemodify(l:reason_config, ':h')
endif
return ''
endfunction
call ale#linter#Define('reason', {
\ 'name': 'reason-language-server',
\ 'lsp': 'stdio',
\ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')},
\ 'command': '%e',
\ 'project_root': function('ale_linters#reason#ls#FindProjectRoot'),
\ 'language': 'reason',
\})

View File

@@ -2,7 +2,7 @@
" Description: A language server for Rust
call ale#Set('rust_rls_executable', 'rls')
call ale#Set('rust_rls_toolchain', 'nightly')
call ale#Set('rust_rls_toolchain', '')
call ale#Set('rust_rls_config', {})
function! ale_linters#rust#rls#GetCommand(buffer) abort

View File

@@ -10,6 +10,7 @@ call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_excl
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)
@@ -40,12 +41,15 @@ function! ale_linters#sh#shellcheck#GetCommand(buffer, version) abort
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 ale#path#BufferCdString(a:buffer)
return l:cd_string
\ . '%e'
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
\ . (!empty(l:options) ? ' ' . l:options : '')

View File

@@ -0,0 +1,13 @@
" Author: Dan Loman <https://github.com/namolnad>
" Description: Support for sourcekit-lsp https://github.com/apple/sourcekit-lsp
call ale#Set('sourcekit_lsp_executable', 'sourcekit-lsp')
call ale#linter#Define('swift', {
\ 'name': 'sourcekitlsp',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')},
\ 'command': '%e',
\ 'project_root': function('ale#swift#FindProjectRoot'),
\ 'language': 'swift',
\})

View File

@@ -0,0 +1,49 @@
" Author: Keith Maxwell <keith.maxwell@gmail.com>
" Description: terraform fmt to check for errors
call ale#Set('terraform_terraform_executable', 'terraform')
function! ale_linters#terraform#terraform#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'terraform_terraform_executable')
endfunction
function! ale_linters#terraform#terraform#GetCommand(buffer) abort
return ale#Escape(ale_linters#terraform#terraform#GetExecutable(a:buffer))
\ . ' fmt -no-color --check=true -'
endfunction
function! ale_linters#terraform#terraform#Handle(buffer, lines) abort
let l:head = '^Error running fmt: In <standard input>: '
let l:output = []
let l:patterns = [
\ l:head.'At \(\d\+\):\(\d\+\): \(.*\)$',
\ l:head.'\(.*\)$'
\]
for l:match in ale#util#GetMatches(a:lines, l:patterns)
if len(l:match[2]) > 0
call add(l:output, {
\ 'lnum': str2nr(l:match[1]),
\ 'col': str2nr(l:match[2]),
\ 'text': l:match[3],
\ 'type': 'E',
\})
else
call add(l:output, {
\ 'lnum': line('$'),
\ 'text': l:match[1],
\ 'type': 'E',
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('terraform', {
\ 'name': 'terraform',
\ 'output_stream': 'stderr',
\ 'executable': function('ale_linters#terraform#terraform#GetExecutable'),
\ 'command': function('ale_linters#terraform#terraform#GetCommand'),
\ 'callback': 'ale_linters#terraform#terraform#Handle',
\})

View File

@@ -0,0 +1,21 @@
" Author: Ricardo Liang <ricardoliang@gmail.com>
" Description: Texlab language server (Rust rewrite)
call ale#Set('tex_texlab_executable', 'texlab')
call ale#Set('tex_texlab_options', '')
function! ale_linters#tex#texlab#GetProjectRoot(buffer) abort
return ''
endfunction
function! ale_linters#tex#texlab#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'tex_texlab_options'))
endfunction
call ale#linter#Define('tex', {
\ 'name': 'texlab',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'tex_texlab_executable')},
\ 'command': function('ale_linters#tex#texlab#GetCommand'),
\ 'project_root': function('ale_linters#tex#texlab#GetProjectRoot'),
\})

View File

@@ -5,5 +5,5 @@ call ale#linter#Define('typescript', {
\ 'name': 'eslint',
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'command': function('ale#handlers#eslint#GetCommand'),
\ 'callback': 'ale#handlers#eslint#Handle',
\ 'callback': 'ale#handlers#eslint#HandleJSON',
\})

View File

@@ -0,0 +1,23 @@
call ale#Set('typescript_xo_executable', 'xo')
call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('typescript_xo_options', '')
function! ale_linters#typescript#xo#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'typescript_xo', [
\ 'node_modules/.bin/xo',
\])
endfunction
function! ale_linters#typescript#xo#GetCommand(buffer) abort
return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer))
\ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options'))
\ . ' --reporter json --stdin --stdin-filename %s'
endfunction
" xo uses eslint and the output format is the same
call ale#linter#Define('typescript', {
\ 'name': 'xo',
\ 'executable': function('ale_linters#typescript#xo#GetExecutable'),
\ 'command': function('ale_linters#typescript#xo#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON',
\})

View File

@@ -43,6 +43,11 @@ function! ale#ShouldDoNothing(buffer) abort
return 1
endif
" Do nothing for diff buffers.
if getbufvar(a:buffer, '&diff')
return 1
endif
" Do nothing for blacklisted files.
if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0
return 1
@@ -92,7 +97,7 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
" Apply ignore lists for linters only if needed.
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
let l:linters = !empty(l:ignore_config)
let l:linters = !empty(l:ignore_config) || l:disable_lsp
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config, l:disable_lsp)
\ : l:linters
@@ -151,7 +156,7 @@ function! ale#Queue(delay, ...) abort
endif
endfunction
let s:current_ale_version = [2, 4, 0]
let s:current_ale_version = [2, 5, 0]
" A function used to check for ALE features in files outside of the project.
function! ale#Has(feature) abort

41
autoload/ale/ant.vim Normal file
View File

@@ -0,0 +1,41 @@
" Author: Andrew Lee <andrewl@mbda.fun>.
" Inspired by ale/gradle.vim by Michael Pardo <michael@michaelpardo.com>
" Description: Functions for working with Ant projects.
" Given a buffer number, find an Ant project root
function! ale#ant#FindProjectRoot(buffer) abort
let l:build_xml_path = ale#path#FindNearestFile(a:buffer, 'build.xml')
if !empty(l:build_xml_path)
return fnamemodify(l:build_xml_path, ':h')
endif
return ''
endfunction
" Given a buffer number, find the path to the `ant` executable. Returns an empty
" string if cannot find the executable.
function! ale#ant#FindExecutable(buffer) abort
if executable('ant')
return 'ant'
endif
return ''
endfunction
" Given a buffer number, build a command to print the classpath of the root
" project. Returns an empty string if cannot build the command.
function! ale#ant#BuildClasspathCommand(buffer) abort
let l:executable = ale#ant#FindExecutable(a:buffer)
let l:project_root = ale#ant#FindProjectRoot(a:buffer)
if !empty(l:executable) && !empty(l:project_root)
return ale#path#CdString(l:project_root)
\ . ale#Escape(l:executable)
\ . ' classpath'
\ . ' -S'
\ . ' -q'
endif
return ''
endfunction

View File

@@ -96,6 +96,13 @@ function! ale#assert#Fixer(expected_result) abort
AssertEqual a:expected_result, l:result
endfunction
function! ale#assert#FixerNotExecuted() abort
let l:buffer = bufnr('')
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))[-1]
Assert empty(l:result), "The fixer will be executed when it shouldn't be"
endfunction
function! ale#assert#LinterNotExecuted() abort
let l:buffer = bufnr('')
let l:linter = s:GetLinter()
@@ -158,6 +165,7 @@ endfunction
function! ale#assert#SetUpFixerTestCommands() abort
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted()
endfunction
" A dummy function for making sure this module is loaded.
@@ -316,4 +324,8 @@ function! ale#assert#TearDownFixerTest() abort
if exists(':AssertFixer')
delcommand AssertFixer
endif
if exists(':AssertFixerNotExecuted')
delcommand AssertFixerNotExecuted
endif
endfunction

View File

@@ -23,27 +23,9 @@ function! ale#c#GetBuildDirectory(buffer) abort
return l:build_dir
endif
return ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
endfunction
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
function! ale#c#FindProjectRoot(buffer) abort
for l:project_filename in g:__ale_c_project_filenames
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
if !empty(l:full_path)
let l:path = fnamemodify(l:full_path, ':h')
" Correct .git path detection.
if fnamemodify(l:path, ':t') is# '.git'
let l:path = fnamemodify(l:path, ':h')
endif
return l:path
endif
endfor
return ''
return ale#path#Dirname(l:json_file)
endfunction
function! ale#c#AreSpecialCharsBalanced(option) abort
@@ -120,7 +102,7 @@ endfunction
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
if !g:ale_c_parse_makefile
return ''
return v:null
endif
let l:buffer_filename = expand('#' . a:buffer . ':t')
@@ -140,14 +122,17 @@ function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line)
endfunction
" Given a buffer number, find the build subdirectory with compile commands
" The subdirectory is returned without the trailing /
" Given a buffer number, find the project directory containing
" compile_commands.json, and the path to the compile_commands.json file.
"
" If compile_commands.json cannot be found, two empty strings will be
" returned.
function! ale#c#FindCompileCommands(buffer) abort
" Look above the current source file to find compile_commands.json
let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
if !empty(l:json_file)
return l:json_file
return [fnamemodify(l:json_file, ':h'), l:json_file]
endif
" Search in build directories if we can't find it in the project.
@@ -157,12 +142,42 @@ function! ale#c#FindCompileCommands(buffer) abort
let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
if filereadable(l:json_file)
return l:json_file
return [l:path, l:json_file]
endif
endfor
endfor
return ''
return ['', '']
endfunction
" Find the project root for C/C++ projects.
"
" The location of compile_commands.json will be used to find project roots.
"
" If compile_commands.json cannot be found, other common configuration files
" will be used to detect the project root.
function! ale#c#FindProjectRoot(buffer) abort
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
" Fall back on detecting the project root based on other filenames.
if empty(l:root)
for l:project_filename in g:__ale_c_project_filenames
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
if !empty(l:full_path)
let l:path = fnamemodify(l:full_path, ':h')
" Correct .git path detection.
if fnamemodify(l:path, ':t') is# '.git'
let l:path = fnamemodify(l:path, ':h')
endif
return l:path
endif
endfor
endif
return l:root
endfunction
" Cache compile_commands.json data in a Dictionary, so we don't need to read
@@ -194,10 +209,14 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
let l:raw_data = []
silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), ''))
if type(l:raw_data) isnot v:t_list
let l:raw_data = []
endif
let l:file_lookup = {}
let l:dir_lookup = {}
for l:entry in l:raw_data
for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : [])
let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
@@ -219,9 +238,32 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
" Search for an exact file match first.
let l:basename = tolower(expand('#' . a:buffer . ':t'))
let l:file_list = get(a:file_lookup, l:basename, [])
" A source file matching the header filename.
let l:source_file = ''
if empty(l:file_list) && l:basename =~? '\.h$\|\.hpp$'
for l:suffix in ['.c', '.cpp']
let l:key = fnamemodify(l:basename, ':r') . l:suffix
let l:file_list = get(a:file_lookup, l:key, [])
if !empty(l:file_list)
let l:source_file = l:key
break
endif
endfor
endif
for l:item in l:file_list
if bufnr(l:item.file) is a:buffer && has_key(l:item, 'command')
" Load the flags for this file, or for a source file matching the
" header file.
if has_key(l:item, 'command')
\&& (
\ bufnr(l:item.file) is a:buffer
\ || (
\ !empty(l:source_file)
\ && l:item.file[-len(l:source_file):] is? l:source_file
\ )
\)
return ale#c#ParseCFlags(l:item.directory, l:item.command)
endif
endfor
@@ -251,25 +293,25 @@ function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort
endfunction
function! ale#c#GetCFlags(buffer, output) abort
let l:cflags = ' '
let l:cflags = v:null
if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output)
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
endif
if ale#Var(a:buffer, 'c_parse_compile_commands')
let l:json_file = ale#c#FindCompileCommands(a:buffer)
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
if !empty(l:json_file)
let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file)
endif
endif
if l:cflags is# ' '
if l:cflags is v:null
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
endif
return l:cflags
return l:cflags isnot v:null ? l:cflags : ''
endfunction
function! ale#c#GetMakeCommand(buffer) abort

View File

@@ -159,18 +159,20 @@ function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort
endfunction
function! s:ReplaceCompletionOptions() abort
" Remember the old omnifunc value, if there is one.
" If we don't store an old one, we'll just never reset the option.
" This will stop some random exceptions from appearing.
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
let b:ale_old_omnifunc = &l:omnifunc
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
" Remember the old omnifunc value, if there is one.
" If we don't store an old one, we'll just never reset the option.
" This will stop some random exceptions from appearing.
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
let b:ale_old_omnifunc = &l:omnifunc
endif
let &l:omnifunc = 'ale#completion#AutomaticOmniFunc'
endif
let &l:omnifunc = 'ale#completion#OmniFunc'
let l:info = get(b:, 'ale_completion_info', {})
if !get(l:info, 'manual')
if l:source is# 'ale-automatic'
if !exists('b:ale_old_completeopt')
let b:ale_old_completeopt = &l:completeopt
endif
@@ -199,47 +201,65 @@ function! ale#completion#RestoreCompletionOptions() abort
endif
endfunction
function! ale#completion#OmniFunc(findstart, base) abort
function! ale#completion#GetCompletionPosition() abort
if !exists('b:ale_completion_info')
return 0
endif
let l:line = b:ale_completion_info.line
let l:column = b:ale_completion_info.column
let l:regex = s:GetFiletypeValue(s:omni_start_map, &filetype)
let l:up_to_column = getline(l:line)[: l:column - 2]
let l:match = matchstr(l:up_to_column, l:regex)
return l:column - len(l:match) - 1
endfunction
function! ale#completion#GetCompletionResult() abort
if exists('b:ale_completion_result')
return b:ale_completion_result
endif
return v:null
endfunction
function! ale#completion#AutomaticOmniFunc(findstart, base) abort
if a:findstart
let l:line = b:ale_completion_info.line
let l:column = b:ale_completion_info.column
let l:regex = s:GetFiletypeValue(s:omni_start_map, &filetype)
let l:up_to_column = getline(l:line)[: l:column - 2]
let l:match = matchstr(l:up_to_column, l:regex)
return l:column - len(l:match) - 1
return ale#completion#GetCompletionPosition()
else
" Parse a new response if there is one.
if exists('b:ale_completion_response')
\&& exists('b:ale_completion_parser')
let l:response = b:ale_completion_response
let l:parser = b:ale_completion_parser
unlet b:ale_completion_response
unlet b:ale_completion_parser
let b:ale_completion_result = function(l:parser)(l:response)
endif
let l:result = ale#completion#GetCompletionResult()
call s:ReplaceCompletionOptions()
return get(b:, 'ale_completion_result', [])
return l:result isnot v:null ? l:result : []
endif
endfunction
function! ale#completion#Show(response, completion_parser) abort
function! ale#completion#Show(result) abort
if ale#util#Mode() isnot# 'i'
return
endif
" Set the list in the buffer, temporarily replace omnifunc with our
" function, and then start omni-completion.
let b:ale_completion_response = a:response
let b:ale_completion_parser = a:completion_parser
let b:ale_completion_result = a:result
" Don't try to open the completion menu if there's nothing to show.
if empty(b:ale_completion_result)
return
endif
" Replace completion options shortly before opening the menu.
call s:ReplaceCompletionOptions()
call timer_start(0, {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")})
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
call timer_start(
\ 0,
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
\)
endif
endfunction
function! s:CompletionStillValid(request_id) abort
@@ -249,7 +269,11 @@ function! s:CompletionStillValid(request_id) abort
\&& has_key(b:, 'ale_completion_info')
\&& b:ale_completion_info.request_id == a:request_id
\&& b:ale_completion_info.line == l:line
\&& b:ale_completion_info.column == l:column
\&& (
\ b:ale_completion_info.column == l:column
\ || b:ale_completion_info.source is# 'deoplete'
\ || b:ale_completion_info.source is# 'ale-omnifunc'
\)
endfunction
function! ale#completion#ParseTSServerCompletions(response) abort
@@ -356,6 +380,8 @@ function! ale#completion#ParseLSPCompletions(response) abort
if get(l:item, 'insertTextFormat') is s:LSP_INSERT_TEXT_FORMAT_PLAIN
\&& type(get(l:item, 'textEdit')) is v:t_dict
let l:text = l:item.textEdit.newText
elseif type(get(l:item, 'insertText')) is v:t_string
let l:text = l:item.insertText
else
let l:text = l:item.label
endif
@@ -442,8 +468,7 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
endif
elseif l:command is# 'completionEntryDetails'
call ale#completion#Show(
\ a:response,
\ 'ale#completion#ParseTSServerCompletionEntryDetails',
\ ale#completion#ParseTSServerCompletionEntryDetails(a:response),
\)
endif
endfunction
@@ -455,8 +480,7 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort
endif
call ale#completion#Show(
\ a:response,
\ 'ale#completion#ParseLSPCompletions',
\ ale#completion#ParseLSPCompletions(a:response),
\)
endfunction
@@ -497,10 +521,7 @@ function! s:OnReady(linter, lsp_details) abort
let l:message = ale#lsp#message#Completion(
\ l:buffer,
\ b:ale_completion_info.line,
\ min([
\ b:ale_completion_info.line_length,
\ b:ale_completion_info.column,
\ ]) + 1,
\ b:ale_completion_info.column,
\ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix),
\)
endif
@@ -517,15 +538,28 @@ function! s:OnReady(linter, lsp_details) abort
endif
endfunction
" This function can be called to check if ALE can provide completion data for
" the current buffer. 1 will be returned if there's a potential source of
" completion data ALE can use, and 0 will be returned otherwise.
function! ale#completion#CanProvideCompletions() abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
return 1
endif
endfor
return 0
endfunction
" This function can be used to manually trigger autocomplete, even when
" g:ale_completion_enabled is set to false
function! ale#completion#GetCompletions(manual) abort
function! ale#completion#GetCompletions(source) abort
let [l:line, l:column] = getpos('.')[1:2]
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
if !a:manual && empty(l:prefix)
return
if a:source is# 'ale-automatic' && empty(l:prefix)
return 0
endif
let l:line_length = len(getline('.'))
@@ -537,21 +571,51 @@ function! ale#completion#GetCompletions(manual) abort
\ 'prefix': l:prefix,
\ 'conn_id': 0,
\ 'request_id': 0,
\ 'manual': a:manual,
\ 'source': a:source,
\}
unlet! b:ale_completion_result
let l:buffer = bufnr('')
let l:Callback = function('s:OnReady')
let l:started = 0
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
let l:started = 1
endif
endif
endfor
return l:started
endfunction
function! ale#completion#OmniFunc(findstart, base) abort
if a:findstart
let l:started = ale#completion#GetCompletions('ale-omnifunc')
if !l:started
" This is the special value for cancelling completions silently.
" See :help complete-functions
return -3
endif
return ale#completion#GetCompletionPosition()
else
let l:result = ale#completion#GetCompletionResult()
while l:result is v:null && !complete_check()
sleep 2ms
let l:result = ale#completion#GetCompletionResult()
endwhile
return l:result isnot v:null ? l:result : []
endif
endfunction
function! s:TimerHandler(...) abort
if !g:ale_completion_enabled
if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled)
return
endif
@@ -562,7 +626,7 @@ function! s:TimerHandler(...) abort
" When running the timer callback, we have to be sure that the cursor
" hasn't moved from where it was when we requested completions by typing.
if s:timer_pos == [l:line, l:column] && ale#util#Mode() is# 'i'
call ale#completion#GetCompletions(0)
call ale#completion#GetCompletions('ale-automatic')
endif
endfunction
@@ -576,7 +640,7 @@ function! ale#completion#StopTimer() abort
endfunction
function! ale#completion#Queue() abort
if !g:ale_completion_enabled
if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled)
return
endif

View File

@@ -25,7 +25,7 @@ function! ale#cursor#TruncatedEcho(original_message) abort
let l:cursor_position = getpos('.')
" The message is truncated and saved to the history.
setlocal shortmess+=T
silent! setlocal shortmess+=T
try
exec "norm! :echomsg l:message\n"

View File

@@ -1,10 +1,6 @@
" Author: Auri <me@aurieh.me>
" Description: Functions for integrating with D linters.
function! otherproject#util#Double(x) abort
return a:x * 2
endfunction
function! ale#d#FindDUBConfig(buffer) abort
" Find a DUB configuration file in ancestor paths.
" The most DUB-specific names will be tried first.

View File

@@ -238,6 +238,12 @@ function! ale#debugging#Info() abort
endfunction
function! ale#debugging#InfoToClipboard() abort
if !has('clipboard')
call s:Echo('clipboard not available. Try :ALEInfoToFile instead.')
return
endif
redir => l:output
silent call ale#debugging#Info()
redir END

View File

@@ -3,6 +3,9 @@
let s:go_to_definition_map = {}
" Enable automatic updates of the tagstack
let g:ale_update_tagstack = get(g:, 'ale_update_tagstack', 1)
" Used to get the definition map in tests.
function! ale#definition#GetMap() abort
return deepcopy(s:go_to_definition_map)
@@ -17,6 +20,20 @@ function! ale#definition#ClearLSPData() abort
let s:go_to_definition_map = {}
endfunction
function! ale#definition#UpdateTagStack() abort
let l:should_update_tagstack = exists('*gettagstack') && exists('*settagstack') && g:ale_update_tagstack
if l:should_update_tagstack
" Grab the old location (to jump back to) and the word under the
" cursor (as a label for the tagstack)
let l:old_location = [bufnr('%'), line('.'), col('.'), 0]
let l:tagname = expand('<cword>')
let l:winid = win_getid()
call settagstack(l:winid, {'items': [{'from': l:old_location, 'tagname': l:tagname}]}, 'a')
call settagstack(l:winid, {'curidx': len(gettagstack(l:winid)['items']) + 1})
endif
endfunction
function! ale#definition#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') is# 'definition'
\&& has_key(s:go_to_definition_map, a:response.request_seq)
@@ -27,6 +44,7 @@ function! ale#definition#HandleTSServerResponse(conn_id, response) abort
let l:line = a:response.body[0].start.line
let l:column = a:response.body[0].start.offset
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options)
endif
endif
@@ -51,6 +69,7 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
let l:line = l:item.range.start.line + 1
let l:column = l:item.range.start.character + 1
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options)
break
endfor

View File

@@ -39,8 +39,8 @@ function! ale#engine#MarkLinterActive(info, linter) abort
endif
endfunction
function! ale#engine#MarkLinterInactive(info, linter) abort
call filter(a:info.active_linter_list, 'v:val.name isnot# a:linter.name')
function! ale#engine#MarkLinterInactive(info, linter_name) abort
call filter(a:info.active_linter_list, 'v:val.name isnot# a:linter_name')
endfunction
function! ale#engine#ResetExecutableCache() abort
@@ -195,7 +195,7 @@ function! s:HandleExit(job_info, buffer, output, data) abort
let l:next_chain_index = a:job_info.next_chain_index
" Remove this job from the list.
call ale#engine#MarkLinterInactive(l:buffer_info, l:linter)
call ale#engine#MarkLinterInactive(l:buffer_info, l:linter.name)
" Stop here if we land in the handle for a job completing if we're in
" a sandbox.
@@ -710,6 +710,10 @@ function! ale#engine#Cleanup(buffer) abort
return
endif
if exists('*ale#lsp#CloseDocument')
call ale#lsp#CloseDocument(a:buffer)
endif
if !has_key(g:ale_buffer_info, a:buffer)
return
endif

View File

@@ -128,7 +128,7 @@ function! ale#events#Init() abort
endif
if g:ale_lint_on_insert_leave
autocmd InsertLeave * call ale#Queue(0)
autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif
endif
if g:ale_echo_cursor || g:ale_cursor_detail

View File

@@ -1,45 +1,61 @@
call ale#Set('fix_on_save_ignore', {})
" Apply fixes queued up for buffers which may be hidden.
" Vim doesn't let you modify hidden buffers.
function! ale#fix#ApplyQueuedFixes() abort
let l:buffer = bufnr('')
let l:data = get(g:ale_fix_buffer_data, l:buffer, {'done': 0})
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
if !l:data.done || (!l:has_bufline_api && a:buffer isnot bufnr(''))
return
endif
call remove(g:ale_fix_buffer_data, l:buffer)
call remove(g:ale_fix_buffer_data, a:buffer)
if l:data.changes_made
let l:start_line = len(l:data.output) + 1
let l:end_line = len(l:data.lines_before)
if l:end_line >= l:start_line
let l:save = winsaveview()
silent execute l:start_line . ',' . l:end_line . 'd_'
call winrestview(l:save)
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:lines_to_set = getbufvar(l:buffer, '&fileformat') is# 'dos'
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
call setline(1, l:lines_to_set)
" 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
if l:data.should_save
if empty(&buftype)
noautocmd :w!
if a:buffer is bufnr('')
if empty(&buftype)
noautocmd :w!
else
set nomodified
endif
else
set nomodified
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks
call setbufvar(a:buffer, '&modified', 0)
endif
endif
endif
if l:data.should_save
let l:should_lint = g:ale_fix_on_save
let l:should_lint = ale#Var(a:buffer, 'fix_on_save')
\ && ale#Var(a:buffer, 'lint_on_save')
else
let l:should_lint = l:data.changes_made
endif
@@ -50,7 +66,7 @@ function! ale#fix#ApplyQueuedFixes() abort
" fixing problems.
if g:ale_enabled
\&& l:should_lint
\&& !ale#events#QuitRecently(l:buffer)
\&& !ale#events#QuitRecently(a:buffer)
call ale#Queue(0, l:data.should_save ? 'lint_file' : '')
endif
endfunction
@@ -81,7 +97,7 @@ function! ale#fix#ApplyFixes(buffer, output) abort
" We can only change the lines of a buffer which is currently open,
" so try and apply the fixes to the current buffer.
call ale#fix#ApplyQueuedFixes()
call ale#fix#ApplyQueuedFixes(a:buffer)
endfunction
function! s:HandleExit(job_info, buffer, job_output, data) abort
@@ -265,7 +281,21 @@ function! s:AddSubCallbacks(full_list, callbacks) abort
return 1
endfunction
function! s:GetCallbacks(buffer, fixers) abort
function! s:IgnoreFixers(callback_list, filetype, config) abort
if type(a:config) is v:t_list
let l:ignore_list = a:config
else
let l:ignore_list = []
for l:part in split(a:filetype , '\.')
call extend(l:ignore_list, get(a:config, l:part, []))
endfor
endif
call filter(a:callback_list, 'index(l:ignore_list, v:val) < 0')
endfunction
function! s:GetCallbacks(buffer, fixing_flag, fixers) abort
if len(a:fixers)
let l:callback_list = a:fixers
elseif type(get(b:, 'ale_fixers')) is v:t_list
@@ -290,8 +320,12 @@ function! s:GetCallbacks(buffer, fixers) abort
endif
endif
if empty(l:callback_list)
return []
if a:fixing_flag is# 'save_file'
let l:config = ale#Var(a:buffer, 'fix_on_save_ignore')
if !empty(l:config)
call s:IgnoreFixers(l:callback_list, &filetype, l:config)
endif
endif
let l:corrected_list = []
@@ -339,7 +373,7 @@ function! ale#fix#Fix(buffer, fixing_flag, ...) abort
endif
try
let l:callback_list = s:GetCallbacks(a:buffer, a:000)
let l:callback_list = s:GetCallbacks(a:buffer, a:fixing_flag, a:000)
catch /E700\|BADNAME/
let l:function_name = join(split(split(v:exception, ':')[3]))
let l:echo_message = printf(
@@ -379,5 +413,4 @@ endfunction
" Set up an autocmd command to try and apply buffer fixes when available.
augroup ALEBufferFixGroup
autocmd!
autocmd BufEnter * call ale#fix#ApplyQueuedFixes()
augroup END
autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand('<abuf>')))

View File

@@ -27,6 +27,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with black.',
\ },
\ 'fecs': {
\ 'function': 'ale#fixers#fecs#Fix',
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
\ 'description': 'Apply fecs format to a file.',
\ },
\ 'tidy': {
\ 'function': 'ale#fixers#tidy#Fix',
\ 'suggested_filetypes': ['html'],
@@ -185,6 +190,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['hack'],
\ 'description': 'Fix Hack files with hackfmt.',
\ },
\ 'floskell': {
\ 'function': 'ale#fixers#floskell#Fix',
\ 'suggested_filetypes': ['haskell'],
\ 'description': 'Fix Haskell files with floskell.',
\ },
\ 'hfmt': {
\ 'function': 'ale#fixers#hfmt#Fix',
\ 'suggested_filetypes': ['haskell'],
@@ -210,6 +220,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['ocaml'],
\ 'description': 'Fix OCaml files with ocamlformat.',
\ },
\ 'ocp-indent': {
\ 'function': 'ale#fixers#ocp_indent#Fix',
\ 'suggested_filetypes': ['ocaml'],
\ 'description': 'Fix OCaml files with ocp-indent.',
\ },
\ 'refmt': {
\ 'function': 'ale#fixers#refmt#Fix',
\ 'suggested_filetypes': ['reason'],
@@ -247,8 +262,8 @@ let s:default_registry = {
\ },
\ 'xo': {
\ 'function': 'ale#fixers#xo#Fix',
\ 'suggested_filetypes': ['javascript'],
\ 'description': 'Fix JavaScript files using xo --fix.',
\ 'suggested_filetypes': ['javascript', 'typescript'],
\ 'description': 'Fix JavaScript/TypeScript files using xo --fix.',
\ },
\ 'qmlfmt': {
\ 'function': 'ale#fixers#qmlfmt#Fix',
@@ -280,6 +295,26 @@ let s:default_registry = {
\ 'suggested_filetypes': ['kt'],
\ 'description': 'Fix Kotlin files with ktlint.',
\ },
\ 'styler': {
\ 'function': 'ale#fixers#styler#Fix',
\ 'suggested_filetypes': ['r', 'rmarkdown'],
\ 'description': 'Fix R files with styler.',
\ },
\ 'latexindent': {
\ 'function': 'ale#fixers#latexindent#Fix',
\ 'suggested_filetypes': ['tex'],
\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
\ },
\ 'pgformatter': {
\ 'function': 'ale#fixers#pgformatter#Fix',
\ 'suggested_filetypes': ['sql'],
\ 'description': 'A PostgreSQL SQL syntax beautifier',
\ },
\ 'reorder-python-imports': {
\ 'function': 'ale#fixers#reorder_python_imports#Fix',
\ 'suggested_filetypes': ['python'],
\ 'description': 'Sort Python imports with reorder-python-imports.',
\ },
\}
" Reset the function registry to the default entries.

View File

@@ -35,9 +35,18 @@ endfunction
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
if empty(l:config)
" Use the configuration file from the options, if configured.
if l:options =~# '\v(^| )-c|(^| )--config'
let l:config = ''
let l:has_config = 1
else
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
let l:has_config = !empty(l:config)
endif
if !l:has_config
return 0
endif
@@ -45,6 +54,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
return {
\ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
\}
@@ -54,6 +64,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
if ale#semver#GTE(a:version, [4, 9, 0])
return {
\ 'command': 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',
\}
@@ -61,7 +72,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
return {
\ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ' -c ' . ale#Escape(l:config)
\ . ale#Pad(l:options)
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
\ . ' --fix %t',
\ 'read_temporary_file': 1,
\}

View File

@@ -0,0 +1,17 @@
" Author: harttle <yangjvn@126.com>
" Description: Apply fecs format to a file.
function! ale#fixers#fecs#Fix(buffer) abort
let l:executable = ale#handlers#fecs#GetExecutable(a:buffer)
if !executable(l:executable)
return 0
endif
let l:config_options = ' format --replace=true %t'
return {
\ 'command': ale#Escape(l:executable) . l:config_options,
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -0,0 +1,20 @@
" Author: robertjlooby <robertjlooby@gmail.com>
" Description: Integration of floskell with ALE.
call ale#Set('haskell_floskell_executable', 'floskell')
function! ale#fixers#floskell#GetExecutable(buffer) abort
let l:executable = ale#Var(a:buffer, 'haskell_floskell_executable')
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'floskell')
endfunction
function! ale#fixers#floskell#Fix(buffer) abort
let l:executable = ale#fixers#floskell#GetExecutable(a:buffer)
return {
\ 'command': l:executable
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -0,0 +1,18 @@
" Author: riley-martine <riley.martine@protonmail.com>
" Description: Integration of latexindent with ALE.
call ale#Set('tex_latexindent_executable', 'latexindent')
call ale#Set('tex_latexindent_options', '')
function! ale#fixers#latexindent#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'tex_latexindent_executable')
let l:options = ale#Var(a:buffer, 'tex_latexindent_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ' -l -w'
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -0,0 +1,18 @@
" Author: Kanenobu Mitsuru
" Description: Integration of ocp-indent with ALE.
call ale#Set('ocaml_ocp_indent_executable', 'ocp-indent')
call ale#Set('ocaml_ocp_indent_options', '')
call ale#Set('ocaml_ocp_indent_config', '')
function! ale#fixers#ocp_indent#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'ocaml_ocp_indent_executable')
let l:config = ale#Var(a:buffer, 'ocaml_ocp_indent_config')
let l:options = ale#Var(a:buffer, 'ocaml_ocp_indent_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (empty(l:config) ? '' : ' --config=' . ale#Escape(l:config))
\ . (empty(l:options) ? '': ' ' . l:options)
\}
endfunction

View File

@@ -0,0 +1,12 @@
call ale#Set('sql_pgformatter_executable', 'pg_format')
call ale#Set('sql_pgformatter_options', '')
function! ale#fixers#pgformatter#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'sql_pgformatter_executable')
let l:options = ale#Var(a:buffer, 'sql_pgformatter_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (empty(l:options) ? '' : ' ' . l:options),
\}
endfunction

View File

@@ -0,0 +1,25 @@
" Author: jake <me@jake.computer>
" Description: Fixing Python imports with reorder-python-imports.
call ale#Set('python_reorder_python_imports_executable', 'reorder-python-imports')
call ale#Set('python_reorder_python_imports_options', '')
call ale#Set('python_reorder_python_imports_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale#fixers#reorder_python_imports#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_reorder_python_imports',
\ ['reorder-python-imports'],
\)
if !executable(l:executable)
return 0
endif
let l:options = ale#Var(a:buffer, 'python_reorder_python_imports_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\}
endfunction

View File

@@ -0,0 +1,16 @@
" Author: tvatter <thibault.vatter@gmail.com>
" Description: Fixing R files with styler.
call ale#Set('r_styler_executable', 'Rscript')
call ale#Set('r_styler_options', 'tidyverse_style')
function! ale#fixers#styler#Fix(buffer) abort
return {
\ 'command': 'Rscript --vanilla -e '
\ . '"suppressPackageStartupMessages(library(styler));'
\ . 'style_file(commandArgs(TRUE), style = '
\ . ale#Var(a:buffer, 'r_styler_options') . ')"'
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -3,15 +3,17 @@ scriptencoding utf-8
" Description: Utilities for ccls
function! ale#handlers#ccls#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls-root')
" Try to find ccls configuration files first.
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls-root')
if empty(l:project_root)
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
if empty(l:config)
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls')
endif
if empty(l:project_root)
let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls')
if !empty(l:config)
return fnamemodify(l:config, ':h')
endif
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
" Fall back on default project root detection.
return ale#c#FindProjectRoot(a:buffer)
endfunction

View File

@@ -1,5 +1,46 @@
" Description: Handle errors for cppcheck.
function! ale#handlers#cppcheck#GetCdCommand(buffer) abort
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
let l:cd_command = !empty(l:dir) ? ale#path#CdString(l:dir) : ''
return l:cd_command
endfunction
function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort
let l:buffer_path_include = ''
" Get path to this buffer so we can include it into cppcheck with -I
" This could be expanded to get more -I directives from the compile
" command in compile_commands.json, if it's found.
let l:buffer_path = fnamemodify(bufname(a:buffer), ':p:h')
let l:buffer_path_include = ' -I' . ale#Escape(l:buffer_path)
return l:buffer_path_include
endfunction
function! ale#handlers#cppcheck#GetCompileCommandsOptions(buffer) abort
" If the current buffer is modified, using compile_commands.json does no
" good, so include the file's directory instead. It's not quite as good as
" using --project, but is at least equivalent to running cppcheck on this
" file manually from the file's directory.
let l:modified = getbufvar(a:buffer, '&modified')
if l:modified
return ''
endif
" Search upwards from the file for compile_commands.json.
"
" If we find it, we'll `cd` to where the compile_commands.json file is,
" then use the file to set up import paths, etc.
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
return !empty(l:json_path)
\ ? '--project=' . ale#Escape(l:json_path[len(l:dir) + 1: ])
\ : ''
endfunction
function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
" Look for lines like the following.
"

View File

@@ -44,16 +44,9 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
return ale#node#Executable(a:buffer, l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -f unix --stdin --stdin-filename %s'
\ . ' -f json --stdin --stdin-filename %s'
endfunction
let s:col_end_patterns = [
\ '\vParsing error: Unexpected token (.+) ?',
\ '\v''(.+)'' is not defined.',
\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
\ '\vUnexpected (console) statement',
\]
function! s:AddHintsForTypeScriptParsingErrors(output) abort
for l:item in a:output
let l:item.text = substitute(
@@ -90,22 +83,71 @@ function! s:CheckForBadConfig(buffer, lines) abort
return 0
endfunction
function! ale#handlers#eslint#Handle(buffer, lines) abort
if s:CheckForBadConfig(a:buffer, a:lines)
return [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(a:lines, "\n"),
\}]
function! s:parseJSON(buffer, lines) abort
try
let l:parsed = json_decode(a:lines[-1])
catch
return []
endtry
if type(l:parsed) != v:t_list || empty(l:parsed)
return []
endif
if a:lines == ['Could not connect']
return [{
\ 'lnum': 1,
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
\}]
let l:errors = l:parsed[0]['messages']
if empty(l:errors)
return []
endif
let l:output = []
for l:error in l:errors
let l:obj = ({
\ 'lnum': get(l:error, 'line', 0),
\ 'text': get(l:error, 'message', ''),
\ 'type': 'E',
\})
if get(l:error, 'severity', 0) is# 1
let l:obj.type = 'W'
endif
if has_key(l:error, 'ruleId')
let l:code = l:error['ruleId']
" Sometimes ESLint returns null here
if !empty(l:code)
let l:obj.code = l:code
endif
endif
if has_key(l:error, 'column')
let l:obj.col = l:error['column']
endif
if has_key(l:error, 'endColumn')
let l:obj.end_col = l:error['endColumn'] - 1
endif
if has_key(l:error, 'endLine')
let l:obj.end_lnum = l:error['endLine']
endif
call add(l:output, l:obj)
endfor
return l:output
endfunction
let s:col_end_patterns = [
\ '\vParsing error: Unexpected token (.+) ?',
\ '\v''(.+)'' is not defined.',
\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
\ '\vUnexpected (console) statement',
\]
function! s:parseLines(buffer, lines) abort
" Matches patterns line the following:
"
" /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]
@@ -120,12 +162,6 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern])
let l:text = l:match[3]
if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
if l:text =~# '^File ignored'
continue
endif
endif
let l:obj = {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
@@ -152,9 +188,59 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
call add(l:output, l:obj)
endfor
return l:output
endfunction
function! s:FilterResult(buffer, obj) abort
if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
if a:obj.text =~# '^File ignored'
return 0
endif
endif
if has_key(a:obj, 'code') && a:obj.code is# 'no-trailing-spaces'
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
return 0
endif
return 1
endfunction
function! s:HandleESLintOutput(buffer, lines, type) abort
if s:CheckForBadConfig(a:buffer, a:lines)
return [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(a:lines, "\n"),
\}]
endif
if a:lines == ['Could not connect']
return [{
\ 'lnum': 1,
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
\}]
endif
if a:type is# 'json'
let l:output = s:parseJSON(a:buffer, a:lines)
else
let l:output = s:parseLines(a:buffer, a:lines)
endif
call filter(l:output, {idx, obj -> s:FilterResult(a:buffer, obj)})
if expand('#' . a:buffer . ':t') =~? '\.tsx\?$'
call s:AddHintsForTypeScriptParsingErrors(l:output)
endif
return l:output
endfunction
function! ale#handlers#eslint#HandleJSON(buffer, lines) abort
return s:HandleESLintOutput(a:buffer, a:lines, 'json')
endfunction
function! ale#handlers#eslint#Handle(buffer, lines) abort
return s:HandleESLintOutput(a:buffer, a:lines, 'lines')
endfunction

View File

@@ -0,0 +1,52 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs http://fecs.baidu.com/
call ale#Set('javascript_fecs_executable', 'fecs')
call ale#Set('javascript_fecs_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale#handlers#fecs#GetCommand(buffer) abort
return '%e check --colors=false --rule=true %t'
endfunction
function! ale#handlers#fecs#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_fecs', [
\ 'node_modules/.bin/fecs',
\ 'node_modules/fecs/bin/fecs',
\])
endfunction
function! ale#handlers#fecs#Handle(buffer, lines) abort
" Matches patterns looking like the following
"
" fecs WARN → line 20, col 25: Unexpected console statement. (no-console)
" fecs ERROR → line 24, col 36: Missing radix parameter. (radix)
"
let l:pattern = '\v^.*(WARN|ERROR)\s+→\s+line (\d+),\s+col\s+(\d+):\s+(.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:obj = {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4]
\}
let l:code_match = matchlist(l:match[4], '\v^(.{-})\s*\((.+)\)$')
if !empty(l:code_match)
let l:obj.code = l:code_match[2]
let l:obj.text = l:code_match[1]
endif
if l:match[1] is# 'WARN'
let l:obj.type = 'W'
elseif l:match[1] is# 'ERROR'
let l:obj.type = 'E'
endif
call add(l:output, l:obj)
endfor
return l:output
endfunction

View File

@@ -11,6 +11,7 @@ let s:pragma_error = '#pragma once in main file'
" <stdin>:10:27: error: invalid operands to binary - (have int and char *)
" -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$'
let s:inline_pattern = '\v inlined from .* at \<stdin\>:(\d+):(\d+):$'
function! s:IsHeaderFile(filename) abort
return a:filename =~? '\v\.(h|hpp)$'
@@ -25,6 +26,28 @@ function! s:RemoveUnicodeQuotes(text) abort
return l:text
endfunction
function! s:ParseInlinedFunctionProblems(buffer, lines) abort
let l:output = []
let l:pos_match = []
for l:line in a:lines
let l:match = matchlist(l:line, s:pattern)
if !empty(l:match) && !empty(l:pos_match)
call add(l:output, {
\ 'lnum': str2nr(l:pos_match[1]),
\ 'col': str2nr(l:pos_match[2]),
\ 'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W',
\ 'text': s:RemoveUnicodeQuotes(l:match[5]),
\})
endif
let l:pos_match = matchlist(l:line, s:inline_pattern)
endfor
return l:output
endfunction
" Report problems inside of header files just for gcc and clang
function! s:ParseProblemsInHeaders(buffer, lines) abort
let l:output = []
@@ -129,6 +152,7 @@ endfunction
function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort
let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines)
call extend(l:output, s:ParseInlinedFunctionProblems(a:buffer, a:lines))
call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines))
return l:output

View File

@@ -56,14 +56,20 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort
endif
if !empty(l:span)
call add(l:output, {
let l:output_line = {
\ 'lnum': l:span.line_start,
\ 'end_lnum': l:span.line_end,
\ 'col': l:span.column_start,
\ 'end_col': l:span.column_end-1,
\ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label),
\ 'type': toupper(l:error.level[0]),
\})
\}
if has_key(l:error, 'rendered') && !empty(l:error.rendered)
let l:output_line.detail = l:error.rendered
endif
call add(l:output, l:output_line)
endif
endfor
endfor

View File

@@ -49,14 +49,33 @@ endfunction
" Given a loclist for current items to highlight, remove all highlights
" except these which have matching loclist item entries.
function! ale#highlight#RemoveHighlights() abort
for l:match in getmatches()
if l:match.group =~# '^ALE'
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
call matchdelete(l:match.id)
endif
endfor
endfunction
function! s:highlight_line(bufnr, lnum, group) abort
call matchaddpos(a:group, [a:lnum])
endfunction
function! s:highlight_range(bufnr, range, group) abort
" Set all of the positions, which are chunked into Lists which
" are as large as will be accepted by matchaddpos.
call map(
\ ale#highlight#CreatePositions(
\ a:range.lnum,
\ a:range.col,
\ a:range.end_lnum,
\ a:range.end_col
\ ),
\ 'matchaddpos(a:group, v:val)'
\)
endfunction
function! ale#highlight#UpdateHighlights() abort
let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled
\ ? get(b:, 'ale_highlight_items', [])
@@ -79,17 +98,14 @@ function! ale#highlight#UpdateHighlights() abort
let l:group = 'ALEError'
endif
let l:line = l:item.lnum
let l:col = l:item.col
let l:end_line = get(l:item, 'end_lnum', l:line)
let l:end_col = get(l:item, 'end_col', l:col)
let l:range = {
\ 'lnum': l:item.lnum,
\ 'col': l:item.col,
\ 'end_lnum': get(l:item, 'end_lnum', l:item.lnum),
\ 'end_col': get(l:item, 'end_col', l:item.col)
\}
" Set all of the positions, which are chunked into Lists which
" are as large as will be accepted by matchaddpos.
call map(
\ ale#highlight#CreatePositions(l:line, l:col, l:end_line, l:end_col),
\ 'matchaddpos(l:group, v:val)'
\)
call s:highlight_range(l:item.bufnr, l:range, l:group)
endfor
" If highlights are enabled and signs are not enabled, we should still
@@ -111,7 +127,7 @@ function! ale#highlight#UpdateHighlights() abort
endif
if l:available_groups[l:group]
call matchaddpos(l:group, [l:item.lnum])
call s:highlight_line(l:item.bufnr, l:item.lnum, l:group)
endif
endfor
endif

View File

@@ -16,5 +16,11 @@ function! ale#java#FindProjectRoot(buffer) abort
return fnamemodify(l:maven_pom_file, ':h')
endif
let l:ant_root = ale#ant#FindProjectRoot(a:buffer)
if !empty(l:ant_root)
return l:ant_root
endif
return ''
endfunction

View File

@@ -13,10 +13,13 @@ let s:default_ale_linter_aliases = {
\ 'Dockerfile': 'dockerfile',
\ 'csh': 'sh',
\ 'plaintex': 'tex',
\ 'rmarkdown': 'r',
\ 'systemverilog': 'verilog',
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
\ 'vimwiki': 'markdown',
\ 'vue': ['vue', 'javascript'],
\ 'xsd': ['xsd', 'xml'],
\ 'xslt': ['xslt', 'xml'],
\ 'zsh': 'sh',
\}
@@ -340,7 +343,7 @@ function! ale#linter#PreProcess(filetype, linter) abort
throw '`aliases` must be a List of String values'
endif
for l:key in filter(keys(l:obj), 'v:val[-9:] is# ''_callback'' || v:val is# ''command_chain''')
for l:key in filter(keys(a:linter), 'v:val[-9:] is# ''_callback'' || v:val is# ''command_chain''')
if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom l:key . '' is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
@@ -355,12 +358,14 @@ function! ale#linter#Define(filetype, linter) abort
" This command will throw from the sandbox.
let &l:equalprg=&l:equalprg
let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
if !has_key(s:linters, a:filetype)
let s:linters[a:filetype] = []
endif
let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
" Remove previously defined linters with the same name.
call filter(s:linters[a:filetype], 'v:val.name isnot# a:linter.name')
call add(s:linters[a:filetype], l:new_linter)
endfunction

View File

@@ -71,8 +71,8 @@ function! s:FixList(buffer, list) abort
return l:new_list
endfunction
function! s:BufWinId(buffer) abort
return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0
function! s:WinFindBuf(buffer) abort
return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0]
endfunction
function! s:SetListsImpl(timer_id, buffer, loclist) abort
@@ -88,17 +88,19 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
call setqflist([], 'r', {'title': l:title})
endif
elseif g:ale_set_loclist
" If windows support is off, bufwinid() may not exist.
" If windows support is off, win_findbuf() may not exist.
" We'll set result in the current window, which might not be correct,
" but it's better than nothing.
let l:id = s:BufWinId(a:buffer)
let l:ids = s:WinFindBuf(a:buffer)
if has('nvim')
call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
else
call setloclist(l:id, s:FixList(a:buffer, a:loclist))
call setloclist(l:id, [], 'r', {'title': l:title})
endif
for l:id in l:ids
if has('nvim')
call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
else
call setloclist(l:id, s:FixList(a:buffer, a:loclist))
call setloclist(l:id, [], 'r', {'title': l:title})
endif
endfor
endif
" Open a window to show the problems if we need to.
@@ -181,11 +183,13 @@ function! s:CloseWindowIfNeeded(buffer) abort
cclose
endif
else
let l:win_id = s:BufWinId(a:buffer)
let l:win_ids = s:WinFindBuf(a:buffer)
if g:ale_set_loclist && empty(getloclist(l:win_id))
lclose
endif
for l:win_id in l:win_ids
if g:ale_set_loclist && empty(getloclist(l:win_id))
lclose
endif
endfor
endif
" Ignore 'Cannot close last window' errors.
catch /E444/

View File

@@ -111,7 +111,7 @@ function! ale#loclist_jumping#Jump(direction, ...) abort
if !empty(l:nearest)
normal! m`
call cursor(l:nearest)
call cursor([l:nearest[0], max([l:nearest[1], 1])])
endif
endfunction

View File

@@ -321,7 +321,69 @@ endfunction
function! s:SendInitMessage(conn) abort
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
\ ale#lsp#message#Initialize(a:conn.root, a:conn.init_options),
\ ale#lsp#message#Initialize(
\ a:conn.root,
\ a:conn.init_options,
\ {
\ 'workspace': {
\ 'applyEdit': v:false,
\ 'didChangeConfiguration': {
\ 'dynamicRegistration': v:false,
\ },
\ 'symbol': {
\ 'dynamicRegistration': v:false,
\ },
\ 'workspaceFolders': v:false,
\ 'configuration': v:false,
\ },
\ 'textDocument': {
\ 'synchronization': {
\ 'dynamicRegistration': v:false,
\ 'willSave': v:false,
\ 'willSaveWaitUntil': v:false,
\ 'didSave': v:true,
\ },
\ 'completion': {
\ 'dynamicRegistration': v:false,
\ 'completionItem': {
\ 'snippetSupport': v:false,
\ 'commitCharactersSupport': v:false,
\ 'documentationFormat': ['plaintext'],
\ 'deprecatedSupport': v:false,
\ 'preselectSupport': v:false,
\ },
\ 'contextSupport': v:false,
\ },
\ 'hover': {
\ 'dynamicRegistration': v:false,
\ 'contentFormat': ['plaintext'],
\ },
\ 'references': {
\ 'dynamicRegistration': v:false,
\ },
\ 'documentSymbol': {
\ 'dynamicRegistration': v:false,
\ 'hierarchicalDocumentSymbolSupport': v:false,
\ },
\ 'definition': {
\ 'dynamicRegistration': v:false,
\ 'linkSupport': v:false,
\ },
\ 'typeDefinition': {
\ 'dynamicRegistration': v:false,
\ },
\ 'publishDiagnostics': {
\ 'relatedInformation': v:true,
\ },
\ 'codeAction': {
\ 'dynamicRegistration': v:false,
\ },
\ 'rename': {
\ 'dynamicRegistration': v:false,
\ },
\ },
\ },
\ ),
\)
let a:conn.init_request_id = l:init_id
call s:SendMessageData(a:conn, l:init_data)
@@ -484,6 +546,35 @@ function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort
return l:opened
endfunction
" Notify LSP servers or tsserver that a document is closed, if opened before.
" If a document is closed, 1 will be returned, otherwise 0 will be returned.
"
" Only the buffer number is required here. A message will be sent to every
" language server that was notified previously of the document being opened.
function! ale#lsp#CloseDocument(buffer) abort
let l:closed = 0
" The connection keys are sorted so the messages are easier to test, and
" so messages are sent in a consistent order.
for l:conn_id in sort(keys(s:connections))
let l:conn = s:connections[l:conn_id]
if l:conn.initialized && has_key(l:conn.open_documents, a:buffer)
if l:conn.is_tsserver
let l:message = ale#lsp#tsserver_message#Close(a:buffer)
else
let l:message = ale#lsp#message#DidClose(a:buffer)
endif
call ale#lsp#Send(l:conn_id, l:message)
call remove(l:conn.open_documents, a:buffer)
let l:closed = 1
endif
endfor
return l:closed
endfunction
" Notify LSP servers or tsserver that a document has changed, if needed.
" If a notification is sent, 1 will be returned, otherwise 0 will be returned.
function! ale#lsp#NotifyForChanges(conn_id, buffer) abort

View File

@@ -28,14 +28,13 @@ function! ale#lsp#message#GetNextVersionID() abort
return l:id
endfunction
function! ale#lsp#message#Initialize(root_path, initialization_options) abort
" TODO: Define needed capabilities.
function! ale#lsp#message#Initialize(root_path, options, capabilities) abort
" NOTE: rootPath is deprecated in favour of rootUri
return [0, 'initialize', {
\ 'processId': getpid(),
\ 'rootPath': a:root_path,
\ 'capabilities': {},
\ 'initializationOptions': a:initialization_options,
\ 'capabilities': a:capabilities,
\ 'initializationOptions': a:options,
\ 'rootUri': ale#path#ToURI(a:root_path),
\}]
endfunction

View File

@@ -28,7 +28,7 @@ function! ale#lsp#response#ReadDiagnostics(response) abort
for l:diagnostic in a:response.params.diagnostics
let l:severity = get(l:diagnostic, 'severity', 0)
let l:loclist_item = {
\ 'text': l:diagnostic.message,
\ 'text': substitute(l:diagnostic.message, '\(\r\n\|\n\|\r\)', ' ', 'g'),
\ 'type': 'E',
\ 'lnum': l:diagnostic.range.start.line + 1,
\ 'col': l:diagnostic.range.start.character + 1,
@@ -90,7 +90,7 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
\ 'lnum': l:diagnostic.start.line,
\ 'col': l:diagnostic.start.offset,
\ 'end_lnum': l:diagnostic.end.line,
\ 'end_col': l:diagnostic.end.offset,
\ 'end_col': l:diagnostic.end.offset - 1,
\}
if has_key(l:diagnostic, 'code')

View File

@@ -8,8 +8,16 @@ if !has_key(s:, 'lsp_linter_map')
let s:lsp_linter_map = {}
endif
" A Dictionary to track one-shot handlers for custom LSP requests
let s:custom_handlers_map = get(s:, 'custom_handlers_map', {})
" Check if diagnostics for a particular linter should be ignored.
function! s:ShouldIgnore(buffer, linter_name) abort
" Ignore all diagnostics if LSP integration is disabled.
if ale#Var(a:buffer, 'disable_lsp')
return 1
endif
let l:config = ale#Var(a:buffer, 'linters_ignore')
" Don't load code for ignoring diagnostics if there's nothing to ignore.
@@ -26,13 +34,14 @@ endfunction
function! s:HandleLSPDiagnostics(conn_id, response) abort
let l:linter_name = s:lsp_linter_map[a:conn_id]
let l:filename = ale#path#FromURI(a:response.params.uri)
let l:buffer = bufnr(l:filename)
let l:buffer = bufnr('^' . l:filename . '$')
let l:info = get(g:ale_buffer_info, l:buffer, {})
if s:ShouldIgnore(l:buffer, l:linter_name)
if empty(l:info)
return
endif
if l:buffer <= 0
if s:ShouldIgnore(l:buffer, l:linter_name)
return
endif
@@ -43,13 +52,15 @@ endfunction
function! s:HandleTSServerDiagnostics(response, error_type) abort
let l:linter_name = 'tsserver'
let l:buffer = bufnr(a:response.body.file)
let l:buffer = bufnr('^' . a:response.body.file . '$')
let l:info = get(g:ale_buffer_info, l:buffer, {})
if empty(l:info)
return
endif
call ale#engine#MarkLinterInactive(l:info, l:linter_name)
if s:ShouldIgnore(l:buffer, l:linter_name)
return
endif
@@ -376,6 +387,10 @@ function! s:CheckWithLSP(linter, details) abort
if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
let l:notified = ale#lsp#Send(l:id, l:message) != 0
if l:notified
call ale#engine#MarkLinterActive(l:info, a:linter)
endif
else
let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer)
endif
@@ -386,10 +401,6 @@ function! s:CheckWithLSP(linter, details) abort
let l:save_message = ale#lsp#message#DidSave(l:buffer)
let l:notified = ale#lsp#Send(l:id, l:save_message) != 0
endif
if l:notified
call ale#engine#MarkLinterActive(l:info, a:linter)
endif
endfunction
function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
@@ -399,9 +410,57 @@ endfunction
" Clear LSP linter data for the linting engine.
function! ale#lsp_linter#ClearLSPData() abort
let s:lsp_linter_map = {}
let s:custom_handlers_map = {}
endfunction
" Just for tests.
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
let s:lsp_linter_map = a:replacement_map
endfunction
function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:custom_handlers_map, a:response.id)
let l:Handler = remove(s:custom_handlers_map, a:response.id)
call l:Handler(a:response)
endif
endfunction
function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
let l:id = a:lsp_details.connection_id
let l:request_id = ale#lsp#Send(l:id, a:args.message)
if l:request_id > 0 && has_key(a:args, 'handler')
let l:Callback = function('s:HandleLSPResponseToCustomRequests')
call ale#lsp#RegisterCallback(l:id, l:Callback)
let s:custom_handlers_map[l:request_id] = a:args.handler
endif
endfunction
" Send a custom request to an LSP linter.
function! ale#lsp_linter#SendRequest(buffer, linter_name, message, ...) abort
let l:filetype = ale#linter#ResolveFiletype(getbufvar(a:buffer, '&filetype'))
let l:linter_list = ale#linter#GetAll(l:filetype)
let l:linter_list = filter(l:linter_list, {_, v -> v.name is# a:linter_name})
if len(l:linter_list) < 1
throw 'Linter "' . a:linter_name . '" not found!'
endif
let l:linter = l:linter_list[0]
if empty(l:linter.lsp)
throw 'Linter "' . a:linter_name . '" does not support LSP!'
endif
let l:is_notification = a:message[0]
let l:callback_args = {'message': a:message}
if !l:is_notification && a:0
let l:callback_args.handler = a:1
endif
let l:Callback = function('s:OnReadyForCustomRequests', [l:callback_args])
return ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
endfunction

View File

@@ -3,13 +3,20 @@
" simplify a path, and fix annoying issues with paths on Windows.
"
" Forward slashes are changed to back slashes so path equality works better.
" Forward slashes are changed to back slashes so path equality works better
" on Windows. Back slashes are changed to forward slashes on Unix.
"
" Unix paths can technically contain back slashes, but in practice no path
" should, and replacing back slashes with forward slashes makes linters work
" in environments like MSYS.
"
" Paths starting with more than one forward slash are changed to only one
" forward slash, to prevent the paths being treated as special MSYS paths.
function! ale#path#Simplify(path) abort
if has('unix')
return substitute(simplify(a:path), '^//\+', '/', 'g') " no-custom-checks
let l:unix_path = substitute(a:path, '\\', '/', 'g')
return substitute(simplify(l:unix_path), '^//\+', '/', 'g') " no-custom-checks
endif
let l:win_path = substitute(a:path, '/', '\\', 'g')

View File

@@ -0,0 +1,32 @@
" Author: zigford <zigford@gmail.com>
" Description: Functions for integrating with Powershell linters.
" Write a powershell script to a temp file for execution
" return the command used to execute it
function! s:TemporaryPSScript(buffer, input) abort
let l:filename = 'script.ps1'
" Create a temp dir to house our temp .ps1 script
" a temp dir is needed as powershell needs the .ps1
" extension
let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
let l:tempscript = l:tempdir . l:filename
" Create the temporary directory for the file, unreadable by 'other'
" users.
call mkdir(l:tempdir, '', 0750)
" Automatically delete the directory later.
call ale#command#ManageDirectory(a:buffer, l:tempdir)
" Write the script input out to a file.
call ale#util#Writefile(a:buffer, a:input, l:tempscript)
return l:tempscript
endfunction
function! ale#powershell#RunPowerShell(buffer, base_var_name, command) abort
let l:executable = ale#Var(a:buffer, a:base_var_name . '_executable')
let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
return ale#Escape(l:executable)
\ . ' -Exe Bypass -NoProfile -File '
\ . ale#Escape(l:tempscript)
\ . ' %t'
endfunction

View File

@@ -25,7 +25,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
\|| filereadable(l:path . '/tox.ini')
\|| filereadable(l:path . '/mypy.ini')
\|| filereadable(l:path . '/pycodestyle.cfg')
\|| filereadable(l:path . '/flake8.cfg')
\|| filereadable(l:path . '/.flake8')
\|| filereadable(l:path . '/.flake8rc')
\|| filereadable(l:path . '/pylama.ini')
\|| filereadable(l:path . '/pylintrc')

View File

@@ -1,7 +1,7 @@
" Author: Eddie Lebow https://github.com/elebow
" Description: Functions for integrating with Ruby tools
" Find the nearest dir contining "app", "db", and "config", and assume it is
" Find the nearest dir containing "app", "db", and "config", and assume it is
" the root of a Rails app.
function! ale#ruby#FindRailsRoot(buffer) abort
for l:name in ['app', 'config', 'db']

View File

@@ -66,7 +66,7 @@ endif
" Spaces and backslashes need to be escaped for signs.
function! s:EscapeSignText(sign_text) abort
return substitute(a:sign_text, '\\\| ', '\\\0', 'g')
return substitute(substitute(a:sign_text, ' *$', '', ''), '\\\| ', '\\\0', 'g')
endfunction
" Signs show up on the left for error markers.

13
autoload/ale/swift.vim Normal file
View File

@@ -0,0 +1,13 @@
" Author: Dan Loman <https://github.com/namolnad>
" Description: Functions for integrating with Swift tools
" Find the nearest dir containing a Package.swift file and assume it is the root of the Swift project.
function! ale#swift#FindProjectRoot(buffer) abort
let l:swift_config = ale#path#FindNearestFile(a:buffer, 'Package.swift')
if !empty(l:swift_config)
return fnamemodify(l:swift_config, ':h')
endif
return ''
endfunction

View File

@@ -422,7 +422,7 @@ function! ale#util#Writefile(buffer, lines, filename) abort
\ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')')
\ : a:lines
call writefile(l:corrected_lines, a:filename) " no-custom-checks
call writefile(l:corrected_lines, a:filename, 'S') " no-custom-checks
endfunction
if !exists('s:patial_timers')

View File

@@ -81,7 +81,7 @@ function! ale#virtualtext#ShowCursorWarning(...) abort
call ale#virtualtext#Clear()
if !empty(l:loc)
let l:msg = get(l:loc, 'detail', l:loc.text)
let l:msg = l:loc.text
let l:hl_group = 'ALEVirtualTextInfo'
let l:type = get(l:loc, 'type', 'E')

View File

@@ -156,7 +156,7 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to clang-tidy.
This variable can be changed to modify compiler flags given to clang-tidy.
- Setting this variable to a non-empty string,
- and working in a buffer where no compilation database is found using
@@ -169,6 +169,14 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options*
of the |g:ale_c_build_dir_names| directories of the project tree.
g:ale_c_clangtidy_extra_options *g:ale_c_clangtidy_extra_options*
*b:ale_c_clangtidy_extra_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to clang-tidy.
===============================================================================
cppcheck *ale-c-cppcheck*

View File

@@ -2,6 +2,26 @@
ALE Chef Integration *ale-chef-options*
===============================================================================
cookstyle *ale-chef-cookstyle*
g:ale_chef_cookstyle_options *g:ale_chef_cookstyle_options*
*b:ale_chef_cookstyle_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to cookstyle.
g:ale_chef_cookstyle_executable *g:ale_chef_cookstyle_executable*
*b:ale_chef_cookstyle_executable*
Type: |String|
Default: `'cookstyle'`
This variable can be changed to point to the cookstyle binary in case it's
not on the $PATH or a specific version/path must be used.
===============================================================================
foodcritic *ale-chef-foodcritic*

View File

@@ -2,6 +2,13 @@
ALE Clojure Integration *ale-clojure-options*
===============================================================================
clj-kondo *ale-clojure-clj-kondo*
A minimal and opinionated linter for code that sparks joy.
https://github.com/borkdude/clj-kondo
===============================================================================
joker *ale-clojure-joker*

View File

@@ -125,7 +125,7 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to clang-tidy.
This variable can be changed to modify compiler flags given to clang-tidy.
- Setting this variable to a non-empty string,
- and working in a buffer where no compilation database is found using
@@ -138,6 +138,14 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options*
of the |g:ale_c_build_dir_names| directories of the project tree.
g:ale_cpp_clangtidy_extra_options *g:ale_cpp_clangtidy_extra_options*
*b:ale_cpp_clangtidy_extra_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to clang-tidy.
===============================================================================
clazy *ale-cpp-clazy*

View File

@@ -2,6 +2,14 @@
ALE CSS Integration *ale-css-options*
===============================================================================
fecs *ale-css-fecs*
`fecs` options for CSS is the same as the options for JavaScript, and both of
them reads `./.fecsrc` as the default configuration file. See:
|ale-javascript-fecs|.
===============================================================================
prettier *ale-css-prettier*

View File

@@ -151,9 +151,9 @@ ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE
runs tests with the following versions of Vim in the following environments.
1. Vim 8.0.0027 on Linux via Travis CI.
2. Vim 8.1.0204 on Linux via Travis CI.
2. Vim 8.1.0519 on Linux via Travis CI.
3. NeoVim 0.2.0 on Linux via Travis CI.
4. NeoVim 0.3.0 on Linux via Travis CI.
4. NeoVim 0.3.5 on Linux via Travis CI.
5. Vim 8 (stable builds) on Windows via AppVeyor.
If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs
@@ -351,6 +351,7 @@ given the above setup are as follows.
`GivenCommandOutput [...]` - Define output for ale#command#Run.
`AssertFixer results` - Check the fixer results
`AssertFixerNotExecuted` - Check that fixers will not be executed.
===============================================================================

View File

@@ -3,6 +3,35 @@ ALE Erlang Integration *ale-erlang-options*
===============================================================================
dialyzer *ale-erlang-dialyzer*
g:ale_erlang_dialyzer_executable *g:ale_erlang_dialyzer_executable*
*b:ale_erlang_dialyzer_executable*
Type: |String|
Default: `'dialyzer'`
This variable can be changed to specify the dialyzer executable.
g:ale_erlang_dialyzer_plt_file *g:ale_erlang_dialyzer_plt_file*
*b:ale_erlang_dialyzer_plt_file*
Type: |String|
This variable can be changed to specify the path to the PLT file. By
default, it will search for the PLT file inside the `_build` directory. If
there isn't one, it will fallback to the path `$REBAR_PLT_DIR/dialyzer/plt`.
Otherwise, it will default to `$HOME/.dialyzer_plt`.
g:ale_erlang_dialyzer_rebar3_profile *g:ale_erlang_dialyzer_rebar3_profile*
*b:ale_erlang_dialyzer_rebar3_profile*
Type: |String|
Default: `'default'`
This variable can be changed to specify the profile that is used to
run dialyzer with rebar3.
-------------------------------------------------------------------------------
erlc *ale-erlang-erlc*
g:ale_erlang_erlc_options *g:ale_erlang_erlc_options*

View File

@@ -30,6 +30,23 @@ g:ale_go_go_executable *g:ale_go_go_options*
the `gomod` fixer.
===============================================================================
bingo *ale-go-bingo*
g:ale_go_bingo_executable *g:ale_go_bingo_executable*
*b:ale_go_bingo_executable*
Type: |String|
Default: `'bingo'`
Location of the bingo binary file.
g:ale_go_bingo_options *g:ale_go_bingo_options*
*b:ale_go_bingo_options*
Type: |String|
Default: `''`
===============================================================================
gobuild *ale-go-gobuild*
@@ -53,6 +70,60 @@ g:ale_go_gofmt_options *g:ale_go_gofmt_options*
This variable can be set to pass additional options to the gofmt fixer.
===============================================================================
golangci-lint *ale-go-golangci-lint*
`golangci-lint` is a `lint_file` linter, which only lints files that are
written to disk. This differs from the default behavior of linting the buffer.
See: |ale-lint-file|
g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
*b:ale_go_golangci_lint_executable*
Type: |String|
Default: `'golangci-lint'`
The executable that will be run for golangci-lint.
g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
*b:ale_go_golangci_lint_options*
Type: |String|
Default: `'--enable-all'`
This variable can be changed to alter the command-line arguments to the
golangci-lint invocation.
g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
*b:ale_go_golangci_lint_package*
Type: |Number|
Default: `0`
When set to `1`, the whole Go package will be checked instead of only the
current file.
===============================================================================
golangserver *ale-go-golangserver*
g:ale_go_langserver_executable *g:ale_go_langserver_executable*
*b:ale_go_langserver_executable*
Type: |String|
Default: `'go-langserver'`
Location of the go-langserver binary file.
g:ale_go_langserver_options *g:ale_go_langserver_options*
*b:ale_go_langserver_options*
Type: |String|
Default: `''`
Additional options passed to the go-langserver command. Note that the
`-gocodecompletion` option is ignored because it is handled automatically
by the |g:ale_completion_enabled| variable.
===============================================================================
golint *ale-go-golint*
@@ -72,17 +143,6 @@ g:ale_go_golint_options *g:ale_go_golint_options*
This variable can be set to pass additional options to the golint linter.
===============================================================================
govet *ale-go-govet*
g:ale_go_govet_options *g:ale_go_govet_options*
*b:ale_go_govet_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the go vet linter.
===============================================================================
gometalinter *ale-go-gometalinter*
@@ -121,6 +181,34 @@ g:ale_go_gometalinter_lint_package *g:ale_go_gometalinter_lint_package*
current file.
===============================================================================
gopls *ale-go-gopls*
g:ale_go_gopls_executable *g:ale_go_gopls_executable*
*b:ale_go_gopls_executable*
Type: |String|
Default: `'gopls'`
Location of the gopls binary file.
g:ale_go_gopls_options *g:ale_go_gopls_options*
*b:ale_go_gopls_options*
Type: |String|
Default: `''`
===============================================================================
govet *ale-go-govet*
g:ale_go_govet_options *g:ale_go_govet_options*
*b:ale_go_govet_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the go vet linter.
===============================================================================
staticcheck *ale-go-staticcheck*
@@ -142,74 +230,5 @@ g:ale_go_staticcheck_lint_package *g:ale_go_staticcheck_lint_package*
current file.
===============================================================================
golangserver *ale-go-golangserver*
g:ale_go_langserver_executable *g:ale_go_langserver_executable*
*b:ale_go_langserver_executable*
Type: |String|
Default: `'go-langserver'`
Location of the go-langserver binary file.
g:ale_go_langserver_options *g:ale_go_langserver_options*
*b:ale_go_langserver_options*
Type: |String|
Default: `''`
Additional options passed to the go-langserver command. Note that the
`-gocodecompletion` option is ignored because it is handled automatically
by the |g:ale_completion_enabled| variable.
===============================================================================
golangci-lint *ale-go-golangci-lint*
`golangci-lint` is a `lint_file` linter, which only lints files that are
written to disk. This differs from the default behavior of linting the buffer.
See: |ale-lint-file|
g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
*b:ale_go_golangci_lint_executable*
Type: |String|
Default: `'golangci-lint'`
The executable that will be run for golangci-lint.
g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
*b:ale_go_golangci_lint_options*
Type: |String|
Default: `'--enable-all'`
This variable can be changed to alter the command-line arguments to the
golangci-lint invocation.
g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
*b:ale_go_golangci_lint_package*
Type: |Number|
Default: `0`
When set to `1`, the whole Go package will be checked instead of only the
current file.
===============================================================================
bingo *ale-go-bingo*
g:ale_go_bingo_executable *g:ale_go_bingo_executable*
*b:ale_go_bingo_executable*
Type: |String|
Default: `'go-bingo'`
Location of the go-bingo binary file.
g:ale_go_bingo_options *g:ale_go_bingo_options*
*b:ale_go_bingo_options*
Type: |String|
Default: `''`
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

Some files were not shown because too many files have changed in this diff Show More