Compare commits

...

143 Commits

Author SHA1 Message Date
w0rp
b24fd13423 Bump the ALE version 2019-10-16 17:23:31 +01:00
w0rp
7c5825ecbc Merge pull request #2803 from diegosouza/update_highest_phpstan_level
Update highest phpstan level
2019-10-14 16:18:10 +01:00
w0rp
01219f0308 Merge pull request #2810 from jmreicha/patch-2
Fix Powershell emoji
2019-10-14 16:16:02 +01:00
w0rp
af1643a948 Merge pull request #2829 from rcorre/fix-doc-example
Fix TCP server config example.
2019-10-14 16:15:35 +01:00
Ryan Roden-Corrent
5a1505ad62 Fix TCP server config example.
The docs for the `address` parameter of `Define` say:

> This argument must only be set if the `lsp` argument
> is set to `'socket'`.
2019-10-13 09:06:38 -04:00
w0rp
3fe2223a48 Fix #2800 - Ignore completion user data which is not a dictionary 2019-10-09 10:12:31 +01:00
w0rp
e8de12c9f0 Fix #2821 - Fix the debride linter after merging older code 2019-10-09 09:53:50 +01:00
Jérôme Foray
f932211309 fix tflint handler for 0.11+ (#2775)
* fix tflint handler for 0.11+
* fixup! fix tflint handler for 0.11+
* maintain compatibility with previous tflint output format
* fixup! maintain compatibility with previous tflint output format
* Add comment about tflint's output format accross versions
2019-10-07 20:14:22 +01:00
w0rp
6d88801789 Clarify that virtualtext is only in NeoVim 2019-10-07 20:03:59 +01:00
w0rp
59b34dd017 Merge pull request #2813 from werneta/master
Update vlog parser to handle new output format
2019-10-07 19:55:41 +01:00
w0rp
f2b231dd76 Merge pull request #2771 from gpanders/master
Use Makefile output with clang-tidy when useful
2019-10-07 19:34:52 +01:00
w0rp
8fda1cebff Merge pull request #2814 from andys8/improvement/elm-ls-name-fix-in-documentation
elm-ls: Removed some leftovers of previous name
2019-10-07 19:32:00 +01:00
w0rp
8097d51e33 Merge pull request #2750 from andys8/improvement/elm-language-server-elm-analyse-trigger-param
Elm language server params update
2019-10-07 19:30:59 +01:00
w0rp
06082ef377 Merge pull request #2735 from zoonfafer/scala-metals
Add linter for Scala Metals
2019-10-07 19:24:47 +01:00
w0rp
d3a3f4011b Merge pull request #2676 from davidtwco/nixfmt-fixer
Add nixpkgs-fmt fixer.
2019-10-07 19:22:01 +01:00
w0rp
cebbb67ea6 Merge pull request #2659 from greg0ire/psalm-language-server-option
Use the psalm executable with the LS option
2019-10-07 19:19:54 +01:00
w0rp
32b784219b Merge pull request #2694 from elebow/add-ruby-debride
Add ruby debride (closes #2471)
2019-10-07 19:17:55 +01:00
Greg Anders
7795898841 Add tests for clangtidy with Makefile 2019-10-06 10:29:23 -06:00
Greg Anders
06a97a8541 Use Makefile output with clang-tidy when useful
In the case where neither a build directory nor a compile_commands.json
file is found, use the output of `make -n` to provide options to
clang-tidy.
2019-10-06 10:29:17 -06:00
andys8
0fa2d18230 elm-ls: Removed some leftovers of previous name
Plugin name is `elm-ls`
Project page: <https://github.com/elm-tooling/elm-language-server>
2019-10-06 00:37:24 +02:00
Thomas A. Werne
d0e87c0df4 Correct vint-discovered advisory in vlog handler 2019-10-05 11:25:56 -07:00
Thomas A. Werne
89fa43551f Add test for new vlog format 2019-10-05 11:25:56 -07:00
Thomas A. Werne
98b0dcd7d6 Update vlog parser to handle new output format
Re #2812, the parser now takes a second pass through the output using an
updated regex.
2019-10-05 10:44:02 -07:00
Josh Reichardt
b96574e5b5 Fix Powershell emoji 2019-10-04 10:48:06 -07:00
w0rp
a486aa1d24 Merge pull request #2809 from hsanson/2802-fix-sign-group-parsing
Fix sign parser to be language independent.
2019-10-04 15:42:46 +01:00
Horacio Sanson
7c2f5e83ab Fix sign parser to be language independent. 2019-10-04 21:58:44 +09:00
Diego Mendes
889e6338fe highest phpstan level in doc updated 2019-10-02 09:22:04 -03:00
Horacio Sanson
41ff80dc9e 569 support vim sign group and priority (#2786)
* Use sign-group only on supported vim versions.

The sign-group feature is only available in nvim 0.4.0 and vim 8.1.614.

* Add priority to ALE signs.

This allows users to set a priority to ALE signs to take precedence over
other plugin signs.
2019-09-25 09:15:16 +01:00
w0rp
6746eaeaa0 Merge pull request #2683 from ahayworth/ahayworth-add-ink-lsp
Add support for ink-language-server
2019-09-22 13:07:19 +01:00
w0rp
d7dbc8f2cf Merge pull request #2719 from kevinywlui/patch-1
Remove texlab rust rewrite link
2019-09-22 12:41:12 +01:00
w0rp
e329413a31 Merge pull request #2667 from Chris-Slade/master
Edit ale-cs-csc docs to remove typos
2019-09-22 12:37:00 +01:00
w0rp
e6241ee0d2 Merge pull request #2784 from hsanson/2733-add-semistandard-executable-to-path-search
Add semistandard to node_modules search.
2019-09-22 11:36:53 +01:00
Horacio Sanson
07c11e4e7f Add semistandard to node_modules search. 2019-09-22 09:11:21 +09:00
w0rp
ab8e043353 Merge pull request #2691 from elebow/mdl-use-json-output
mdl: Use JSON output instead of parsing text
2019-09-20 20:59:59 +01:00
w0rp
e6946de98a Merge pull request #2736 from zoonfafer/doc-typos
doc: Fix typos
2019-09-20 20:50:58 +01:00
w0rp
6ab264ff0f Close #2641 - Document how to add your own LSP linters 2019-09-20 20:38:37 +01:00
w0rp
d93512fe60 Fix #2744 - Make ALEFix work when only casing is changed 2019-09-20 19:02:21 +01:00
w0rp
7b38e97943 Merge pull request #2780 from jeremija/tsserver-autoimport-desc
Show description of autoimport action for tsserver
2019-09-20 09:30:52 +01:00
Jerko Steiner
f5e44415e8 Show description of autoimport action for tsserver 2019-09-20 13:11:16 +07:00
w0rp
e3784c4c4e Close #2764 - Support the new React filetypes with aliases 2019-09-19 20:48:37 +01:00
w0rp
b531a4e0b3 Merge pull request #2653 from AntoineGagne/bugfix/bugged-plt-detection
Fix bug with detection of the PLT in Erlang Dialyzer
2019-09-19 20:35:54 +01:00
w0rp
dd6bd6f0fe Fix #2711 - Fix writing to files on save 2019-09-19 20:32:33 +01:00
w0rp
529f57a66f Document and test solc 2019-09-19 20:26:24 +01:00
Mo Zhonghua
b8949aaac3 arguments needs to be handled for compile_commands.json in addition to command (#2123)
* c linter: compatible with compile_commands.json without command field
2019-09-19 20:20:37 +01:00
Karl Bartel
dc42c0f948 Add support for solc Solidity compiler (#2648)
* Add support for `solc` Solidity compiler
* Set default value for `solidity_solc_options`
* Add test for solc handler
2019-09-19 19:40:00 +01:00
w0rp
41ed10be4e Merge pull request #2770 from statquant/master
Adding linting for rmd filetype (duplicate of rmarkdown)
2019-09-19 19:29:38 +01:00
statquant
34431d885b Adding linting for rmd filetype (duplicate of rmarkdown) 2019-09-14 15:55:04 +01:00
w0rp
61cfb3fefb Merge pull request #2693 from elebow/chmod-remove-x
Remove +x bit from some files that don't need it.
2019-09-12 23:00:34 +01:00
w0rp
321ee6d26b Merge pull request #2738 from Joshuao95/patch-1
Update irrelevant JSCS site link
2019-09-12 22:59:20 +01:00
w0rp
58b7c281c5 Merge pull request #2696 from elebow/update-test-docs-for-linter-lists
Update test docs and output for linter tables checked
2019-09-12 22:57:44 +01:00
Cluas
a6c59faa0f feat: support sqlformat. (#2702)
* feat: support sqlformat.
2019-09-12 22:48:27 +01:00
Jerko Steiner
3e8c8d3ccb Add ALERename (tsserver & LSP), ALEOrganizeImports (tsserver) and auto import support (tsserver) (#2709)
This commit adds support for renaming symbols in tsserver and with LSP tools, and for organising imports with tsserver. Completion results for symbols that can be imported are now suggested if enabled for tsserver completion done via ALE.
2019-09-12 21:53:23 +01:00
w0rp
b66d202c1d Merge pull request #2695 from elebow/move-ruby-escape-executable
Move ale#handlers#ruby#EscapeExecutable to ale#ruby#EscapeExecutable
2019-09-12 21:29:41 +01:00
Samuel Roeca
05ba522c9a languagetools: stop auto-appending --autoDetect (#2616)
Options are now configurable for languagetools, and `--autoDetect` can be removed by changing the options.
2019-09-12 21:22:47 +01:00
w0rp
34f2943fdd Limit the branches for branch builds for AppVeyor 2019-09-12 20:59:44 +01:00
w0rp
84a455185c Limit the branches for Travis CI branch builds 2019-09-12 20:52:36 +01:00
w0rp
fbe7cea91c Merge pull request #2741 from zoonfafer/shell
linter/sh: Improve parsing of error messages in different locales
2019-09-12 20:41:49 +01:00
w0rp
cda46636f4 Fix #2760 - Ignore all errors for adding NeoVim highlights 2019-09-11 16:49:25 +01:00
theoremoon
2e323b529d dfmt support (#2662)
* Add support for `dfmt`
2019-09-10 20:54:14 +01:00
andys8
bd1f7e1420 Elm language server params update
* There is a new param 'elmAnalyseTrigger' (change|save|never)
* Empty path default to let the language server search for binary
2019-09-04 00:20:12 +02:00
w0rp
6e18c03d80 Make help text clearer for line number highlights 2019-09-01 14:09:17 +01:00
BlahGeek
9f814a8ce9 Add g:ale_sign_highlight_linenr (#2678)
* add g:ale_sign_highlight_linenr
* Fix tests. Change option default value
* Rename ale_sign_highlight_linenr to ale_sign_highlight_linenrs
* Default ale_sign_highlight_linenrs to 0
2019-09-01 14:03:54 +01:00
w0rp
67ee2b9586 Fix tests so they work with new NeoVim highlight code 2019-09-01 13:31:09 +01:00
w0rp
7d7ddf22d3 Merge pull request #2638 from frangio/nvim-highlight
Use Neovim API for highlights when available
2019-09-01 10:47:28 +01:00
Jeffrey Lau
2b12c8ccbf linter/sh: Improve parsing of error messages in different locales
Fixes #2687
2019-08-31 15:08:54 +08:00
Jeffrey Lau
5fcb24bb3e Add linter for Scala Metals
https://scalameta.org/metals/
2019-08-31 12:34:57 +08:00
Joshuao95
cf47bda024 Update irrelevant JSCS site link
jscs.info appears to have nothing to do with the linter, and just contains a blogpost about student debt.
This appears to be the closest to canonical site for the project (although it's now merged with ESLint I suppose some still use it?)
2019-08-29 17:05:38 +01:00
Jeffrey Lau
da262f40dd doc: Fix typos 2019-08-28 00:28:58 +08:00
David Wood
6aeb462171 Add nixpkgs-fmt fixer.
This commit adds a fixer for the Nix language, nixpkgs-fmt
(https://github.com/nix-community/nixpkgs-fmt).
2019-08-26 19:21:07 +01:00
Kevin Lui
442fb2d22f Remove texlab rust rewrite link
It seems like the texlab rust rewrite has completed so the link is now broken and not necessary.
2019-08-19 23:10:40 -07:00
Eddie Lebow
08a5bfcaa9 mdl: Use JSON output instead of parsing text
Also add test coverage for the mdl handler.
2019-08-18 23:28:32 -04:00
w0rp
73812c3e41 Merge remote-tracking branch 'AlexeiDrake/master' into bugfix/c-lsp-build-dir-settings 2019-08-18 18:29:59 +01:00
w0rp
91636cff06 Merge pull request #2677 from davidtwco/check-toc-test-failure
Remove `/bin/ls` assumption from check-toc test.
2019-08-18 16:26:14 +01:00
w0rp
d787369f37 Merge pull request #2701 from elebow/doc-elixir-linters-floppy_disk
Add 💾 to dialyxir and dogma
2019-08-18 16:22:46 +01:00
richyfish
c4bdf165ca Black fixer should include --pyi for files with .pyi extension (#2705)
* black fixer should include --pyi for files with .pyi extension
2019-08-18 15:45:15 +01:00
w0rp
ddb559b3be Merge pull request #2631 from timlag1305/feat/ada-gnatpp
Add gnatpp fixer for Ada
2019-08-18 15:37:51 +01:00
w0rp
ee62cc6898 Merge pull request #2706 from richyfish/2703_mypy_stderr
mypy linter capture stderr for error reporting in ALEInfo
2019-08-17 19:21:42 +01:00
Andre Souto
219fb5873c Keep cursor position on screen when opening/closing lists (#2632)
* Trying to keep win view from bouncing
* Adjusting when views are saved and restored
* Also restore view when closing quickfix
* Don't restore view when opening list vertically
2019-08-17 19:14:21 +01:00
fx-carton
b62e306222 Fix cflags parsing (#2510, #2265) (#2590)
* Parse CFLAGS that can be passed using a whitelist

I went through GCC's man page and selected flags that can safely be
passed to GCC and that can be useful to syntax checking. These include:

- -I/-i* include flags
- preprocessor flags such as -D
- -W* warning flags
- -O* optimization flags
- most -f options
- -m arch dependent options

* Fix CFLAGS tests: -Idir is now parsed to -I dir
* Added two tests for flags we want or don't want to pass.
* Also check for / in addition to s:sep
2019-08-17 19:08:14 +01:00
Donnie West
5388ff1d54 Add asyncomplete.vim Support (#2627) 2019-08-17 18:40:05 +01:00
Richard French
266fa1c0a4 mypy linter capture stderr for error reporting in ALEInfo 2019-08-15 16:36:11 +01:00
Eddie Lebow
b70eeaadb4 Add 💾 to dialyxir and dogma 2019-08-15 00:40:30 -04:00
Eddie Lebow
74a43755c6 Update test docs and output for linter tables checked
This makes some of the run-test output less misleading.

Also fix a minor shellcheck issue: "\*" and "\\*" are equivalent, but
the second one makes clear that the literal backslash is intentional.
2019-08-13 21:30:13 -04:00
Eddie Lebow
58e8d32d79 Move ale#handlers#ruby#EscapeExecutable to ale#ruby#EscapeExecutable
This function is generally applicable to Ruby, not just handling linter
output.
2019-08-13 01:52:13 -04:00
Eddie Lebow
8aa1578605 Correct copied typo in doc/ale-ruby 2019-08-13 01:48:18 -04:00
Eddie Lebow
501af8dd8b debride: Add debride linter (closes #2471) 2019-08-13 01:43:27 -04:00
Eddie Lebow
b1810b2752 Remove +x bit from some files that don't need it. 2019-08-13 00:28:31 -04:00
richyfish
28c93ab185 aleinfo global options (#2686)
* added omitted global variables which was breaking this test when run standalone
* invert logic for s:GetLinterVariables excluding disabled linters, so that linter global options can appear in output
* additional tests for s:GetLinterVariables for linter global options
2019-08-12 16:29:28 +01:00
Andrew Hayworth
ab0bf61512 Add support for ink-language-server
This commit add support for ink-language-server, which it does by
largely copying and pasting from the pure-language-server PR that was
merged recently.

The most interesting things to note are:
- ink-language-server is distributed upstream via npm, which is why we
  search through node_modules
- With some coaxing, it can be installed globally - which is why we
  search for a global binary.
- Ink is a funky language, and users will likely need to add
  initialization options.
- I am not incredibly familiar with vimscript; and I may not have done
  some of the buffer searching correctly.
2019-08-07 16:35:12 -05:00
David Wood
20cc6d3e05 Remove /bin/ls assumption.
On some systems, notably NixOS, there is no `/bin/ls` and thus this test
can fail unnecessarily on those systems. This commit uses
`/usr/bin/env ls` which resolves the issue.
2019-08-03 12:42:22 +01:00
w0rp
dd1e1025b8 Fix #2668 - Set g:ale_go_go111module 2019-08-02 09:09:10 +01:00
w0rp
3ae01ba249 Merge pull request #2430 from eliath/master
Support $GO111MODULE with Go tooling
2019-07-30 21:17:20 +01:00
Chris-Slade
9c7673e6c9 Edit ale-cs-csc docs
Edits the ale-cs-csc docs to remove typos, misspellings, and run-on
sentences.
2019-07-30 11:12:46 -04:00
w0rp
8f5ecf0120 Merge pull request #2646 from paulreimer/fixer-clangformat-use-assume-filename
Set --assume-filename for clangformat fixer
2019-07-30 08:21:21 +01:00
JINNOUCHI Yasushi
d1c56769b7 Add setting for numhl highlights (#2637)
* Add setting for numhl highlights
* Add doc for numhl feature
2019-07-29 22:08:33 +01:00
w0rp
b1230873b6 Merge pull request #2612 from andys8/feature/elm-language-server-update
Update elm-ls
2019-07-29 21:56:27 +01:00
w0rp
4fe7402e89 Update links to use the new GitHub organization 2019-07-29 21:10:41 +01:00
Grégoire Paris
e47c1965a6 Use the psalm executable with the LS option
This is the simplest way of getting the psalm language server to run
now.
2019-07-25 23:19:30 +02:00
Antoine Gagné
c675212ddd Fix bug with detection of the PLT
Previously, it did not detect the PLT inside the `_build` directory and
would always default to the default PLT or the one from the `kerl` tool.
2019-07-22 09:50:16 -04:00
Paul Reimer
d25711a516 Set --assume-filename for clangformat fixer 2019-07-19 07:57:10 -07:00
w0rp
aae6d30b1e Merge pull request #2618 from rustic-games/clippy-flags
Update Rust cargo linter to better integrate with Clippy
2019-07-14 15:16:15 +01:00
w0rp
bafa1c619d Merge pull request #2643 from delphinus/feature/update-deoplete-for-cpp
Add Deoplete's input_patterns for cpp
2019-07-14 15:05:00 +01:00
delphinus
240bb8abae Add Deoplete's input_patterns for cpp 2019-07-14 22:20:44 +09:00
w0rp
36a50111b9 Merge pull request #2601 from delphinus/feature/better-completion-for-deoplete
Show more candidates for Deoplete completion
2019-07-14 10:29:03 +01:00
Matthew Lanigan
abb38955d3 Add Sorbet ruby linter and fixer (#2614) 2019-07-13 17:37:48 +01:00
andys8
fa5aecc250 Elm-ls backward compatibility for previous naming
Previous name of `elm-language-server` was `elm-lsp`
2019-07-10 12:04:33 +02:00
Francisco Giordano
6e6ad2e430 Try to mock nvim api functions 2019-07-10 01:20:22 -03:00
Francisco Giordano
79dde5f0e5 Implement highlights using neovim API 2019-07-09 23:23:27 -03:00
w0rp
6c47d7fc35 Merge pull request #2606 from hsanson/fix-javalsp-executable-docs
Default executable for javalsp is empthy string.
2019-07-06 14:31:32 +01:00
Pete Beardmore
a5240009ba Fix incorrect re-selection (#2630)
ALE now only resets selections when needed, to prevent side effects.
2019-07-02 08:31:24 +01:00
hernot
46ab7c5904 Support csc, update mcsc (#2586)
* Added a new csc linter for C# code.
* More output is now handled for mcsc.
2019-07-02 08:18:17 +01:00
ObserverOfTime
8700586890 Add clangtidy fixer (#2548)
* Add clangtidy fixer
* Add extra_options to clangtidy fixer
* Also, use cpp variables in cpp filetypes
2019-07-02 08:11:10 +01:00
Tim Lagnese
221aceb6db Add gnatpp fixer for Ada 2019-07-01 20:50:02 -04:00
Elias Martinez Cohen
49db8210f6 Support $GO111MODULE with Go tooling
Allows the user to override $GO111MODULE environment variable through
ale options. This gives control over the default behavior of Go module
resolution.

Golang documentation:
https://github.com/golang/go/wiki/Modules#how-to-use-modules

Add `ale#Go#EnvString()` function to make it easy to add similar Go
environment variables in the future.

Use the new `EnvString` function in all available Go tools callbacks
& update tests

Also add test of linter command callback for `gofmt`
2019-07-01 11:04:33 -04:00
w0rp
89f7292138 Merge pull request #2625 from ericdwang/update-readme
Update README section about running linters on save
2019-06-30 18:17:19 +01:00
Eric Wang
6feeca793a Update README section about running linters on save
The default for `g:ale_lint_on_insert_leave` was recently changed to 1,
so it now needs to be explicitly set to 0 to run linters only when files
are saved.
2019-06-27 19:25:06 -07:00
Jean Mertz
53b0e6c37d support all cargo options for build/clippy 2019-06-25 11:22:36 +02:00
delphinus
a3521de64e Use input_patterns & add comments for updating it 2019-06-25 18:04:04 +09:00
Jean Mertz
e52388b8b1 support clippy options with -- 2019-06-24 19:47:49 +02:00
andys8
0843efc7a5 Update elm-ls
* elm_lsp is now elm_ls
* The binary published by @elm-tooling is elm-language-server

Updates tests, docs and adds more options to the plugin.
2019-06-21 20:10:23 +02:00
RyanSquared
65ba4b85ec Merge branch 'fix-small-doc-typo' 2019-06-21 04:16:42 -05:00
Horacio Sanson
bf0d0597cb Fix small doc typo 2019-06-20 08:51:45 +09:00
Jesse Harris
9ad8fd6a1b Handle powershell unexpected token with newline (#2588)
* Newline in unexpected token broke parser
* fixed test to properly capture regressions
* removed deprecated linter options for powershell
2019-06-19 23:35:10 +01:00
w0rp
d2c3141f26 Merge pull request #2600 from hsanson/add-javalsp-lsp-options-2
Add support for javalsp configuration options.
2019-06-19 23:32:06 +01:00
w0rp
418f8a6fed Merge pull request #2602 from lbonn/master
Update docs on default after recent changes
2019-06-19 16:18:41 +01:00
lbonn
9c48c584a9 Update docs on default after recent changes
`g:ale_lint_on_insert_leave` default has been changed from 0 to 1 in
168768b326
2019-06-19 13:32:11 +02:00
w0rp
38a55fa9fe Merge pull request #2599 from parkovski/cpp-autocomplete-trigger
Enable C++ autocompletion on '::' and '->'
2019-06-19 10:46:19 +01:00
delphinus
4e1c46947d Add & fix tests for added funcs 2019-06-19 15:34:53 +09:00
delphinus
e0f8304860 Add separated func for deoplete
Deoplete needs `get_complete_position` method and it has a different
signature. It already fetches the input string and attempts to detect
the position with `\k*` regexp patterns.
2019-06-19 15:08:24 +09:00
delphinus
f5a908bf99 Add input_pattern setting for deoplete
This option is used to determine if `min_pattern_length` is ignored.
In usual, it does not start completion when the matched input string is
shorter than `min_pattern_length`. But when the string matches
`input_pattern`, it starts completion even when ths string is `''`.
2019-06-19 15:08:24 +09:00
Horacio Sanson
f2e52b9432 Default executable for javalsp is empthy string.
This fixes documentation to match actual implementation.
2019-06-19 11:50:03 +09:00
Horacio Sanson
40bf6e6b5c Add support for javalsp configuration options.
This MR adds a new configuration variable `g:ale_java_javalsp_config`
that allows to configure external dependencies and class paths to the
language server.

The variable accepts a dictionary similar to the one supported by the
[vscode/settings.json](https://github.com/georgewfraser/java-language-server#settings)
file.

Deprecates: #2561
2019-06-19 11:38:23 +09:00
Parker Snell
c5a4bbf8b0 Enable C++ autocompletion on '::' and '->' 2019-06-18 18:02:44 -07:00
Drew Olson
1c71da5624 Add support for purescript language server (#2572)
* Add support for purescript language server
* Update naming
* Add purescript language server tests
2019-06-17 12:54:43 +01:00
w0rp
701c1e4f17 Merge pull request #2578 from andys8/patch-2
Elm: Update link to compiler repository
2019-06-17 12:48:01 +01:00
w0rp
15f23532b7 Merge pull request #2577 from hsanson/fix-checkstyle-defaults
Fix checkstyle default configuration.
2019-06-16 18:13:47 +01:00
w0rp
3acfa0813e Merge pull request #2591 from blahgeek/inc-deoplete-rank
Raise deoplete source rank to 1000
2019-06-16 17:29:26 +01:00
BlahGeek
e0871be22b Raise deoplete source rank to 1000 2019-06-15 16:00:17 +08:00
w0rp
6e28eec243 Merge pull request #2563 from dcyriller/fixer-prettier-glimmer
prettier: Support experimental languages (Handlebars)
2019-06-13 11:08:21 +01:00
Cyrille David
86205967ea Refactor to be less verbose 2019-06-13 10:36:51 +02:00
Horacio Sanson
eb6a7b7516 Fix checkstyle default configuration.
Checkstyle xml configuration is mandatory and not providing one causes
the tool to fail with the following error:

    Must specify a config XML file.

Checkstyle itself contains a default configuration as part of its
assests named `/google_checks.xml`. Invoking checkstyle with this config
works even if such file does not exists in the file system:

    checkstyle -c /google_checks.xml

This should be the default invocation to allow ALE to use checkstyle
with zero configuration.

Also when a user sets `g:ale_java_checkstyle_config` option, ALE should
use it to invoke checkstyle even such file does not exists in the
filesystem. This is because checkstyle is able to use configuration files
within JAR files defined in the CLASSPATH. The default `/google_checks.xml`
is an example of such configuration available within a JAR resource.
2019-06-12 10:53:28 +09:00
Andy
0135fb3ad3 Elm: Update link to compiler repository 2019-06-11 18:14:57 +02:00
Cyrille David
3e4b8ea466 prettier: Support experimental languages
Such as handlebars
2019-06-06 22:04:32 +02:00
201 changed files with 5513 additions and 547 deletions

View File

@@ -5,6 +5,11 @@ clone_depth: 10
# Use the directory C:\testplugin so test directories will mostly work.
clone_folder: C:\testplugin
branches:
only:
- master
- /v\d+\.\d+\.(x|\d+)/
# Cache the vim and vader directories between builds.
cache:
- C:\vim -> .appveyor.yml

View File

@@ -3,6 +3,10 @@ sudo: required
services:
- docker
language: generic
branches:
only:
- master
- /^v\d+\.\d+\.(x|\d+)$/
env:
- OPTIONS=--vim-80-only
- OPTIONS=--vim-81-only

View File

@@ -1,4 +1,4 @@
# 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)
# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.com/dense-analysis/ale.svg?branch=master)](https://travis-ci.com/dense-analysis/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/dense-analysis/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/](https://user-images.githubusercontent.com/3518142/59195920-2c339500-8b85-11e9-9c22-f6b7f69637b8.jpg)
@@ -189,6 +189,14 @@ completion manually with `<C-x><C-o>`.
set omnifunc=ale#completion#OmniFunc
```
When working with TypeScript files, ALE supports automatic imports from
external modules. This behavior is disabled by default and can be enabled by
setting:
```vim
let g:ale_completion_tsserver_autoimport = 1
```
See `:help ale-completion` for more information.
<a name="usage-go-to-definition"></a>
@@ -258,14 +266,14 @@ any other tools. Simply clone the plugin into your `pack` directory.
```bash
mkdir -p ~/.vim/pack/git-plugins/start
git clone --depth 1 https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale
git clone --depth 1 https://github.com/dense-analysis/ale.git ~/.vim/pack/git-plugins/start/ale
```
#### NeoVim on Unix
```bash
mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start
git clone --depth 1 https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
git clone --depth 1 https://github.com/dense-analysis/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
```
#### Vim 8 on Windows
@@ -273,7 +281,7 @@ git clone --depth 1 https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pac
```bash
# Run these commands in the "Git for Windows" Bash terminal
mkdir -p ~/vimfiles/pack/git-plugins/start
git clone --depth 1 https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale
git clone --depth 1 https://github.com/dense-analysis/ale.git ~/vimfiles/pack/git-plugins/start/ale
```
#### Generating Vim help files
@@ -304,7 +312,7 @@ You can run the following commands in your terminal to do so:
```bash
cd ~/.vim/bundle
git clone https://github.com/w0rp/ale.git
git clone https://github.com/dense-analysis/ale.git
```
<a name="installation-with-vundle"></a>
@@ -315,7 +323,7 @@ You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.v
by using the path on GitHub for this repository.
```vim
Plugin 'w0rp/ale'
Plugin 'dense-analysis/ale'
```
See the Vundle documentation for more information.
@@ -329,7 +337,7 @@ by adding the GitHub path for this repository to your `~/.vimrc`
and running `:PlugInstall`.
```vim
Plug 'w0rp/ale'
Plug 'dense-analysis/ale'
```
<a name="contributing"></a>
@@ -337,14 +345,14 @@ Plug 'w0rp/ale'
## 4. Contributing
If you would like to see support for more languages and tools, please
[create an issue](https://github.com/w0rp/ale/issues)
or [create a pull request](https://github.com/w0rp/ale/pulls).
[create an issue](https://github.com/dense-analysis/ale/issues)
or [create a pull request](https://github.com/dense-analysis/ale/pulls).
If your tool can read from stdin or you have code to suggest which is good,
support can be happily added for it.
If you are interested in the general direction of the project, check out the
[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a
Roadmap for the future, and more.
[wiki home page](https://github.com/dense-analysis/ale/wiki). The wiki includes
a Roadmap for the future, and more.
If you'd liked to discuss the project more directly, check out the `#vim-ale` channel
on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels=vim-ale).
@@ -596,6 +604,7 @@ options off.
```vim
" Write this in your vimrc file
let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_insert_leave = 0
" You can disable this option too
" if you don't want linters to run on opening a file
let g:ale_lint_on_enter = 0

View File

@@ -19,14 +19,17 @@ call ale#Set('c_clangtidy_options', '')
call ale#Set('c_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
function! ale_linters#c#clangtidy#GetCommand(buffer, output) abort
let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',')
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = ''
" Get the extra options if we couldn't find a build directory.
let l:options = empty(l:build_dir)
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
\ : ''
if empty(l:build_dir)
let l:options = ale#Var(a:buffer, 'c_clangtidy_options')
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
endif
" Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
@@ -43,7 +46,7 @@ call ale#linter#Define('c', {
\ 'name': 'clangtidy',
\ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')},
\ 'command': function('ale_linters#c#clangtidy#GetCommand'),
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clangtidy#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

View File

@@ -13,14 +13,17 @@ call ale#Set('cpp_clangtidy_options', '')
call ale#Set('cpp_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort
let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',')
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = ''
" Get the extra options if we couldn't find a build directory.
let l:options = empty(l:build_dir)
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
\ : ''
if empty(l:build_dir)
let l:options = ale#Var(a:buffer, 'cpp_clangtidy_options')
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
endif
" Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
@@ -37,7 +40,7 @@ call ale#linter#Define('cpp', {
\ 'name': 'clangtidy',
\ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')},
\ 'command': function('ale_linters#cpp#clangtidy#GetCommand'),
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clangtidy#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

95
ale_linters/cs/csc.vim Normal file
View File

@@ -0,0 +1,95 @@
call ale#Set('cs_csc_options', '')
call ale#Set('cs_csc_source', '')
call ale#Set('cs_csc_assembly_path', [])
call ale#Set('cs_csc_assemblies', [])
function! s:GetWorkingDirectory(buffer) abort
let l:working_directory = ale#Var(a:buffer, 'cs_csc_source')
if !empty(l:working_directory)
return l:working_directory
endif
return expand('#' . a:buffer . ':p:h')
endfunction
function! ale_linters#cs#csc#GetCommand(buffer) abort
" Pass assembly paths via the -lib: parameter.
let l:path_list = ale#Var(a:buffer, 'cs_csc_assembly_path')
let l:lib_option = !empty(l:path_list)
\ ? '/lib:' . join(map(copy(l:path_list), 'ale#Escape(v:val)'), ',')
\ : ''
" Pass paths to DLL files via the -r: parameter.
let l:assembly_list = ale#Var(a:buffer, 'cs_csc_assemblies')
let l:r_option = !empty(l:assembly_list)
\ ? '/r:' . join(map(copy(l:assembly_list), 'ale#Escape(v:val)'), ',')
\ : ''
" register temporary module target file with ale
" register temporary module target file with ALE.
let l:out = ale#command#CreateFile(a:buffer)
" The code is compiled as a module and the output is redirected to a
" temporary file.
return ale#path#CdString(s:GetWorkingDirectory(a:buffer))
\ . 'csc /unsafe'
\ . ale#Pad(ale#Var(a:buffer, 'cs_csc_options'))
\ . ale#Pad(l:lib_option)
\ . ale#Pad(l:r_option)
\ . ' /out:' . l:out
\ . ' /t:module'
\ . ' /recurse:' . ale#Escape('*.cs')
endfunction
function! ale_linters#cs#csc#Handle(buffer, lines) abort
" Look for lines like the following.
"
" Tests.cs(12,29): error CSXXXX: ; expected
"
" NOTE: pattern also captures file name as linter compiles all
" files within the source tree rooted at the specified source
" path and not just the file loaded in the buffer
let l:patterns = [
\ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
\ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
\]
let l:output = []
let l:dir = s:GetWorkingDirectory(a:buffer)
for l:match in ale#util#GetMatches(a:lines, l:patterns)
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'type': l:match[4] is# 'error' ? 'E' : 'W',
\ 'code': l:match[5],
\ 'text': l:match[6] ,
\})
elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
call add(l:output, {
\ 'filename':'<csc>',
\ 'lnum': -1,
\ 'col': -1,
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
\ 'code': l:match[2],
\ 'text': l:match[3],
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('cs',{
\ 'name': 'csc',
\ 'output_stream': 'stdout',
\ 'executable': 'csc',
\ 'command': function('ale_linters#cs#csc#GetCommand'),
\ 'callback': 'ale_linters#cs#csc#Handle',
\ 'lint_file': 1
\})

View File

@@ -52,12 +52,16 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
" NOTE: pattern also captures file name as linter compiles all
" files within the source tree rooted at the specified source
" path and not just the file loaded in the buffer
let l:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$'
let l:patterns = [
\ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
\ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
\]
let l:output = []
let l:dir = s:GetWorkingDirectory(a:buffer)
for l:match in ale#util#GetMatches(a:lines, l:pattern)
for l:match in ale#util#GetMatches(a:lines, l:patterns)
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
@@ -66,6 +70,16 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
\ 'code': l:match[5],
\ 'text': l:match[6] ,
\})
elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
call add(l:output, {
\ 'filename':'<mcs>',
\ 'lnum': -1,
\ 'col': -1,
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
\ 'code': l:match[2],
\ 'text': l:match[3],
\})
endif
endfor
return l:output

View File

@@ -0,0 +1,40 @@
" Author: antew - https://github.com/antew
" Description: elm-language-server integration for elm (diagnostics, formatting, and more)
call ale#Set('elm_ls_executable', 'elm-language-server')
call ale#Set('elm_ls_use_global', get(g:, 'ale_use_global_executables', 1))
" elm-language-server will search for local and global binaries, if empty
call ale#Set('elm_ls_elm_path', '')
call ale#Set('elm_ls_elm_format_path', '')
call ale#Set('elm_ls_elm_test_path', '')
call ale#Set('elm_ls_elm_analyse_trigger', 'change')
function! elm_ls#GetRootDir(buffer) abort
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
endfunction
function! elm_ls#GetOptions(buffer) abort
return {
\ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'),
\ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'),
\ 'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'),
\ 'elmAnalyseTrigger': ale#Var(a:buffer, 'elm_ls_elm_analyse_trigger'),
\}
endfunction
call ale#linter#Define('elm', {
\ 'name': 'elm_ls',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#node#FindExecutable(b, 'elm_ls', [
\ 'node_modules/.bin/elm-language-server',
\ 'node_modules/.bin/elm-lsp',
\ 'elm-lsp'
\ ])},
\ 'command': '%e --stdio',
\ 'project_root': function('elm_ls#GetRootDir'),
\ 'language': 'elm',
\ 'initialization_options': function('elm_ls#GetOptions')
\})

View File

@@ -1,22 +0,0 @@
" Author: antew - https://github.com/antew
" Description: LSP integration for elm, currently supports diagnostics (linting)
call ale#Set('elm_lsp_executable', 'elm-lsp')
call ale#Set('elm_lsp_use_global', get(g:, 'ale_use_global_executables', 0))
function! elm_lsp#GetRootDir(buffer) abort
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
endfunction
call ale#linter#Define('elm', {
\ 'name': 'elm_lsp',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#node#FindExecutable(b, 'elm_lsp', [
\ 'node_modules/.bin/elm-lsp',
\ ])},
\ 'command': '%e --stdio',
\ 'project_root': function('elm_lsp#GetRootDir'),
\ 'language': 'elm'
\})

View File

@@ -15,10 +15,10 @@ 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)
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')
let l:plt_file = globpath(l:plt_file_directory, '*_plt', 0, 1)
endif
if !empty(l:plt_file)

View File

@@ -8,7 +8,7 @@ call ale#Set('eruby_ruumba_options', '')
function! ale_linters#eruby#ruumba#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'eruby_ruumba_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'ruumba')
return ale#ruby#EscapeExecutable(l:executable, 'ruumba')
\ . ' --format json --force-exclusion '
\ . ale#Var(a:buffer, 'eruby_ruumba_options')
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))

View File

@@ -5,11 +5,13 @@ call ale#Set('go_bingo_executable', 'bingo')
call ale#Set('go_bingo_options', '--mode stdio')
function! ale_linters#go#bingo#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
return ale#go#EnvString(a:buffer) . '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
endfunction
function! ale_linters#go#bingo#FindProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
let l:project_root = l:go_modules_off ?
\ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
let l:mods = ':h'
if empty(l:project_root)

View File

@@ -11,6 +11,7 @@ function! ale_linters#go#gobuild#GetCommand(buffer) abort
" Run go test in local directory with relative path
return ale#path#BufferCdString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . ale#Var(a:buffer, 'go_go_executable') . ' test'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -c -o /dev/null ./'

View File

@@ -1,10 +1,16 @@
" Author: neersighted <bjorn@neersighted.com>
" Description: gofmt for Go files
function! ale_linters#go#gofmt#GetCommand(buffer) abort
return ale#go#EnvString(a:buffer)
\ . '%e -e %t'
endfunction
call ale#linter#Define('go', {
\ 'name': 'gofmt',
\ 'output_stream': 'stderr',
\ 'executable': 'gofmt',
\ 'command': 'gofmt -e %t',
\ 'command': function('ale_linters#go#gofmt#GetCommand'),
\ 'callback': 'ale#handlers#unix#HandleAsError',
\})

View File

@@ -10,13 +10,16 @@ function! ale_linters#go#golangci_lint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_golangci_lint_options')
let l:lint_package = ale#Var(a:buffer, 'go_golangci_lint_package')
if l:lint_package
return ale#path#BufferCdString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . '%e run '
\ . l:options
endif
return ale#path#BufferCdString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . '%e run '
\ . ale#Escape(l:filename)
\ . ' ' . l:options

View File

@@ -7,7 +7,7 @@ call ale#Set('go_golint_options', '')
function! ale_linters#go#golint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_golint_options')
return '%e'
return ale#go#EnvString(a:buffer) . '%e'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t'
endfunction

View File

@@ -14,11 +14,13 @@ function! ale_linters#go#gometalinter#GetCommand(buffer) abort
" be calculated to absolute paths in the Handler
if l:lint_package
return ale#path#BufferCdString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . '%e'
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif
return ale#path#BufferCdString(a:buffer)
\ . ale#go#EnvString(a:buffer)
\ . '%e'
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename))
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'

View File

@@ -6,11 +6,15 @@ 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'))
return ale#go#EnvString(a:buffer)
\ . '%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:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
let l:project_root = l:go_modules_off ?
\ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
let l:mods = ':h'
if empty(l:project_root)

View File

@@ -2,7 +2,8 @@
" Description: gosimple for Go files
function! ale_linters#go#gosimple#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer) . ' gosimple .'
return ale#path#BufferCdString(a:buffer) . ' '
\ . ale#go#EnvString(a:buffer) . 'gosimple .'
endfunction
call ale#linter#Define('go', {

View File

@@ -6,7 +6,8 @@ function! ale_linters#go#gotype#GetCommand(buffer) abort
return ''
endif
return ale#path#BufferCdString(a:buffer) . ' gotype -e .'
return ale#path#BufferCdString(a:buffer) . ' '
\ . ale#go#EnvString(a:buffer) . 'gotype -e .'
endfunction
call ale#linter#Define('go', {

View File

@@ -11,6 +11,7 @@ function! ale_linters#go#govet#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_govet_options')
return ale#path#BufferCdString(a:buffer) . ' '
\ . ale#go#EnvString(a:buffer)
\ . ale#Var(a:buffer, 'go_go_executable') . ' vet '
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' .'

View File

@@ -15,8 +15,9 @@ function! ale_linters#go#langserver#GetCommand(buffer) abort
endif
let l:options = uniq(sort(l:options))
let l:env = ale#go#EnvString(a:buffer)
return join(extend(l:executable, l:options), ' ')
return l:env . join(extend(l:executable, l:options), ' ')
endfunction
call ale#linter#Define('go', {

View File

@@ -8,17 +8,18 @@ function! ale_linters#go#staticcheck#GetCommand(buffer) abort
let l:filename = expand('#' . a:buffer . ':t')
let l:options = ale#Var(a:buffer, 'go_staticcheck_options')
let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package')
let l:env = ale#go#EnvString(a:buffer)
" BufferCdString is used so that we can be sure the paths output from
" staticcheck can be calculated to absolute paths in the Handler
if l:lint_package
return ale#path#BufferCdString(a:buffer)
\ . 'staticcheck'
\ . l:env . 'staticcheck'
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif
return ale#path#BufferCdString(a:buffer)
\ . 'staticcheck'
\ . l:env . 'staticcheck'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' ' . ale#Escape(l:filename)
endfunction

35
ale_linters/ink/ls.vim Normal file
View File

@@ -0,0 +1,35 @@
" Author: Andreww Hayworth <ahayworth@gmail.com>
" Description: Integrate ALE with ink-language-server
call ale#Set('ink_ls_executable', 'ink-language-server')
call ale#Set('ink_ls_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('ink_ls_initialization_options', {})
function! ale_linters#ink#ls#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'ink_ls', [
\ 'ink-language-server',
\ 'node_modules/.bin/ink-language-server',
\])
endfunction
function! ale_linters#ink#ls#GetCommand(buffer) abort
let l:executable = ale_linters#ink#ls#GetExecutable(a:buffer)
return ale#Escape(l:executable) . ' --stdio'
endfunction
function! ale_linters#ink#ls#FindProjectRoot(buffer) abort
let l:main_file = get(ale#Var(a:buffer, 'ink_ls_initialization_options'), 'mainStoryPath', 'main.ink')
let l:config = ale#path#ResolveLocalPath(a:buffer, l:main_file, expand('#' . a:buffer . ':p'))
return ale#path#Dirname(l:config)
endfunction
call ale#linter#Define('ink', {
\ 'name': 'ink-language-server',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#ink#ls#GetExecutable'),
\ 'command': function('ale_linters#ink#ls#GetCommand'),
\ 'project_root': function('ale_linters#ink#ls#FindProjectRoot'),
\ 'initialization_options': {b -> ale#Var(b, 'ink_ls_initialization_options')},
\})

View File

@@ -2,7 +2,7 @@
" 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_config', '/google_checks.xml')
call ale#Set('java_checkstyle_options', '')
function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
@@ -39,11 +39,21 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
return l:output
endfunction
function! s:GetConfig(buffer, config) abort
if ale#path#IsAbsolute(a:config)
return a:config
endif
let s:file = ale#path#FindNearestFile(a:buffer, a:config)
return !empty(s:file) ? s:file : a:config
endfunction
function! ale_linters#java#checkstyle#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'java_checkstyle_options')
let l:config_option = ale#Var(a:buffer, 'java_checkstyle_config')
let l:config = l:options !~# '\v(^| )-c' && !empty(l:config_option)
\ ? ale#path#FindNearestFile(a:buffer, l:config_option)
\ ? s:GetConfig(a:buffer, l:config_option)
\ : ''
return '%e'

View File

@@ -2,11 +2,24 @@
" Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac
call ale#Set('java_javalsp_executable', '')
call ale#Set('java_javalsp_config', {})
function! ale_linters#java#javalsp#Executable(buffer) abort
return ale#Var(a:buffer, 'java_javalsp_executable')
endfunction
function! ale_linters#java#javalsp#Config(buffer) abort
let l:defaults = { 'java': { 'classPath': [], 'externalDependencies': [] } }
let l:config = ale#Var(a:buffer, 'java_javalsp_config')
" Ensure the config dictionary contains both classPath and
" externalDependencies keys to avoid a NPE crash on Java Language Server.
call extend(l:config, l:defaults, 'keep')
call extend(l:config['java'], l:defaults['java'], 'keep')
return l:config
endfunction
function! ale_linters#java#javalsp#Command(buffer) abort
let l:executable = ale_linters#java#javalsp#Executable(a:buffer)
@@ -38,4 +51,5 @@ call ale#linter#Define('java', {
\ 'command': function('ale_linters#java#javalsp#Command'),
\ 'language': 'java',
\ 'project_root': function('ale#java#FindProjectRoot'),
\ 'lsp_config': function('ale_linters#java#javalsp#Config')
\})

0
ale_linters/javascript/flow.vim Executable file → Normal file
View File

View File

@@ -8,6 +8,7 @@ call ale#Set('javascript_standard_options', '')
function! ale_linters#javascript#standard#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
\ 'node_modules/standard/bin/cmd.js',
\ 'node_modules/semistandard/bin/cmd.js',
\ 'node_modules/.bin/standard',
\])
endfunction

0
ale_linters/less/lessc.vim Executable file → Normal file
View File

View File

@@ -17,18 +17,17 @@ function! ale_linters#markdown#mdl#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'markdown_mdl_options')
return ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -j' . (!empty(l:options) ? ' ' . l:options : '')
endfunction
function! ale_linters#markdown#mdl#Handle(buffer, lines) abort
" matches: '(stdin):173: MD004 Unordered list style'
let l:pattern = ':\(\d*\): \(.*\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'text': l:match[2],
\ 'lnum': l:error['line'],
\ 'code': l:error['rule'] . '/' . join(l:error['aliases'], '/'),
\ 'text': l:error['description'],
\ 'type': 'W',
\})
endfor

View File

@@ -1,7 +1,7 @@
" Author: Matt Brown <https://github.com/muglug>
" Description: plugin for Psalm, static analyzer for PHP
call ale#Set('psalm_langserver_executable', 'psalm-language-server')
call ale#Set('psalm_langserver_executable', 'psalm')
call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#php#psalm#GetProjectRoot(buffer) abort
@@ -14,8 +14,8 @@ call ale#linter#Define('php', {
\ 'name': 'psalm',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#node#FindExecutable(b, 'psalm_langserver', [
\ 'vendor/bin/psalm-language-server',
\ 'vendor/bin/psalm',
\ ])},
\ 'command': '%e',
\ 'command': '%e --language-server',
\ 'project_root': function('ale_linters#php#psalm#GetProjectRoot'),
\})

12
ale_linters/powershell/powershell.vim Executable file → Normal file
View File

@@ -49,11 +49,19 @@ function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
let l:matchcount = 1
endif
" If the match is 0, it was a failed match
" probably due to an unexpected token which
" contained a newline. Reset matchcount. to
" continue to the next match
if !empty(l:match[1])
let l:item = {
\ 'lnum': str2nr(l:match[1]),
\ 'col': str2nr(l:match[2]),
\ 'type': 'E',
\}
else
let l:matchcount = 0
endif
elseif l:matchcount == 2
" Second match[0] grabs the full line in order
" to handles the text
@@ -84,8 +92,8 @@ endfunction
call ale#linter#Define('powershell', {
\ 'name': 'powershell',
\ 'executable_callback': 'ale_linters#powershell#powershell#GetExecutable',
\ 'command_callback': 'ale_linters#powershell#powershell#GetCommand',
\ 'executable': function('ale_linters#powershell#powershell#GetExecutable'),
\ 'command': function('ale_linters#powershell#powershell#GetCommand'),
\ 'output_stream': 'stdout',
\ 'callback': 'ale_linters#powershell#powershell#Handle',
\})

View File

@@ -0,0 +1,49 @@
" Author: Drew Olson <drew@drewolson.org>
" Description: Integrate ALE with purescript-language-server.
call ale#Set('purescript_ls_executable', 'purescript-language-server')
call ale#Set('purescript_ls_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('purescript_ls_config', {})
function! ale_linters#purescript#ls#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'purescript_ls', [
\ 'node_modules/.bin/purescript-language-server',
\])
endfunction
function! ale_linters#purescript#ls#GetCommand(buffer) abort
let l:executable = ale_linters#purescript#ls#GetExecutable(a:buffer)
return ale#Escape(l:executable) . ' --stdio'
endfunction
function! ale_linters#purescript#ls#FindProjectRoot(buffer) abort
let l:config = ale#path#FindNearestFile(a:buffer, 'bower.json')
if !empty(l:config)
return fnamemodify(l:config, ':h')
endif
let l:config = ale#path#FindNearestFile(a:buffer, 'psc-package.json')
if !empty(l:config)
return fnamemodify(l:config, ':h')
endif
let l:config = ale#path#FindNearestFile(a:buffer, 'spago.dhall')
if !empty(l:config)
return fnamemodify(l:config, ':h')
endif
return ''
endfunction
call ale#linter#Define('purescript', {
\ 'name': 'purescript-language-server',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#purescript#ls#GetExecutable'),
\ 'command': function('ale_linters#purescript#ls#GetCommand'),
\ 'project_root': function('ale_linters#purescript#ls#FindProjectRoot'),
\ 'lsp_config': {b -> ale#Var(b, 'purescript_ls_config')},
\})

View File

@@ -78,4 +78,5 @@ call ale#linter#Define('python', {
\ 'executable': function('ale_linters#python#mypy#GetExecutable'),
\ 'command': function('ale_linters#python#mypy#GetCommand'),
\ 'callback': 'ale_linters#python#mypy#Handle',
\ 'output_stream': 'both'
\})

View File

@@ -36,7 +36,7 @@ function! ale_linters#ruby#brakeman#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_brakeman_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'brakeman')
return ale#ruby#EscapeExecutable(l:executable, 'brakeman')
\ . ' -f json -q '
\ . ale#Var(a:buffer, 'ruby_brakeman_options')
\ . ' -p ' . ale#Escape(l:rails_root)

View File

@@ -0,0 +1,42 @@
" Author: Eddie Lebow https://github.com/elebow
" Description: debride, a dead method detector for Ruby files
call ale#Set('ruby_debride_executable', 'debride')
call ale#Set('ruby_debride_options', '')
function! ale_linters#ruby#debride#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_debride_executable')
return ale#ruby#EscapeExecutable(l:executable, 'debride')
\ . ale#Var(a:buffer, 'ruby_debride_options')
\ . ' %s'
endfunction
function! ale_linters#ruby#debride#HandleOutput(buffer, lines) abort
let l:output = []
for l:line in a:lines
if l:line !~# '^ '
continue
endif
let l:elements = split(l:line)
let l:method_name = l:elements[0]
let l:lnum = split(l:elements[1], ':')[1]
call add(l:output, {
\ 'lnum': 0 + l:lnum,
\ 'text': 'Possible unused method: ' . l:method_name,
\ 'type': 'W',
\})
endfor
return l:output
endfunction
call ale#linter#Define('ruby', {
\ 'name': 'debride',
\ 'executable': {b -> ale#Var(b, 'ruby_debride_executable')},
\ 'command': function('ale_linters#ruby#debride#GetCommand'),
\ 'callback': 'ale_linters#ruby#debride#HandleOutput',
\})

View File

@@ -33,7 +33,7 @@ function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort
let l:output_file = has('win32') ? '%t ' : '/dev/stdout '
let l:cat_file = has('win32') ? '; type %t' : ''
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
return ale#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
\ . ' --silent -f json --output-file ' . l:output_file
\ . ale#Var(a:buffer, 'ruby_rails_best_practices_options')
\ . ale#Escape(l:rails_root)

View File

@@ -14,7 +14,7 @@ function! ale_linters#ruby#reek#GetCommand(buffer, version) abort
\ ? ' --stdin-filename %s'
\ : ''
return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek')
return ale#ruby#EscapeExecutable(l:executable, 'reek')
\ . ' -f json --no-progress --no-color --force-exclusion'
\ . l:display_name_args
endfunction

View File

@@ -7,7 +7,7 @@ call ale#Set('ruby_rubocop_options', '')
function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop')
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
\ . ' --format json --force-exclusion '
\ . ale#Var(a:buffer, 'ruby_rubocop_options')
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))

View File

@@ -0,0 +1,23 @@
call ale#Set('ruby_sorbet_executable', 'srb')
call ale#Set('ruby_sorbet_options', '')
function! ale_linters#ruby#sorbet#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
return ale#ruby#EscapeExecutable(l:executable, 'srb')
\ . ' tc'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --lsp --disable-watchman'
endfunction
call ale#linter#Define('ruby', {
\ 'name': 'sorbet',
\ 'aliases': ['srb'],
\ 'lsp': 'stdio',
\ 'language': 'ruby',
\ 'executable': {b -> ale#Var(b, 'ruby_sorbet_executable')},
\ 'command': function('ale_linters#ruby#sorbet#GetCommand'),
\ 'project_root': function('ale#ruby#FindProjectRoot')
\})

View File

@@ -8,7 +8,7 @@ call ale#Set('ruby_standardrb_options', '')
function! ale_linters#ruby#standardrb#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_standardrb_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb')
return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
\ . ' --format json --force-exclusion '
\ . ale#Var(a:buffer, 'ruby_standardrb_options')
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))

View File

@@ -25,14 +25,11 @@ endfunction
function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
\ && ale#semver#GTE(a:version, [0, 17, 0])
let l:use_all_targets = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
let l:use_all_targets = ale#Var(a:buffer, 'rust_cargo_check_all_targets')
\ && ale#semver#GTE(a:version, [0, 22, 0])
let l:use_examples = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_examples')
let l:use_examples = ale#Var(a:buffer, 'rust_cargo_check_examples')
\ && ale#semver#GTE(a:version, [0, 22, 0])
let l:use_tests = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_tests')
let l:use_tests = ale#Var(a:buffer, 'rust_cargo_check_tests')
\ && ale#semver#GTE(a:version, [0, 22, 0])
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
@@ -69,7 +66,15 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
if ale#Var(a:buffer, 'rust_cargo_use_clippy')
let l:subcommand = 'clippy'
let l:clippy_options = ' ' . ale#Var(a:buffer, 'rust_cargo_clippy_options')
let l:clippy_options = ale#Var(a:buffer, 'rust_cargo_clippy_options')
if l:clippy_options =~# '^-- '
let l:clippy_options = join(split(l:clippy_options, '-- '))
endif
if l:clippy_options isnot# ''
let l:clippy_options = ' -- ' . l:clippy_options
endif
endif
return l:nearest_cargo_prefix . 'cargo '

View File

@@ -0,0 +1,48 @@
" Author: Jeffrey Lau - https://github.com/zoonfafer
" Description: Metals Language Server for Scala https://scalameta.org/metals/
call ale#Set('scala_metals_executable', 'metals-vim')
call ale#Set('scala_metals_project_root', '')
function! ale_linters#scala#metals#GetProjectRoot(buffer) abort
let l:project_root = ale#Var(a:buffer, 'scala_metals_project_root')
if !empty(l:project_root)
return l:project_root
endif
let l:potential_roots = [
\ 'build.sc',
\ 'build.sbt',
\ '.bloop',
\ '.metals',
\]
for l:root in l:potential_roots
let l:project_root = ale#path#ResolveLocalPath(
\ a:buffer,
\ l:root,
\ ''
\)
if !empty(l:project_root)
return fnamemodify(
\ l:project_root,
\ ':h',
\)
endif
endfor
endfunction
function! ale_linters#scala#metals#GetCommand(buffer) abort
return '%e' . ale#Pad('stdio')
endfunction
call ale#linter#Define('scala', {
\ 'name': 'metals',
\ 'lsp': 'stdio',
\ 'language': 'scala',
\ 'executable': {b -> ale#Var(b, 'scala_metals_executable')},
\ 'command': function('ale_linters#scala#metals#GetCommand'),
\ 'project_root': function('ale_linters#scala#metals#GetProjectRoot'),
\})

View File

@@ -34,8 +34,10 @@ function! ale_linters#sh#shell#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" bash: line 13: syntax error near unexpected token `d'
" bash:行0: 未预期的符号“done”附近有语法错误
" bash: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符
" sh: 11: Syntax error: "(" unexpected
let l:pattern = '\v(line |: ?)(\d+): (.+)$'
let l:pattern = '\v([^:]+:\D*)(\d+): (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)

View File

@@ -0,0 +1,35 @@
" Author: Karl Bartel <karl42@gmail.com> - http://karl.berlin/
" Description: Report solc compiler errors in Solidity code
call ale#Set('solidity_solc_options', '')
function! ale_linters#solidity#solc#Handle(buffer, lines) abort
" Matches patterns like the following:
" /path/to/file/file.sol:1:10: Error: Identifier not found or not unique.
let l:pattern = '\v^[^:]+:(\d+):(\d+): (Error|Warning): (.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:isError = l:match[3] is? 'error'
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[4],
\ 'type': l:isError ? 'E' : 'W',
\})
endfor
return l:output
endfunction
function! ale_linters#solidity#solc#GetCommand(buffer) abort
return 'solc' . ale#Pad(ale#Var(a:buffer, 'solidity_solc_options')) . ' %s'
endfunction
call ale#linter#Define('solidity', {
\ 'name': 'solc',
\ 'executable': 'solc',
\ 'command': function('ale_linters#solidity#solc#GetCommand'),
\ 'callback': 'ale_linters#solidity#solc#Handle',
\ 'output_stream': 'stderr',
\})

0
ale_linters/terraform/terraform.vim Executable file → Normal file
View File

View File

@@ -9,8 +9,13 @@ call ale#Set('terraform_tflint_executable', 'tflint')
function! ale_linters#terraform#tflint#Handle(buffer, lines) abort
let l:output = []
let l:pattern = '\v^(.*):(\d+),(\d+)-(\d+)?,?(\d+): (.{-1,}); (.+)$'
let l:json = ale#util#FuzzyJSONDecode(a:lines, {})
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
" This is a rough test for tflint's output format
" On versions prior to 0.11 it outputs all errors as a single level list
if type(l:json) is v:t_list
for l:error in l:json
if l:error.type is# 'ERROR'
let l:type = 'E'
elseif l:error.type is# 'NOTICE'
@@ -26,6 +31,47 @@ function! ale_linters#terraform#tflint#Handle(buffer, lines) abort
\ 'code': l:error.detector,
\})
endfor
else
for l:error in get(l:json, 'errors', [])
for l:match in ale#util#GetMatches(l:error.message, [l:pattern])
if l:match[4] is# ''
let l:match[4] = l:match[2]
endif
call add(l:output, {
\ 'filename': l:match[1],
\ 'lnum': str2nr(l:match[2]),
\ 'col': str2nr(l:match[3]),
\ 'end_lnum': str2nr(l:match[4]),
\ 'end_col': str2nr(l:match[5]),
\ 'text': l:match[7],
\ 'code': l:match[6],
\ 'type': 'E',
\})
endfor
endfor
for l:error in get(l:json, 'issues', [])
if l:error.rule.severity is# 'ERROR'
let l:type = 'E'
elseif l:error.rule.severity is# 'NOTICE'
let l:type = 'I'
else
let l:type = 'W'
endif
call add(l:output, {
\ 'filename': l:error.range.filename,
\ 'lnum': l:error.range.start.line,
\ 'col': l:error.range.start.column,
\ 'end_lnum': l:error.range.end.line,
\ 'end_col': l:error.range.end.column,
\ 'text': l:error.message,
\ 'code': l:error.rule.name,
\ 'type': l:type,
\})
endfor
endif
return l:output
endfunction

View File

@@ -24,6 +24,20 @@ function! ale_linters#verilog#vlog#Handle(buffer, lines) abort
\})
endfor
"Matches patterns like the following:
"** Warning: (vlog-2623) add.v(7): Undefined variable: C.
"** Error: (vlog-13294) file.v(1): Identifier must be declared with a port mode: C.
" let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
let l:pattern = '^**\s\(\w*\):\s\([^)]*)\)[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[3] + 0,
\ 'type': l:match[1] is? 'Error' ? 'E' : 'W',
\ 'text': l:match[2] . ' ' . l:match[4],
\})
endfor
return l:output
endfunction

View File

@@ -156,7 +156,7 @@ function! ale#Queue(delay, ...) abort
endif
endfunction
let s:current_ale_version = [2, 5, 0]
let s:current_ale_version = [2, 6, 0]
" A function used to check for ALE features in files outside of the project.
function! ale#Has(feature) abort

View File

@@ -28,76 +28,107 @@ function! ale#c#GetBuildDirectory(buffer) abort
return ale#path#Dirname(l:json_file)
endfunction
function! ale#c#AreSpecialCharsBalanced(option) abort
" Escape \"
let l:option_escaped = substitute(a:option, '\\"', '', 'g')
" Retain special chars only
let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g')
let l:special_chars = split(l:special_chars, '\zs')
" Check if they are balanced
function! ale#c#ShellSplit(line) abort
let l:stack = []
let l:args = ['']
let l:prev = ''
for l:char in l:special_chars
if l:char is# ')'
if len(l:stack) == 0 || get(l:stack, -1) isnot# '('
return 0
endif
for l:char in split(a:line, '\zs')
if l:char is# ''''
if len(l:stack) > 0 && get(l:stack, -1) is# ''''
call remove(l:stack, -1)
elseif l:char is# '('
elseif (len(l:stack) == 0 || get(l:stack, -1) isnot# '"') && l:prev isnot# '\'
call add(l:stack, l:char)
else
endif
elseif (l:char is# '"' || l:char is# '`') && l:prev isnot# '\'
if len(l:stack) > 0 && get(l:stack, -1) is# l:char
call remove(l:stack, -1)
else
elseif len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
call add(l:stack, l:char)
endif
elseif (l:char is# '(' || l:char is# '[' || l:char is# '{') && l:prev isnot# '\'
if len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
call add(l:stack, l:char)
endif
elseif (l:char is# ')' || l:char is# ']' || l:char is# '}') && l:prev isnot# '\'
if len(l:stack) > 0 && get(l:stack, -1) is# {')': '(', ']': '[', '}': '{'}[l:char]
call remove(l:stack, -1)
endif
elseif l:char is# ' ' && len(l:stack) == 0
if len(get(l:args, -1)) > 0
call add(l:args, '')
endif
continue
endif
let l:args[-1] = get(l:args, -1) . l:char
endfor
return len(l:stack) == 0
return l:args
endfunction
function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
let l:split_lines = split(a:cflag_line)
let l:cflags_list = []
let l:split_lines = ale#c#ShellSplit(a:cflag_line)
let l:option_index = 0
while l:option_index < len(l:split_lines)
let l:next_option_index = l:option_index + 1
" Join space-separated option
while l:next_option_index < len(l:split_lines)
\&& stridx(l:split_lines[l:next_option_index], '-') != 0
let l:next_option_index += 1
endwhile
let l:option = join(l:split_lines[l:option_index : l:next_option_index-1], ' ')
call remove(l:split_lines, l:option_index, l:next_option_index-1)
call insert(l:split_lines, l:option, l:option_index)
" Ignore invalid or conflicting options
if stridx(l:option, '-') != 0
\|| stridx(l:option, '-o') == 0
\|| stridx(l:option, '-c') == 0
call remove(l:split_lines, l:option_index)
let l:option_index = l:option_index - 1
" Fix relative path
elseif stridx(l:option, '-I') == 0
if !(stridx(l:option, ':') == 2+1 || stridx(l:option, '/') == 2+0)
let l:option = '-I' . a:path_prefix . s:sep . l:option[2:]
call remove(l:split_lines, l:option_index)
call insert(l:split_lines, l:option, l:option_index)
endif
endif
let l:option = l:split_lines[l:option_index]
let l:option_index = l:option_index + 1
" Include options, that may need relative path fix
if stridx(l:option, '-I') == 0
\ || stridx(l:option, '-iquote') == 0
\ || stridx(l:option, '-isystem') == 0
\ || stridx(l:option, '-idirafter') == 0
if stridx(l:option, '-I') == 0 && l:option isnot# '-I'
let l:arg = join(split(l:option, '\zs')[2:], '')
let l:option = '-I'
else
let l:arg = l:split_lines[l:option_index]
let l:option_index = l:option_index + 1
endif
" Fix relative paths if needed
if stridx(l:arg, s:sep) != 0 && stridx(l:arg, '/') != 0
let l:rel_path = substitute(l:arg, '"', '', 'g')
let l:rel_path = substitute(l:rel_path, '''', '', 'g')
let l:arg = ale#Escape(a:path_prefix . s:sep . l:rel_path)
endif
call add(l:cflags_list, l:option)
call add(l:cflags_list, l:arg)
" Options with arg that can be grouped with the option or separate
elseif stridx(l:option, '-D') == 0 || stridx(l:option, '-B') == 0
call add(l:cflags_list, l:option)
if l:option is# '-D' || l:option is# '-B'
call add(l:cflags_list, l:split_lines[l:option_index])
let l:option_index = l:option_index + 1
endif
" Options that have an argument (always separate)
elseif l:option is# '-iprefix' || stridx(l:option, '-iwithprefix') == 0
\ || l:option is# '-isysroot' || l:option is# '-imultilib'
call add(l:cflags_list, l:option)
call add(l:cflags_list, l:split_lines[l:option_index])
let l:option_index = l:option_index + 1
" Options without argument
elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0)
\ || l:option is# '-w' || stridx(l:option, '-pedantic') == 0
\ || l:option is# '-ansi' || stridx(l:option, '-std=') == 0
\ || (stridx(l:option, '-f') == 0 && stridx(l:option, '-fdump') != 0 && stridx(l:option, '-fdiagnostics') != 0 && stridx(l:option, '-fno-show-column') != 0)
\ || stridx(l:option, '-O') == 0
\ || l:option is# '-C' || l:option is# '-CC' || l:option is# '-trigraphs'
\ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0
\ || stridx(l:option, '--sysroot=') == 0 || l:option is# '--no-sysroot-suffix'
\ || stridx(l:option, '-m') == 0
call add(l:cflags_list, l:option)
endif
endwhile
call uniq(l:split_lines)
return join(l:split_lines, ' ')
return join(l:cflags_list, ' ')
endfunction
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
@@ -234,6 +265,16 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
return l:empty
endfunction
function! ale#c#GetCompileCommand(json_item) abort
if has_key(a:json_item, 'command')
return a:json_item.command
elseif has_key(a:json_item, 'arguments')
return join(a:json_item.arguments, ' ')
endif
return ''
endfunction
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'))
@@ -256,15 +297,14 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
for l:item in l:file_list
" Load the flags for this file, or for a source file matching the
" header file.
if has_key(l:item, 'command')
\&& (
if (
\ 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)
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
endif
endfor
@@ -276,8 +316,7 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
for l:item in l:dir_list
if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir
\&& has_key(l:item, 'command')
return ale#c#ParseCFlags(l:item.directory, l:item.command)
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
endif
endfor

View File

@@ -0,0 +1,163 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Code action support for LSP / tsserver
function! ale#code_action#HandleCodeAction(code_action) abort
let l:current_buffer = bufnr('')
let l:changes = a:code_action.changes
for l:file_code_edit in l:changes
let l:buf = bufnr(l:file_code_edit.fileName)
if l:buf != -1 && l:buf != l:current_buffer && getbufvar(l:buf, '&mod')
call ale#util#Execute('echom ''Aborting action, file is unsaved''')
return
endif
endfor
for l:file_code_edit in l:changes
call ale#code_action#ApplyChanges(
\ l:file_code_edit.fileName, l:file_code_edit.textChanges)
endfor
endfunction
function! ale#code_action#ApplyChanges(filename, changes) abort
let l:current_buffer = bufnr('')
" The buffer is used to determine the fileformat, if available.
let l:buffer = bufnr(a:filename)
let l:is_current_buffer = l:buffer > 0 && l:buffer == l:current_buffer
if l:buffer > 0
let l:lines = getbufline(l:buffer, 1, '$')
else
let l:lines = readfile(a:filename, 'b')
endif
if l:is_current_buffer
let l:pos = getpos('.')[1:2]
else
let l:pos = [1, 1]
endif
" We have to keep track of how many lines we have added, and offset
" changes accordingly.
let l:line_offset = 0
let l:column_offset = 0
let l:last_end_line = 0
for l:code_edit in a:changes
if l:code_edit.start.line isnot l:last_end_line
let l:column_offset = 0
endif
let l:line = l:code_edit.start.line + l:line_offset
let l:column = l:code_edit.start.offset + l:column_offset
let l:end_line = l:code_edit.end.line + l:line_offset
let l:end_column = l:code_edit.end.offset + l:column_offset
let l:text = l:code_edit.newText
let l:cur_line = l:pos[0]
let l:cur_column = l:pos[1]
let l:last_end_line = l:end_line
" Adjust the ends according to previous edits.
if l:end_line > len(l:lines)
let l:end_line_len = 0
else
let l:end_line_len = len(l:lines[l:end_line - 1])
endif
let l:insertions = split(l:text, '\n', 1)
if l:line is 1
" Same logic as for column below. Vimscript's slice [:-1] will not
" be an empty list.
let l:start = []
else
let l:start = l:lines[: l:line - 2]
endif
if l:column is 1
" We need to handle column 1 specially, because we can't slice an
" empty string ending on index 0.
let l:middle = [l:insertions[0]]
else
let l:middle = [l:lines[l:line - 1][: l:column - 2] . l:insertions[0]]
endif
call extend(l:middle, l:insertions[1:])
let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :]
let l:lines_before_change = len(l:lines)
let l:lines = l:start + l:middle + l:lines[l:end_line :]
let l:current_line_offset = len(l:lines) - l:lines_before_change
let l:line_offset += l:current_line_offset
let l:column_offset = len(l:middle[-1]) - l:end_line_len
let l:pos = s:UpdateCursor(l:pos,
\ [l:line, l:column],
\ [l:end_line, l:end_column],
\ [l:current_line_offset, l:column_offset])
endfor
if l:lines[-1] is# ''
call remove(l:lines, -1)
endif
call ale#util#Writefile(l:buffer, l:lines, a:filename)
if l:is_current_buffer
call ale#util#Execute(':e!')
call setpos('.', [0, l:pos[0], l:pos[1], 0])
endif
endfunction
function! s:UpdateCursor(cursor, start, end, offset) abort
let l:cur_line = a:cursor[0]
let l:cur_column = a:cursor[1]
let l:line = a:start[0]
let l:column = a:start[1]
let l:end_line = a:end[0]
let l:end_column = a:end[1]
let l:line_offset = a:offset[0]
let l:column_offset = a:offset[1]
if l:end_line < l:cur_line
" both start and end lines are before the cursor. only line offset
" needs to be updated
let l:cur_line += l:line_offset
elseif l:end_line == l:cur_line
" end line is at the same location as cursor, which means
" l:line <= l:cur_line
if l:line < l:cur_line || l:column <= l:cur_column
" updates are happening either before or around the cursor
if l:end_column < l:cur_column
" updates are happening before the cursor, update the
" column offset for cursor
let l:cur_line += l:line_offset
let l:cur_column += l:column_offset
else
" updates are happening around the cursor, move the cursor
" to the end of the changes
let l:cur_line += l:line_offset
let l:cur_column = l:end_column + l:column_offset
endif
" else is not necessary, it means modifications are happening
" after the cursor so no cursor updates need to be done
endif
else
" end line is after the cursor
if l:line < l:cur_line || l:line == l:cur_line && l:column <= l:cur_column
" changes are happening around the cursor, move the cursor
" to the end of the changes
let l:cur_line = l:end_line + l:line_offset
let l:cur_column = l:end_column + l:column_offset
" else is not necesary, it means modifications are happening
" after the cursor so no cursor updates need to be done
endif
endif
return [l:cur_line, l:cur_column]
endfunction

View File

@@ -15,6 +15,7 @@ onoremap <silent> <Plug>(ale_show_completion_menu) <Nop>
let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100)
let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', [])
let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50)
let g:ale_completion_tsserver_autoimport = get(g:, 'ale_completion_tsserver_autoimport', 0)
let s:timer_id = -1
let s:last_done_pos = []
@@ -52,6 +53,7 @@ let s:should_complete_map = {
\ 'lisp': s:lisp_regex,
\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$',
\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
\ 'cpp': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$|-\>$',
\}
" Regular expressions for finding the start column to replace with completion.
@@ -59,11 +61,13 @@ let s:omni_start_map = {
\ '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$',
\}
" A map of exact characters for triggering LSP completions.
" A map of exact characters for triggering LSP completions. Do not forget to
" update self.input_patterns in ale.py in updating entries in this map.
let s:trigger_character_map = {
\ '<default>': ['.'],
\ 'typescript': ['.', '''', '"'],
\ 'rust': ['.', '::'],
\ 'cpp': ['.', '::', '->'],
\}
function! s:GetFiletypeValue(map, filetype) abort
@@ -215,6 +219,10 @@ function! ale#completion#GetCompletionPosition() abort
return l:column - len(l:match) - 1
endfunction
function! ale#completion#GetCompletionPositionForDeoplete(input) abort
return match(a:input, '\k*$')
endfunction
function! ale#completion#GetCompletionResult() abort
if exists('b:ale_completion_result')
return b:ale_completion_result
@@ -260,6 +268,14 @@ function! ale#completion#Show(result) abort
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
\)
endif
if l:source is# 'ale-callback'
call b:CompleteCallback(b:ale_completion_result)
endif
endfunction
function! ale#completion#GetAllTriggers() abort
return deepcopy(s:trigger_character_map)
endfunction
function! s:CompletionStillValid(request_id) abort
@@ -273,6 +289,7 @@ function! s:CompletionStillValid(request_id) abort
\ b:ale_completion_info.column == l:column
\ || b:ale_completion_info.source is# 'deoplete'
\ || b:ale_completion_info.source is# 'ale-omnifunc'
\ || b:ale_completion_info.source is# 'ale-callback'
\)
endfunction
@@ -280,7 +297,10 @@ function! ale#completion#ParseTSServerCompletions(response) abort
let l:names = []
for l:suggestion in a:response.body
call add(l:names, l:suggestion.name)
call add(l:names, {
\ 'word': l:suggestion.name,
\ 'source': get(l:suggestion, 'source', ''),
\})
endfor
return l:names
@@ -294,6 +314,10 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
for l:suggestion in a:response.body
let l:displayParts = []
for l:action in get(l:suggestion, 'codeActions', [])
call add(l:displayParts, l:action.description . ' ')
endfor
for l:part in l:suggestion.displayParts
call add(l:displayParts, l:part.text)
endfor
@@ -314,13 +338,22 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
endif
" See :help complete-items
call add(l:results, {
let l:result = {
\ 'word': l:suggestion.name,
\ 'kind': l:kind,
\ 'icase': 1,
\ 'menu': join(l:displayParts, ''),
\ 'dup': g:ale_completion_tsserver_autoimport,
\ 'info': join(l:documentationParts, ''),
\}
if has_key(l:suggestion, 'codeActions')
let l:result.user_data = json_encode({
\ 'codeActions': l:suggestion.codeActions,
\ })
endif
call add(l:results, l:result)
endfor
let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', [])
@@ -329,12 +362,12 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
let l:names_with_details = map(copy(l:results), 'v:val.word')
let l:missing_names = filter(
\ copy(l:names),
\ 'index(l:names_with_details, v:val) < 0',
\ 'index(l:names_with_details, v:val.word) < 0',
\)
for l:name in l:missing_names
call add(l:results, {
\ 'word': l:name,
\ 'word': l:name.word,
\ 'kind': 'v',
\ 'icase': 1,
\ 'menu': '',
@@ -456,13 +489,22 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names)
if !empty(l:names)
let l:identifiers = []
for l:name in l:names
call add(l:identifiers, {
\ 'name': l:name.word,
\ 'source': get(l:name, 'source', ''),
\})
endfor
let b:ale_completion_info.request_id = ale#lsp#Send(
\ b:ale_completion_info.conn_id,
\ ale#lsp#tsserver_message#CompletionEntryDetails(
\ l:buffer,
\ b:ale_completion_info.line,
\ b:ale_completion_info.column,
\ l:names,
\ l:identifiers,
\ ),
\)
endif
@@ -509,6 +551,7 @@ function! s:OnReady(linter, lsp_details) abort
\ b:ale_completion_info.line,
\ b:ale_completion_info.column,
\ b:ale_completion_info.prefix,
\ g:ale_completion_tsserver_autoimport,
\)
else
" Send a message saying the buffer has changed first, otherwise
@@ -553,12 +596,25 @@ endfunction
" This function can be used to manually trigger autocomplete, even when
" g:ale_completion_enabled is set to false
function! ale#completion#GetCompletions(source) abort
function! ale#completion#GetCompletions(...) abort
let l:source = get(a:000, 0, '')
let l:options = get(a:000, 1, {})
if len(a:000) > 2
throw 'Too many arguments!'
endif
let l:CompleteCallback = get(l:options, 'callback', v:null)
if l:CompleteCallback isnot v:null
let b:CompleteCallback = l:CompleteCallback
endif
let [l:line, l:column] = getpos('.')[1:2]
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
if a:source is# 'ale-automatic' && empty(l:prefix)
if l:source is# 'ale-automatic' && empty(l:prefix)
return 0
endif
@@ -571,7 +627,7 @@ function! ale#completion#GetCompletions(source) abort
\ 'prefix': l:prefix,
\ 'conn_id': 0,
\ 'request_id': 0,
\ 'source': a:source,
\ 'source': l:source,
\}
unlet! b:ale_completion_result
@@ -663,6 +719,30 @@ function! ale#completion#Queue() abort
let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler'))
endfunction
function! ale#completion#HandleUserData(completed_item) abort
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
if l:source isnot# 'ale-automatic' && l:source isnot# 'ale-manual'
return
endif
let l:user_data_json = get(a:completed_item, 'user_data', '')
if empty(l:user_data_json)
return
endif
let l:user_data = json_decode(l:user_data_json)
if type(l:user_data) isnot v:t_dict
return
endif
for l:code_action in get(l:user_data, 'codeActions', [])
call ale#code_action#HandleCodeAction(l:code_action)
endfor
endfunction
function! ale#completion#Done() abort
silent! pclose
@@ -671,6 +751,10 @@ function! ale#completion#Done() abort
let s:last_done_pos = getpos('.')[1:2]
endfunction
augroup ALECompletionActions
autocmd CompleteDone * call ale#completion#HandleUserData(v:completed_item)
augroup END
function! s:Setup(enabled) abort
augroup ALECompletionGroup
autocmd!

View File

@@ -50,6 +50,7 @@ let s:global_variable_list = [
\ 'ale_sign_style_error',
\ 'ale_sign_style_warning',
\ 'ale_sign_warning',
\ 'ale_sign_highlight_linenrs',
\ 'ale_statusline_format',
\ 'ale_type_map',
\ 'ale_use_global_executables',
@@ -62,7 +63,7 @@ function! s:Echo(message) abort
execute 'echo a:message'
endfunction
function! s:GetLinterVariables(filetype, linter_names) abort
function! s:GetLinterVariables(filetype, exclude_linter_names) abort
let l:variable_list = []
let l:filetype_parts = split(a:filetype, '\.')
@@ -73,7 +74,7 @@ function! s:GetLinterVariables(filetype, linter_names) abort
" Include matching variables.
if !empty(l:match)
\&& index(l:filetype_parts, l:match[1]) >= 0
\&& index(a:linter_names, l:match[2]) >= 0
\&& index(a:exclude_linter_names, l:match[2]) == -1
call add(l:variable_list, l:key)
endif
endfor
@@ -211,10 +212,11 @@ function! ale#debugging#Info() abort
let l:all_names = map(copy(l:all_linters), 'v:val[''name'']')
let l:enabled_names = map(copy(l:enabled_linters), 'v:val[''name'']')
let l:exclude_names = filter(copy(l:all_names), 'index(l:enabled_names, v:val) == -1')
" Load linter variables to display
" This must be done after linters are loaded.
let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names)
let l:variable_list = s:GetLinterVariables(l:filetype, l:exclude_names)
let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype)
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))

View File

@@ -47,7 +47,7 @@ function! ale#fix#ApplyQueuedFixes(buffer) abort
set nomodified
endif
else
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks
call writefile(l:new_lines, expand('#' . a:buffer . ':p')) " no-custom-checks
call setbufvar(a:buffer, '&modified', 0)
endif
endif
@@ -74,7 +74,7 @@ endfunction
function! ale#fix#ApplyFixes(buffer, output) abort
let l:data = g:ale_fix_buffer_data[a:buffer]
let l:data.output = a:output
let l:data.changes_made = l:data.lines_before != l:data.output
let l:data.changes_made = l:data.lines_before !=# l:data.output " no-custom-checks
let l:data.done = 1
call ale#command#RemoveManagedFiles(a:buffer)

View File

@@ -27,6 +27,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with black.',
\ },
\ 'dfmt': {
\ 'function': 'ale#fixers#dfmt#Fix',
\ 'suggested_filetypes': ['d'],
\ 'description': 'Fix D files with dfmt.',
\ },
\ 'fecs': {
\ 'function': 'ale#fixers#fecs#Fix',
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
@@ -115,6 +120,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['scala'],
\ 'description': 'Fix Scala files using scalafmt',
\ },
\ 'sorbet': {
\ 'function': 'ale#fixers#sorbet#Fix',
\ 'suggested_filetypes': ['ruby'],
\ 'description': 'Fix ruby files with srb tc --autocorrect.',
\ },
\ 'standard': {
\ 'function': 'ale#fixers#standard#Fix',
\ 'suggested_filetypes': ['javascript'],
@@ -145,6 +155,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['php'],
\ 'description': 'Fix PHP files with php-cs-fixer.',
\ },
\ 'clangtidy': {
\ 'function': 'ale#fixers#clangtidy#Fix',
\ 'suggested_filetypes': ['c', 'cpp', 'objc'],
\ 'description': 'Fix C/C++ and ObjectiveC files with clang-tidy.',
\ },
\ 'clang-format': {
\ 'function': 'ale#fixers#clangformat#Fix',
\ 'suggested_filetypes': ['c', 'cpp', 'cuda'],
@@ -205,6 +220,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['haskell'],
\ 'description': 'Fix Haskell files with brittany.',
\ },
\ 'hindent': {
\ 'function': 'ale#fixers#hindent#Fix',
\ 'suggested_filetypes': ['haskell'],
\ 'description': 'Fix Haskell files with hindent.',
\ },
\ 'hlint': {
\ 'function': 'ale#fixers#hlint#Fix',
\ 'suggested_filetypes': ['haskell'],
@@ -240,6 +260,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['sql'],
\ 'description': 'Fix SQL files with sqlfmt.',
\ },
\ 'sqlformat': {
\ 'function': 'ale#fixers#sqlformat#Fix',
\ 'suggested_filetypes': ['sql'],
\ 'description': 'Fix SQL files with sqlformat.',
\ },
\ 'google_java_format': {
\ 'function': 'ale#fixers#google_java_format#Fix',
\ 'suggested_filetypes': ['java'],
@@ -297,7 +322,7 @@ let s:default_registry = {
\ },
\ 'styler': {
\ 'function': 'ale#fixers#styler#Fix',
\ 'suggested_filetypes': ['r', 'rmarkdown'],
\ 'suggested_filetypes': ['r', 'rmarkdown', 'rmd'],
\ 'description': 'Fix R files with styler.',
\ },
\ 'latexindent': {
@@ -315,6 +340,16 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'],
\ 'description': 'Sort Python imports with reorder-python-imports.',
\ },
\ 'gnatpp': {
\ 'function': 'ale#fixers#gnatpp#Fix',
\ 'suggested_filetypes': ['ada'],
\ 'description': 'Format Ada files with gnatpp.',
\ },
\ 'nixpkgs-fmt': {
\ 'function': 'ale#fixers#nixpkgsfmt#Fix',
\ 'suggested_filetypes': ['nix'],
\ 'description': 'A formatter for Nix code',
\ },
\}
" Reset the function registry to the default entries.

View File

@@ -29,6 +29,10 @@ function! ale#fixers#black#Fix(buffer) abort
let l:options = ale#Var(a:buffer, 'python_black_options')
if expand('#' . a:buffer . ':e') is? 'pyi'
let l:options .= '--pyi'
endif
return {
\ 'command': l:cd_string . ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '')

View File

@@ -13,10 +13,15 @@ function! ale#fixers#clangformat#GetExecutable(buffer) abort
endfunction
function! ale#fixers#clangformat#Fix(buffer) abort
let l:executable = ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
let l:filename = ale#Escape(bufname(a:buffer))
let l:options = ale#Var(a:buffer, 'c_clangformat_options')
return {
\ 'command': ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
\ . ' ' . l:options,
\}
let l:command = l:executable . ' --assume-filename=' . l:filename
if l:options isnot# ''
let l:command .= ' ' . l:options
endif
return {'command': l:command}
endfunction

View File

@@ -0,0 +1,52 @@
scriptencoding utf-8
" Author: ObserverOfTime <chronobserver@disroot.org>
" Description: Fixing C/C++ files with clang-tidy.
function! s:set_variables() abort
let l:use_global = get(g:, 'ale_use_global_executables', 0)
for l:ft in ['c', 'cpp']
call ale#Set(l:ft . '_clangtidy_executable', 'clang-tidy')
call ale#Set(l:ft . '_clangtidy_use_global', l:use_global)
call ale#Set(l:ft . '_clangtidy_checks', [])
call ale#Set(l:ft . '_clangtidy_options', '')
call ale#Set(l:ft . '_clangtidy_extra_options', '')
call ale#Set(l:ft . '_clangtidy_fix_errors', 1)
endfor
call ale#Set('c_build_dir', '')
endfunction
call s:set_variables()
function! ale#fixers#clangtidy#Var(buffer, name) abort
let l:ft = getbufvar(str2nr(a:buffer), '&filetype')
let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c'
return ale#Var(a:buffer, l:ft . '_clangtidy_' . a:name)
endfunction
function! ale#fixers#clangtidy#GetCommand(buffer) abort
let l:checks = join(ale#fixers#clangtidy#Var(a:buffer, 'checks'), ',')
let l:extra_options = ale#fixers#clangtidy#Var(a:buffer, 'extra_options')
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = empty(l:build_dir)
\ ? ale#fixers#clangtidy#Var(a:buffer, 'options') : ''
let l:fix_errors = ale#fixers#clangtidy#Var(a:buffer, 'fix_errors')
return ' -fix' . (l:fix_errors ? ' -fix-errors' : '')
\ . (empty(l:checks) ? '' : ' -checks=' . ale#Escape(l:checks))
\ . (empty(l:extra_options) ? '' : ' ' . l:extra_options)
\ . (empty(l:build_dir) ? '' : ' -p ' . ale#Escape(l:build_dir))
\ . ' %t' . (empty(l:options) ? '' : ' -- ' . l:options)
endfunction
function! ale#fixers#clangtidy#Fix(buffer) abort
let l:executable = ale#fixers#clangtidy#Var(a:buffer, 'executable')
let l:command = ale#fixers#clangtidy#GetCommand(a:buffer)
return {
\ 'command': ale#Escape(l:executable) . l:command,
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -0,0 +1,18 @@
" Author: theoldmoon0602
" Description: Integration of dfmt with ALE.
call ale#Set('d_dfmt_executable', 'dfmt')
call ale#Set('d_dfmt_options', '')
function! ale#fixers#dfmt#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'd_dfmt_executable')
let l:options = ale#Var(a:buffer, 'd_dfmt_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ' -i'
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -0,0 +1,17 @@
" Author: tim <tim@inept.tech>
" Description: Fix files with gnatpp.
call ale#Set('ada_gnatpp_executable', 'gnatpp')
call ale#Set('ada_gnatpp_options', '')
function! ale#fixers#gnatpp#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'ada_gnatpp_executable')
let l:options = ale#Var(a:buffer, 'ada_gnatpp_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -7,9 +7,10 @@ call ale#Set('go_gofmt_options', '')
function! ale#fixers#gofmt#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'go_gofmt_executable')
let l:options = ale#Var(a:buffer, 'go_gofmt_options')
let l:env = ale#go#EnvString(a:buffer)
return {
\ 'command': ale#Escape(l:executable)
\ 'command': l:env . ale#Escape(l:executable)
\ . ' -l -w'
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . ' %t',

View File

@@ -7,13 +7,14 @@ call ale#Set('go_goimports_options', '')
function! ale#fixers#goimports#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'go_goimports_executable')
let l:options = ale#Var(a:buffer, 'go_goimports_options')
let l:env = ale#go#EnvString(a:buffer)
if !executable(l:executable)
return 0
endif
return {
\ 'command': ale#Escape(l:executable)
\ 'command': l:env . ale#Escape(l:executable)
\ . ' -l -w -srcdir %s'
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . ' %t',

View File

@@ -2,9 +2,10 @@ call ale#Set('go_go_executable', 'go')
function! ale#fixers#gomod#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'go_go_executable')
let l:env = ale#go#EnvString(a:buffer)
return {
\ 'command': ale#Escape(l:executable) . ' mod edit -fmt %t',
\ 'command': l:env . ale#Escape(l:executable) . ' mod edit -fmt %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

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

View File

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

View File

@@ -39,9 +39,15 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
let l:parser = ''
let l:filetypes = split(getbufvar(a:buffer, '&filetype'), '\.')
if index(l:filetypes, 'handlebars') > -1
let l:parser = 'glimmer'
endif
" Append the --parser flag depending on the current filetype (unless it's
" already set in g:javascript_prettier_options).
if empty(expand('#' . a:buffer . ':e')) && match(l:options, '--parser') == -1
if empty(expand('#' . a:buffer . ':e')) && l:parser is# '' && match(l:options, '--parser') == -1
" Mimic Prettier's defaults. In cases without a file extension or
" filetype (scratch buffer), Prettier needs `parser` set to know how
" to process the buffer.
@@ -65,7 +71,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
\ 'html': 'html',
\}
for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.')
for l:filetype in l:filetypes
if has_key(l:prettier_parsers, l:filetype)
let l:parser = l:prettier_parsers[l:filetype]
break

View File

@@ -6,7 +6,7 @@ function! ale#fixers#rubocop#GetCommand(buffer) abort
let l:config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml')
let l:options = ale#Var(a:buffer, 'ruby_rubocop_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop')
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --auto-correct --force-exclusion %t'

View File

@@ -0,0 +1,19 @@
call ale#Set('ruby_sorbet_executable', 'srb')
call ale#Set('ruby_sorbet_options', '')
function! ale#fixers#sorbet#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
return ale#ruby#EscapeExecutable(l:executable, 'srb')
\ . ' tc'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --autocorrect --file %t'
endfunction
function! ale#fixers#sorbet#Fix(buffer) abort
return {
\ 'command': ale#fixers#sorbet#GetCommand(a:buffer),
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -0,0 +1,16 @@
" Author: Cluas <Cluas@live.cn>
" Description: Fixing files with sqlformat.
call ale#Set('sql_sqlformat_executable', 'sqlformat')
call ale#Set('sql_sqlformat_options', '')
function! ale#fixers#sqlformat#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'sql_sqlformat_executable')
let l:options = ale#Var(a:buffer, 'sql_sqlformat_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -'
\}
endfunction

View File

@@ -9,7 +9,7 @@ function! ale#fixers#standardrb#GetCommand(buffer) abort
let l:config = ale#path#FindNearestFile(a:buffer, '.standard.yml')
let l:options = ale#Var(a:buffer, 'ruby_standardrb_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb')
return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --fix --force-exclusion %t'

View File

@@ -25,3 +25,20 @@ function! ale#go#FindProjectRoot(buffer) abort
return ''
endfunction
call ale#Set('go_go111module', '')
" Return a string setting Go-specific environment variables
function! ale#go#EnvString(buffer) abort
let l:env = ''
" GO111MODULE - turn go modules behavior on/off
let l:go111module = ale#Var(a:buffer, 'go_go111module')
if !empty(l:go111module)
let l:env = ale#Env('GO111MODULE', l:go111module) . l:env
endif
return l:env
endfunction

View File

@@ -2,6 +2,7 @@
" Description: languagetool for markdown files
"
call ale#Set('languagetool_executable', 'languagetool')
call ale#Set('languagetool_options', '--autoDetect')
function! ale#handlers#languagetool#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'languagetool_executable')
@@ -9,8 +10,10 @@ endfunction
function! ale#handlers#languagetool#GetCommand(buffer) abort
let l:executable = ale#handlers#languagetool#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'languagetool_options')
return ale#Escape(l:executable) . ' --autoDetect %s'
return ale#Escape(l:executable)
\ . (empty(l:options) ? '' : ' ' . l:options) . ' %s'
endfunction
function! ale#handlers#languagetool#HandleOutput(buffer, lines) abort

View File

@@ -36,11 +36,3 @@ endfunction
function! ale#handlers#ruby#HandleSyntaxErrors(buffer, lines) abort
return s:HandleSyntaxError(a:buffer, a:lines)
endfunction
function! ale#handlers#ruby#EscapeExecutable(executable, bundle_exec) abort
let l:exec_args = a:executable =~? 'bundle'
\ ? ' exec ' . a:bundle_exec
\ : ''
return ale#Escape(a:executable) . l:exec_args
endfunction

View File

@@ -26,6 +26,25 @@ endif
let s:MAX_POS_VALUES = 8
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
let s:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
if s:has_nvim_highlight
let s:ns_id = nvim_create_namespace('ale_highlight')
endif
" Wrappers are necessary to test this functionality by faking the calls in tests.
function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
" Ignore all errors for adding highlights.
try
call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end)
catch
endtry
endfunction
function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
call nvim_buf_clear_namespace(a:buffer, a:ns_id, a:line_start, a:line_end)
endfunction
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
if a:line >= a:end_line
" For single lines, just return the one position.
@@ -51,15 +70,53 @@ endfunction
" except these which have matching loclist item entries.
function! ale#highlight#RemoveHighlights() abort
if s:has_nvim_highlight
call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1)
else
for l:match in getmatches()
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
call matchdelete(l:match.id)
endif
endfor
endif
endfunction
" Same semantics of matchaddpos but will use nvim_buf_add_highlight if
" available. This involves iterating over the position list, switching from
" 1-based indexing to 0-based indexing, and translating the multiple ways
" that position can be specified for matchaddpos into line + col_start +
" col_end.
function! s:matchaddpos(group, pos_list) abort
if s:has_nvim_highlight
for l:pos in a:pos_list
let l:line = type(l:pos) == v:t_number
\ ? l:pos - 1
\ : l:pos[0] - 1
if type(l:pos) == v:t_number || len(l:pos) == 1
let l:col_start = 0
let l:col_end = s:MAX_COL_SIZE
else
let l:col_start = l:pos[1] - 1
let l:col_end = l:col_start + get(l:pos, 2, 1)
endif
call ale#highlight#nvim_buf_add_highlight(
\ bufnr(''),
\ s:ns_id,
\ a:group,
\ l:line,
\ l:col_start,
\ l:col_end,
\)
endfor
else
call matchaddpos(a:group, a:pos_list)
endif
endfunction
function! s:highlight_line(bufnr, lnum, group) abort
call matchaddpos(a:group, [a:lnum])
call s:matchaddpos(a:group, [a:lnum])
endfunction
function! s:highlight_range(bufnr, range, group) abort
@@ -72,7 +129,7 @@ function! s:highlight_range(bufnr, range, group) abort
\ a:range.end_lnum,
\ a:range.end_col
\ ),
\ 'matchaddpos(a:group, v:val)'
\ 's:matchaddpos(a:group, v:val)'
\)
endfunction

View File

@@ -12,9 +12,12 @@ let s:linters = {}
let s:default_ale_linter_aliases = {
\ 'Dockerfile': 'dockerfile',
\ 'csh': 'sh',
\ 'javascriptreact': ['javascript', 'jsx'],
\ 'plaintex': 'tex',
\ 'rmarkdown': 'r',
\ 'rmd': 'r',
\ 'systemverilog': 'verilog',
\ 'typescriptreact': ['typescript', 'tsx'],
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
\ 'vimwiki': 'markdown',
\ 'vue': ['vue', 'javascript'],

View File

@@ -103,6 +103,9 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
endfor
endif
" Save the current view before opening/closing any window
call setbufvar(a:buffer, 'ale_winview', winsaveview())
" Open a window to show the problems if we need to.
"
" We'll check if the current buffer's List is not empty here, so the
@@ -110,8 +113,6 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
if s:ShouldOpen(a:buffer) && !empty(a:loclist)
let l:winnr = winnr()
let l:mode = mode()
let l:reset_visual_selection = l:mode is? 'v' || l:mode is# "\<c-v>"
let l:reset_character_selection = l:mode is? 's' || l:mode is# "\<c-s>"
" open windows vertically instead of default horizontally
let l:open_type = ''
@@ -133,15 +134,18 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
wincmd p
endif
if l:reset_visual_selection || l:reset_character_selection
" If we were in a selection mode before, select the last selection.
" Return to original mode when applicable
if mode() != l:mode
if l:mode is? 'v' || l:mode is# "\<c-v>"
" Reset our last visual selection
normal! gv
if l:reset_character_selection
" Switch back to Select mode, if we were in that.
elseif l:mode is? 's' || l:mode is# "\<c-s>"
" Reset our last character selection
normal! "\<c-g>"
endif
endif
call s:RestoreViewIfNeeded(a:buffer)
endif
" If ALE isn't currently checking for more problems, close the window if
@@ -152,6 +156,30 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
endif
endfunction
" Try to restore the window view after closing any of the lists to avoid making
" the it moving around, especially useful when on insert mode
function! s:RestoreViewIfNeeded(buffer) abort
let l:saved_view = getbufvar(a:buffer, 'ale_winview', {})
" Saved view is empty, can't do anything
if empty(l:saved_view)
return
endif
" Check wether the cursor has moved since linting was actually requested. If
" the user has indeed moved lines, do nothing
let l:current_view = winsaveview()
if l:current_view['lnum'] != l:saved_view['lnum']
return
endif
" Anchor view by topline if the list is set to open horizontally
if ale#Var(a:buffer, 'list_vertical') == 0
call winrestview({'topline': l:saved_view['topline']})
endif
endfunction
function! ale#list#SetLists(buffer, loclist) abort
if get(g:, 'ale_set_lists_synchronously') == 1
\|| getbufvar(a:buffer, 'ale_save_event_fired', 0)
@@ -175,12 +203,15 @@ function! s:CloseWindowIfNeeded(buffer) abort
return
endif
let l:did_close_any_list = 0
try
" Only close windows if the quickfix list or loclist is completely empty,
" including errors set through other means.
if g:ale_set_quickfix
if empty(getqflist())
cclose
let l:did_close_any_list = 1
endif
else
let l:win_ids = s:WinFindBuf(a:buffer)
@@ -188,10 +219,15 @@ function! s:CloseWindowIfNeeded(buffer) abort
for l:win_id in l:win_ids
if g:ale_set_loclist && empty(getloclist(l:win_id))
lclose
let l:did_close_any_list = 1
endif
endfor
endif
" Ignore 'Cannot close last window' errors.
catch /E444/
endtry
if l:did_close_any_list
call s:RestoreViewIfNeeded(a:buffer)
endif
endfunction

View File

@@ -37,6 +37,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
\ 'init_queue': [],
\ 'capabilities': {
\ 'hover': 0,
\ 'rename': 0,
\ 'references': 0,
\ 'completion': 0,
\ 'completion_trigger_characters': [],
@@ -199,6 +200,10 @@ function! s:UpdateCapabilities(conn, capabilities) abort
let a:conn.capabilities.references = 1
endif
if get(a:capabilities, 'renameProvider') is v:true
let a:conn.capabilities.rename = 1
endif
if !empty(get(a:capabilities, 'completionProvider'))
let a:conn.capabilities.completion = 1
endif
@@ -317,6 +322,7 @@ function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort
let l:conn.capabilities.completion_trigger_characters = ['.']
let l:conn.capabilities.definition = 1
let l:conn.capabilities.symbol_search = 1
let l:conn.capabilities.rename = 1
endfunction
function! s:SendInitMessage(conn) abort

View File

@@ -162,3 +162,13 @@ function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
\ 'settings': a:config,
\}]
endfunction
function! ale#lsp#message#Rename(buffer, line, column, new_name) abort
return [0, 'textDocument/rename', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\ 'newName': a:new_name,
\}]
endfunction

View File

@@ -36,12 +36,14 @@ function! ale#lsp#tsserver_message#Geterr(buffer) abort
return [1, 'ts@geterr', {'files': [expand('#' . a:buffer . ':p')]}]
endfunction
function! ale#lsp#tsserver_message#Completions(buffer, line, column, prefix) abort
function! ale#lsp#tsserver_message#Completions(
\ buffer, line, column, prefix, include_external) abort
return [0, 'ts@completions', {
\ 'line': a:line,
\ 'offset': a:column,
\ 'file': expand('#' . a:buffer . ':p'),
\ 'prefix': a:prefix,
\ 'includeExternalModuleExports': a:include_external,
\}]
endfunction
@@ -77,3 +79,27 @@ function! ale#lsp#tsserver_message#Quickinfo(buffer, line, column) abort
\ 'file': expand('#' . a:buffer . ':p'),
\}]
endfunction
function! ale#lsp#tsserver_message#Rename(
\ buffer, line, column, find_in_comments, find_in_strings) abort
return [0, 'ts@rename', {
\ 'line': a:line,
\ 'offset': a:column,
\ 'file': expand('#' . a:buffer . ':p'),
\ 'arguments': {
\ 'findInComments': a:find_in_comments,
\ 'findInStrings': a:find_in_strings,
\ }
\}]
endfunction
function! ale#lsp#tsserver_message#OrganizeImports(buffer) abort
return [0, 'ts@organizeImports', {
\ 'scope': {
\ 'type': 'file',
\ 'args': {
\ 'file': expand('#' . a:buffer . ':p'),
\ },
\ },
\}]
endfunction

View File

@@ -0,0 +1,59 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Organize imports support for tsserver
"
function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') isnot# 'organizeImports'
return
endif
if get(a:response, 'success', v:false) isnot v:true
return
endif
let l:file_code_edits = a:response.body
call ale#code_action#HandleCodeAction({
\ 'description': 'Organize Imports',
\ 'changes': l:file_code_edits,
\})
endfunction
function! s:OnReady(linter, lsp_details) abort
let l:id = a:lsp_details.connection_id
if a:linter.lsp isnot# 'tsserver'
call ale#util#Execute('echom ''OrganizeImports currently only works with tsserver''')
return
endif
let l:buffer = a:lsp_details.buffer
let l:Callback = function('ale#organize_imports#HandleTSServerResponse')
call ale#lsp#RegisterCallback(l:id, l:Callback)
let l:message = ale#lsp#tsserver_message#OrganizeImports(l:buffer)
let l:request_id = ale#lsp#Send(l:id, l:message)
endfunction
function! s:OrganizeImports(linter) abort
let l:buffer = bufnr('')
let [l:line, l:column] = getpos('.')[1:2]
if a:linter.lsp isnot# 'tsserver'
let l:column = min([l:column, len(getline(l:line))])
endif
let l:Callback = function('s:OnReady')
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
endfunction
function! ale#organize_imports#Execute() abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:OrganizeImports(l:linter)
endif
endfor
endfunction

View File

@@ -54,14 +54,14 @@ function! ale#path#FindNearestDirectory(buffer, directory_name) abort
return ''
endfunction
" Given a buffer, a string to search for, an a global fallback for when
" Given a buffer, a string to search for, and a global fallback for when
" the search fails, look for a file in parent paths, and if that fails,
" use the global fallback path instead.
function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abort
" Search for a locally installed file first.
let l:path = ale#path#FindNearestFile(a:buffer, a:search_string)
" If the serach fails, try the global executable instead.
" If the search fails, try the global executable instead.
if empty(l:path)
let l:path = a:global_fallback
endif

225
autoload/ale/rename.vim Normal file
View File

@@ -0,0 +1,225 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Rename symbol support for LSP / tsserver
let s:rename_map = {}
" Used to get the rename map in tests.
function! ale#rename#GetMap() abort
return deepcopy(s:rename_map)
endfunction
" Used to set the rename map in tests.
function! ale#rename#SetMap(map) abort
let s:rename_map = a:map
endfunction
function! ale#rename#ClearLSPData() abort
let s:rename_map = {}
endfunction
let g:ale_rename_tsserver_find_in_comments = get(g:, 'ale_rename_tsserver_find_in_comments')
let g:ale_rename_tsserver_find_in_strings = get(g:, 'ale_rename_tsserver_find_in_strings')
function! s:message(message) abort
call ale#util#Execute('echom ' . string(a:message))
endfunction
function! ale#rename#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') isnot# 'rename'
return
endif
if !has_key(s:rename_map, a:response.request_seq)
return
endif
let l:old_name = s:rename_map[a:response.request_seq].old_name
let l:new_name = s:rename_map[a:response.request_seq].new_name
call remove(s:rename_map, a:response.request_seq)
if get(a:response, 'success', v:false) is v:false
let l:message = get(a:response, 'message', 'unknown')
call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name
\ . '". Reason: ' . l:message)
return
endif
let l:changes = []
for l:response_item in a:response.body.locs
let l:filename = l:response_item.file
let l:text_changes = []
for l:loc in l:response_item.locs
call add(l:text_changes, {
\ 'start': {
\ 'line': l:loc.start.line,
\ 'offset': l:loc.start.offset,
\ },
\ 'end': {
\ 'line': l:loc.end.line,
\ 'offset': l:loc.end.offset,
\ },
\ 'newText': l:new_name,
\})
endfor
call add(l:changes, {
\ 'fileName': l:filename,
\ 'textChanges': l:text_changes,
\})
endfor
if empty(l:changes)
call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name . '"')
return
endif
call ale#code_action#HandleCodeAction({
\ 'description': 'rename',
\ 'changes': l:changes,
\})
endfunction
function! ale#rename#HandleLSPResponse(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:rename_map, a:response.id)
call remove(s:rename_map, a:response.id)
if !has_key(a:response, 'result')
call s:message('No rename result received from server')
return
endif
let l:workspace_edit = a:response.result
if !has_key(l:workspace_edit, 'changes') || empty(l:workspace_edit.changes)
call s:message('No changes received from server')
return
endif
let l:changes = []
for l:file_name in keys(l:workspace_edit.changes)
let l:text_edits = l:workspace_edit.changes[l:file_name]
let l:text_changes = []
for l:edit in l:text_edits
let l:range = l:edit.range
let l:new_text = l:edit.newText
call add(l:text_changes, {
\ 'start': {
\ 'line': l:range.start.line + 1,
\ 'offset': l:range.start.character + 1,
\ },
\ 'end': {
\ 'line': l:range.end.line + 1,
\ 'offset': l:range.end.character + 1,
\ },
\ 'newText': l:new_text,
\})
endfor
call add(l:changes, {
\ 'fileName': ale#path#FromURI(l:file_name),
\ 'textChanges': l:text_changes,
\})
endfor
call ale#code_action#HandleCodeAction({
\ 'description': 'rename',
\ 'changes': l:changes,
\})
endif
endfunction
function! s:OnReady(line, column, old_name, new_name, linter, lsp_details) abort
let l:id = a:lsp_details.connection_id
if !ale#lsp#HasCapability(l:id, 'rename')
return
endif
let l:buffer = a:lsp_details.buffer
let l:Callback = a:linter.lsp is# 'tsserver'
\ ? function('ale#rename#HandleTSServerResponse')
\ : function('ale#rename#HandleLSPResponse')
call ale#lsp#RegisterCallback(l:id, l:Callback)
if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Rename(
\ l:buffer,
\ a:line,
\ a:column,
\ g:ale_rename_tsserver_find_in_comments,
\ g:ale_rename_tsserver_find_in_strings,
\)
else
" Send a message saying the buffer has changed first, or the
" rename position probably won't make sense.
call ale#lsp#NotifyForChanges(l:id, l:buffer)
let l:message = ale#lsp#message#Rename(
\ l:buffer,
\ a:line,
\ a:column,
\ a:new_name
\)
endif
let l:request_id = ale#lsp#Send(l:id, l:message)
let s:rename_map[l:request_id] = {
\ 'new_name': a:new_name,
\ 'old_name': a:old_name,
\}
endfunction
function! s:ExecuteRename(linter, old_name, new_name) abort
let l:buffer = bufnr('')
let [l:line, l:column] = getpos('.')[1:2]
if a:linter.lsp isnot# 'tsserver'
let l:column = min([l:column, len(getline(l:line))])
endif
let l:Callback = function(
\ 's:OnReady', [l:line, l:column, a:old_name, a:new_name])
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
endfunction
function! ale#rename#Execute() abort
let l:lsp_linters = []
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call add(l:lsp_linters, l:linter)
endif
endfor
if empty(l:lsp_linters)
call s:message('No active LSPs')
return
endif
let l:old_name = expand('<cword>')
let l:new_name = ale#util#Input('New name: ', l:old_name)
if empty(l:new_name)
call s:message('New name cannot be empty!')
return
endif
for l:lsp_linter in l:lsp_linters
call s:ExecuteRename(l:lsp_linter, l:old_name, l:new_name)
endfor
endfunction

View File

@@ -74,3 +74,10 @@ function! ale#ruby#HandleRubocopOutput(buffer, lines) abort
return l:output
endfunction
function! ale#ruby#EscapeExecutable(executable, bundle_exec) abort
let l:exec_args = a:executable =~? 'bundle'
\ ? ' exec ' . a:bundle_exec
\ : ''
return ale#Escape(a:executable) . l:exec_args
endfunction

View File

@@ -14,12 +14,14 @@ let g:ale_sign_style_error = get(g:, 'ale_sign_style_error', g:ale_sign_error)
let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--')
let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning)
let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning)
let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30)
" This variable sets an offset which can be set for sign IDs.
" This ID can be changed depending on what IDs are set for other plugins.
" The dummy sign will use the ID exactly equal to the offset.
let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000)
" This flag can be set to 1 to keep sign gutter always open
let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0)
let g:ale_sign_highlight_linenrs = get(g:, 'ale_sign_highlight_linenrs', 0)
if !hlexists('ALEErrorSign')
highlight link ALEErrorSign error
@@ -82,6 +84,34 @@ execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
sign define ALEDummySign
if g:ale_sign_highlight_linenrs && has('nvim-0.3.2')
if !hlexists('ALEErrorSignLineNr')
highlight link ALEErrorSignLineNr CursorLineNr
endif
if !hlexists('ALEStyleErrorSignLineNr')
highlight link ALEStyleErrorSignLineNr CursorLineNr
endif
if !hlexists('ALEWarningSignLineNr')
highlight link ALEWarningSignLineNr CursorLineNr
endif
if !hlexists('ALEStyleWarningSignLineNr')
highlight link ALEStyleWarningSignLineNr CursorLineNr
endif
if !hlexists('ALEInfoSignLineNr')
highlight link ALEInfoSignLineNr CursorLineNr
endif
sign define ALEErrorSign numhl=ALEErrorSignLineNr
sign define ALEStyleErrorSign numhl=ALEStyleErrorSignLineNr
sign define ALEWarningSign numhl=ALEWarningSignLineNr
sign define ALEStyleWarningSign numhl=ALEStyleWarningSignLineNr
sign define ALEInfoSign numhl=ALEInfoSignLineNr
endif
function! ale#sign#GetSignName(sublist) abort
let l:priority = g:ale#util#style_warning_priority
@@ -118,24 +148,59 @@ function! ale#sign#GetSignName(sublist) abort
return 'ALEErrorSign'
endfunction
function! s:PriorityCmd() abort
if has('nvim-0.4.0') || (v:version >= 801 && has('patch614'))
return ' priority=' . g:ale_sign_priority . ' '
else
return ''
endif
endfunction
function! s:GroupCmd() abort
if has('nvim-0.4.0') || (v:version >= 801 && has('patch614'))
return ' group=ale '
else
return ' '
endif
endfunction
" Read sign data for a buffer to a list of lines.
function! ale#sign#ReadSigns(buffer) abort
redir => l:output
silent execute 'sign place buffer=' . a:buffer
silent execute 'sign place ' . s:GroupCmd() . s:PriorityCmd()
\ . ' buffer=' . a:buffer
redir end
return split(l:output, "\n")
endfunction
" Given a list of lines for sign output, return a List of [line, id, group]
function! ale#sign#ParseSigns(line_list) abort
function! ale#sign#ParsePattern() abort
if has('nvim-0.4.0') || (v:version >= 801 && has('patch614'))
" Matches output like :
" line=4 id=1 group=ale name=ALEErrorSign
" строка=1 id=1000001 группа=ale имя=ALEErrorSign
" 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign
" línea=12 id=1000001 grupo=ale nombre=ALEWarningSign
" riga=1 id=1000001 gruppo=ale nome=ALEWarningSign
" Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale>.*\=(ALE[a-zA-Z]+Sign)'
else
" Matches output like :
" line=4 id=1 name=ALEErrorSign
" строка=1 id=1000001 имя=ALEErrorSign
" 行=1 識別子=1000001 名前=ALEWarningSign
" línea=12 id=1000001 nombre=ALEWarningSign
" riga=1 id=1000001, nome=ALEWarningSign
" riga=1 id=1000001 nome=ALEWarningSign
" Zeile=235 id=1000001 Name=ALEErrorSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)'
endif
return l:pattern
endfunction
" Given a list of lines for sign output, return a List of [line, id, group]
function! ale#sign#ParseSigns(line_list) abort
let l:pattern =ale#sign#ParsePattern()
let l:result = []
let l:is_dummy_sign_set = 0
@@ -290,8 +355,10 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
if !l:is_dummy_sign_set && (!empty(a:sign_map) || g:ale_sign_column_always)
call add(l:command_list, 'sign place '
\ . g:ale_sign_offset
\ . ' line=1 name=ALEDummySign buffer='
\ . a:buffer
\ . s:GroupCmd()
\ . s:PriorityCmd()
\ . ' line=1 name=ALEDummySign '
\ . ' buffer=' . a:buffer
\)
let l:is_dummy_sign_set = 1
endif
@@ -308,6 +375,8 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
if index(l:info.current_id_list, l:info.new_id) < 0
call add(l:command_list, 'sign place '
\ . (l:info.new_id)
\ . s:GroupCmd()
\ . s:PriorityCmd()
\ . ' line=' . l:line_str
\ . ' name=' . (l:info.new_name)
\ . ' buffer=' . a:buffer
@@ -322,6 +391,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
if l:current_id isnot l:info.new_id
call add(l:command_list, 'sign unplace '
\ . l:current_id
\ . s:GroupCmd()
\ . ' buffer=' . a:buffer
\)
endif
@@ -332,6 +402,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
if l:is_dummy_sign_set && !g:ale_sign_column_always
call add(l:command_list, 'sign unplace '
\ . g:ale_sign_offset
\ . s:GroupCmd()
\ . ' buffer=' . a:buffer
\)
endif
@@ -386,3 +457,12 @@ function! ale#sign#SetSigns(buffer, loclist) abort
highlight link SignColumn ALESignColumnWithoutErrors
endif
endfunction
" Remove all signs.
function! ale#sign#Clear() abort
if has('nvim-0.4.0') || (v:version >= 801 && has('patch614'))
sign unplace group=ale *
else
sign unplace *
endif
endfunction

View File

@@ -477,3 +477,6 @@ function! ale#util#FindItemAtCursor(buffer) abort
return [l:info, l:loc]
endfunction
function! ale#util#Input(message, value) abort
return input(a:message, a:value)
endfunction

View File

@@ -0,0 +1,26 @@
function! asyncomplete#sources#ale#get_source_options(...) abort
let l:default = extend({
\ 'name': 'ale',
\ 'completor': function('asyncomplete#sources#ale#completor'),
\ 'whitelist': ['*'],
\ 'triggers': asyncomplete#sources#ale#get_triggers(),
\ }, a:0 >= 1 ? a:1 : {})
return extend(l:default, {'refresh_pattern': '\k\+$'})
endfunction
function! asyncomplete#sources#ale#get_triggers() abort
let l:triggers = ale#completion#GetAllTriggers()
let l:triggers['*'] = l:triggers['<default>']
return l:triggers
endfunction
function! asyncomplete#sources#ale#completor(options, context) abort
let l:keyword = matchstr(a:context.typed, '\w\+$')
let l:startcol = a:context.col - len(l:keyword)
call ale#completion#GetCompletions('ale-callback', { 'callback': {completions ->
\ asyncomplete#complete(a:options.name, a:context, l:startcol, completions)
\ }})
endfunction

View File

@@ -21,5 +21,16 @@ g:ale_ada_gcc_options *g:ale_ada_gcc_options*
This variable can be set to pass additional options to gcc.
===============================================================================
gnatpp *ale-ada-gnatpp*
g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options*
*b:ale_ada_gnatpp_options*
Type: |String|
Default: `''`
This variable can be set to pass extra options to the gnatpp fixer.
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@@ -177,6 +177,15 @@ g:ale_c_clangtidy_extra_options *g:ale_c_clangtidy_extra_options*
This variable can be changed to modify flags given to clang-tidy.
g:ale_c_clangtidy_fix_errors *g:ale_c_clangtidy_fix_errors*
*b:ale_c_clangtidy_fix_errors*
Type: |Number|
Default: `1`
This variable can be changed to disable the `-fix-errors` option for the
|clangtidy| fixer.
===============================================================================
cppcheck *ale-c-cppcheck*

View File

@@ -146,6 +146,15 @@ g:ale_cpp_clangtidy_extra_options *g:ale_cpp_clangtidy_extra_options*
This variable can be changed to modify flags given to clang-tidy.
g:ale_cpp_clangtidy_fix_errors *g:ale_cpp_clangtidy_fix_errors*
*b:ale_cpp_clangtidy_fix_errors*
Type: |Number|
Default: `1`
This variable can be changed to disable the `-fix-errors` option for the
|clangtidy| fixer.
===============================================================================
clazy *ale-cpp-clazy*

View File

@@ -6,11 +6,96 @@ In addition to the linters that are provided with ALE, C# code can be checked
with the OmniSharp plugin. See here: https://github.com/OmniSharp/omnisharp-vim
===============================================================================
csc *ale-cs-csc*
The |ale-cs-csc| linter checks for semantic errors when files are opened or
saved.
See |ale-lint-file-linters| for more information on linters which do not
check for problems while you type.
The csc linter uses the mono csc compiler, providing full C# 7 and newer
support, to generate a temporary module target file (/t:module). The module
includes all '*.cs' files contained in the directory tree rooted at the path
defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source| variable and
all sub directories.
It will in future replace the |ale-cs-mcs| and |ale-cs-mcsc| linters as both
utilize the mcsc compiler which, according to the mono project, is no longer
actively developed, and only receives maintenance updates. However, because
the csc compiler does not support the -syntax option, this linter does not
offer any as-you-type syntax checking, similar to the |ale-cs-mcsc| linter.
The paths to search for additional assembly files can be specified using the
|g:ale_cs_csc_assembly_path| or |b:ale_cs_csc_assembly_path| variables.
NOTE: ALE will not find any errors in files apart from syntax errors if any
one of the source files contains a syntax error. Syntax errors must be fixed
first before other errors will be shown.
g:ale_cs_csc_options *g:ale_cs_csc_options*
*b:ale_cs_csc_options*
Type: |String|
Default: `''`
This option can be set to pass additional arguments to the `csc` compiler.
For example, to add the dotnet package which is not added per default: >
let g:ale_cs_mcs_options = ' /warn:4 /langversion:7.2'
<
NOTE: the `/unsafe` option is always passed to `csc`.
g:ale_cs_csc_source *g:ale_cs_csc_source*
*b:ale_cs_csc_source*
Type: |String|
Default: `''`
This variable defines the root path of the directory tree searched for the
'*.cs' files to be linted. If this option is empty, the source file's
directory will be used.
NOTE: Currently it is not possible to specify sub directories and
directory sub trees which shall not be searched for *.cs files.
g:ale_cs_csc_assembly_path *g:ale_cs_csc_assembly_path*
*b:ale_cs_csc_assembly_path*
Type: |List|
Default: `[]`
This variable defines a list of path strings to be searched for external
assembly files. The list is passed to the csc compiler using the `/lib:`
flag.
g:ale_cs_csc_assemblies *g:ale_cs_csc_assemblies*
*b:ale_cs_csc_assemblies*
Type: |List|
Default: `[]`
This variable defines a list of external assembly (*.dll) files required
by the mono mcs compiler to generate a valid module target. The list is
passed the csc compiler using the `/r:` flag.
For example: >
" Compile C# programs with the Unity engine DLL file on Mac.
let g:ale_cs_mcsc_assemblies = [
\ '/Applications/Unity/Unity.app/Contents/Frameworks/Managed/UnityEngine.dll',
\ 'path-to-unityproject/obj/Debug',
\]
<
===============================================================================
mcs *ale-cs-mcs*
The `mcs` linter looks only for syntax errors while you type. See |ale-cs-mcsc|
for the separately configured linter for checking for semantic errors.
The `mcs` linter looks only for syntax errors while you type. See
|ale-cs-mcsc| for the separately configured linter for checking for semantic
errors.
g:ale_cs_mcs_options *g:ale_cs_mcs_options*

View File

@@ -1,6 +1,15 @@
===============================================================================
ALE D Integration *ale-d-options*
===============================================================================
dfmt *ale-d-dfmt*
g:ale_d_dfmt_options *g:ale_d_dfmt_options*
*b:ale_d_dfmt_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the dfmt fixer.
===============================================================================
dls *ale-d-dls*

View File

@@ -184,13 +184,12 @@ tests: https://github.com/junegunn/vader.vim
See |ale-development-linter-tests| for more information on how to write linter
tests.
When you add new linters or fixers, make sure to add them into the table in
the README, and also into the |ale-support| list in the main help file. If you
forget to keep them both in sync, you should see an error like the following
in Travis CI. >
When you add new linters or fixers, make sure to add them into the tables in
supported-tools.md and |ale-supported-languages-and-tools.txt|. If you forget to
keep them both in sync, you should see an error like the following in Travis CI.
>
========================================
diff README.md and doc/ale.txt tables
diff supported-tools.md and doc/ale-supported-languages-and-tools.txt tables
========================================
Differences follow:

View File

@@ -29,23 +29,55 @@ g:ale_elm_format_options *g:ale_elm_format_options*
This variable can be set to pass additional options to elm-format.
===============================================================================
elm-lsp *ale-elm-elm-lsp*
elm-ls *ale-elm-elm-ls*
g:ale_elm_lsp_executable *g:ale_elm_lsp_executable*
*b:ale_elm_lsp_executable*
g:ale_elm_ls_executable *g:ale_elm_ls_executable*
*b:ale_elm_ls_executable*
Type: |String|
Default: `'elm-lsp'`
Default: `'elm-language-server'`
See |ale-integrations-local-executables|
g:ale_elm_lsp_use_global *g:ale_elm_lsp_use_global*
*b:ale_elm_lsp_use_global*
g:ale_elm_ls_use_global *g:ale_elm_ls_use_global*
*b:ale_elm_ls_use_global*
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 0)`
Default: `get(g:, 'ale_use_global_executables', 1)`
See |ale-integrations-local-executables|
g:ale_elm_ls_elm_path *g:ale_elm_ls_elm_path*
*b:ale_elm_ls_elm_path*
Type: |String|
Default: `''`
See |ale-integrations-local-executables|
g:ale_elm_ls_elm_format_path *g:ale_elm_ls_elm_format_path*
*b:ale_elm_ls_elm_format_path*
Type: |String|
Default: `''`
See |ale-integrations-local-executables|
g:ale_elm_ls_elm_test_path *g:ale_elm_ls_elm_test_path*
*b:ale_elm_ls_elm_test_path*
Type: |String|
Default: `''`
See |ale-integrations-local-executables|
g:ale_elm_ls_elm_analyse_trigger *g:ale_elm_ls_elm_analyse_trigger*
*b:ale_elm_ls_elm_analyse_trigger*
Type: |String|
Default: `'change'`
One of 'change', 'save' or 'never'
===============================================================================
elm-make *ale-elm-elm-make*

View File

@@ -30,6 +30,16 @@ g:ale_go_go_executable *g:ale_go_go_options*
the `gomod` fixer.
g:ale_go_go111module *g:ale_go_go111module*
*b:ale_go_go111module*
Type: |String|
Default: `''`
Override the value of the `$GO111MODULE` environment variable for
golang tools.
===============================================================================
bingo *ale-go-bingo*

View File

@@ -2,6 +2,13 @@
ALE Handlebars Integration *ale-handlebars-options*
===============================================================================
prettier *ale-handlebars-prettier*
See |ale-javascript-prettier| for information about the available options.
Uses glimmer parser by default.
===============================================================================
ember-template-lint *ale-handlebars-embertemplatelint*

View File

@@ -12,6 +12,7 @@ g:ale_haskell_brittany_executable *g:ale_haskell_brittany_executable*
This variable can be changed to use a different executable for brittany.
===============================================================================
floskell *ale-haskell-floskell*
@@ -22,6 +23,7 @@ g:ale_haskell_floskell_executable *g:ale_haskell_floskell_executable*
This variable can be changed to use a different executable for floskell.
===============================================================================
ghc *ale-haskell-ghc*
@@ -32,6 +34,7 @@ g:ale_haskell_ghc_options *g:ale_haskell_ghc_options*
This variable can be changed to modify flags given to ghc.
===============================================================================
ghc-mod *ale-haskell-ghc-mod*
@@ -42,6 +45,7 @@ g:ale_haskell_ghc_mod_executable *g:ale_haskell_ghc_mod_executable*
This variable can be changed to use a different executable for ghc-mod.
===============================================================================
cabal-ghc *ale-haskell-cabal-ghc*
@@ -53,6 +57,7 @@ g:ale_haskell_cabal_ghc_options *g:ale_haskell_cabal_ghc_options*
This variable can be changed to modify flags given to ghc through cabal
exec.
===============================================================================
hdevtools *ale-haskell-hdevtools*
@@ -87,6 +92,18 @@ g:ale_haskell_hfmt_executable *g:ale_haskell_hfmt_executable*
This variable can be changed to use a different executable for hfmt.
===============================================================================
hindent *ale-haskell-hindent*
g:ale_haskell_hindent_executable *g:ale_haskell_hindent_executable*
*b:ale_haskell_hindent_executable*
Type: |String|
Default: `'hindent'`
This variable can be changed to use a different executable for hindent.
===============================================================================
hlint *ale-haskell-hlint*
@@ -106,6 +123,7 @@ g:ale_haskell_hlint_options g:ale_haskell_hlint_options
This variable can be used to pass extra options to the underlying hlint
executable.
===============================================================================
stack-build *ale-haskell-stack-build*
@@ -117,6 +135,7 @@ g:ale_haskell_stack_build_options *g:ale_haskell_stack_build_options*
We default to using `'--fast'`. Since Stack generates binaries, your
programs will be slower unless you separately rebuild them outside of ALE.
===============================================================================
stack-ghc *ale-haskell-stack-ghc*
@@ -128,6 +147,7 @@ g:ale_haskell_stack_ghc_options *g:ale_haskell_stack_ghc_options*
This variable can be changed to modify flags given to ghc through `stack
ghc`
===============================================================================
stylish-haskell *ale-haskell-stylish-haskell*
@@ -139,6 +159,7 @@ g:ale_haskell_stylish_haskell_executable
This variable can be changed to use a different executable for stylish-haskell.
===============================================================================
hie *ale-haskell-hie*
@@ -150,5 +171,6 @@ g:ale_haskell_hie_executable *g:ale_haskell_hie_executable*
This variable can be changed to use a different executable for the haskell
ide engine. i.e. `'hie-wrapper'`
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

40
doc/ale-ink.txt Normal file
View File

@@ -0,0 +1,40 @@
===============================================================================
ALE Ink Integration *ale-ink-options*
===============================================================================
ink-language-server *ale-ink-language-server*
Ink Language Server
(https://github.com/ephraim/ink-language-server)
g:ale_ink_ls_executable g:ale_ink_ls_executable
b:ale_ink_ls_executable
Type: |String|
Default: `'ink-language-server'`
Ink language server executable.
g:ale_ink_ls_initialization_options
g:ale_ink_ls_initialization_options
b:ale_ink_ls_initialization_options
Type: |Dictionary|
Default: `{}`
Dictionary containing configuration settings that will be passed to the
language server at startup. For certain platforms and certain story
structures, the defaults will suffice. However, many projects will need to
change these settings - see the ink-language-server website for more
information.
An example of setting non-default options:
{
\ 'ink': {
\ 'mainStoryPath': 'init.ink',
\ 'inklecateExecutablePath': '/usr/local/bin/inklecate',
\ 'runThroughMono': v:false
\ }
\}
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@@ -9,7 +9,7 @@ g:ale_java_checkstyle_config *g:ale_java_checkstyle_config*
*b:ale_java_checkstyle_config*
Type: |String|
Default: `'google_checks.xml'`
Default: `'/google_checks.xml'`
A path to a checkstyle configuration file.
@@ -123,7 +123,7 @@ executable in this directory.
g:ale_java_javalsp_executable *g:ale_java_javalsp_executable*
*b:ale_java_javalsp_executable*
Type: |String|
Default: `'launcher'`
Default: `''`
This variable must be set to the absolute path of the language server launcher
executable. For example:
@@ -131,6 +131,33 @@ executable. For example:
let g:ale_java_javalsp_executable=/java-language-server/dist/mac/bin/launcher
<
g:ale_java_javalsp_config *g:ale_java_javalsp_config*
*b:ale_java_javalsp_config*
Type: |Dictionary|
Default: `{}`
The javalsp linter automatically detects external depenencies for Maven and
Gradle projects. In case the javalsp fails to detect some of them, you can
specify them setting a dictionary to |g:ale_java_javalsp_config| variable.
>
let g:ale_java_javalsp_executable =
\ {
\ 'java': {
\ 'externalDependencies': [
\ 'junit:junit:jar:4.12:test', " Maven format
\ 'junit:junit:4.1' " Gradle format
\ ],
\ 'classPath': [
\ 'lib/some-dependency.jar',
\ '/android-sdk/platforms/android-28.jar'
\ ]
\ }
\ }
The Java language server will look for the dependencies you specify in
`externalDependencies` array in your Maven and Gradle caches ~/.m2 and
~/.gradle.
===============================================================================
eclipselsp *ale-java-eclipselsp*

24
doc/ale-nix.txt Normal file
View File

@@ -0,0 +1,24 @@
===============================================================================
ALE Nix Integration *ale-nix-options*
===============================================================================
nixpkgs-fmt *ale-nix-nixpkgs-fmt*
g:ale_nix_nixpkgsfmt_executable *g:ale_nix_nixpkgsfmt_executable*
*b:ale_nix_nixpkgsfmt_executable*
Type: |String|
Default: `'nixpkgs-fmt'`
This variable sets executable used for nixpkgs-fmt.
g:ale_nix_nixpkgsfmt_options *g:ale_nix_nixpkgsfmt_options*
*b:ale_nix_nixpkgsfmt_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the nixpkgs-fmt fixer.
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@@ -157,9 +157,9 @@ g:ale_php_phpstan_level *g:ale_php_phpstan_level*
Type: |String|
Default: `''`
This variable controls the rule levels. 0 is the loosest and 4 is the
This variable controls the rule levels. 0 is the loosest and 7 is the
strictest. If this option isn't set, the rule level will be controlled by
the configuration file. If no configuration file can be detected, `'4'` will
the configuration file. If no configuration file can be detected, `'7'` will
be used instead.

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