Compare commits

..

9 Commits

Author SHA1 Message Date
w0rp
4c3bd8a84f Revert "Merge pull request #1487 from rhysd/fix-1472"
This reverts commit 67b71653f5.
2018-04-17 13:33:47 +01:00
w0rp
d1224a05c4 #1497 Tolerate important ALE variables being undefined for some reason when viewing buffers like git commits 2018-04-12 21:04:15 +01:00
w0rp
0e4a7a7187 Fix #1495 - Fall back to /bin/sh when shell=pwsh 2018-04-12 21:04:02 +01:00
w0rp
36a3932ce8 Fix #1492 - Make pylint error parsing work on Windows 2018-04-10 15:20:02 +01:00
w0rp
67b71653f5 Merge pull request #1487 from rhysd/fix-1472
pylint: Move to the buffer's directory before running pylint command
2018-04-09 18:15:28 +01:00
aspidiets
229da9b8ef Fix #1424 - Make the brittany fixer work 2018-04-08 17:39:51 +01:00
w0rp
7e4372bd1f Use the --stdin-filename option for textlint, so configuration files will be discovered better 2018-04-05 15:12:24 +01:00
w0rp
f6fc1edcdc Fix config and executable issues with the textlint linter 2018-04-05 15:09:41 +01:00
w0rp
6e5a74285c Merge pull request #1455 from Christian-Gibbons/flawfinder_cpp_severity_fix
Fix Flawfinder for C++
2018-04-05 15:07:12 +01:00
320 changed files with 2103 additions and 8993 deletions

1
.gitattributes vendored
View File

@@ -2,7 +2,6 @@
/CODE_OF_CONDUCT.md export-ignore
/CONTRIBUTING.md export-ignore
/Dockerfile export-ignore
/ISSUE_TEMPLATE export-ignore
/ISSUE_TEMPLATE.md export-ignore
/Makefile export-ignore
/PULL_REQUEST_TEMPLATE.md export-ignore

View File

@@ -1,40 +0,0 @@
---
name: Report a bug
about: Report a bug with ALE.
---
<!--
This is the template for reporting ALE bugs. Make sure you try updating ALE
to a more recent version before reporting a bug. Look through existing bug
reports for similar issues before reporting a new one. Don't leave comments
about new bugs in the comment section for old issues.
Make sure to try disabling other plugins and trying to repeat your bug before
reporting it in ALE. Some times problems can arise when two plugins are used
together, but often your issues might be problems with other plugins.
-->
## Information
**VIM version**
<!-- Paste just the first two lines of :version here. -->
Operating System: <!-- Describe your operating system version. -->
### :ALEInfo
<!-- Paste the output of :ALEInfo here. Try :ALEInfoToClipboard -->
<!-- Make sure to run :ALEInfo from the buffer where the bug occurred. -->
## What went wrong
<!-- Describe what went wrong here. -->
## Reproducing the bug
<!-- Write a list of steps below. -->
1. I did this.
2. Then this happened.

View File

@@ -1,20 +0,0 @@
---
name: Suggest a new linter or fixer
about: Suggest a new tool ALE can officially integrate with.
---
<!--
Write "Add support for foobar" as the issue title, or similar.
Fill out the details below.
-->
**Name:** foobar
**URL:** https://foo.bar.com
<!--
Write a description of the tool, and add any other information you think might
be helpful. Consider creating a pull request to add support for the tool
yourself.
-->

View File

@@ -1,7 +0,0 @@
---
name: Suggest an improvement
about: Suggest some way to improve ALE, or add a new feature.
---
<!-- There's no fixed format for feature requests. Just add your thoughts. -->

7
.gitignore vendored
View File

@@ -1,7 +1,6 @@
/init.vim
/doc/tags
.*
!.editorconfig
*.obj
.*
/doc/tags
/init.vim
/test/ale-info-test-file
tags

View File

@@ -2,6 +2,6 @@
sudo: required
services:
- docker
language: generic
language: python
script: |
./run-tests -v
./run-tests

View File

@@ -1,11 +1,37 @@
## Guidelines
# Contributing to ALE
1. [Guidelines](#guidelines)
2. [Creating Issues](#issues)
3. [Creating Pull Requests](#pull-requests)
1. [Adding a New Linter](#adding-a-new-linter)
2. [Adding New Options](#adding-new-options)
4. [Writing Documentation](#writing-documentation)
1. [Documenting New Linters](#documenting-new-linters)
2. [Editing the Online Documentation](#editing-online-documentation)
3. [Documenting Linter Options](#documenting-linter-options)
5. [In Case of Busses](#in-case-of-busses)
<a name="guidelines"></a>
## 1. Guidelines
Have fun, and work on whatever floats your boat. Take It Easy :tm:.
For help with contributing to ALE, see `:help ale-development` in Vim, or view
the help file online [here](/w0rp/ale/blob/master/doc/ale-development.txt).
Don't forget to **write documentation** for whatever it is you are doing.
See the ["Writing Documentation"](#writing-documentation) section.
## Creating Issues
Remember to write Vader tests for most of the code you write. You can look at
existing Vader tests in the `test` directory for examples.
When writing code, follow the [Google Vimscript Style
Guide](https://google.github.io/styleguide/vimscriptguide.xml), and run `vint
-s` on your files to check for most of what the guide mentions and more. If you
install this plugin (ALE) and install [Vint](https://github.com/Kuniwak/vint), it
will check your code while you type.
<a name="issues"></a>
## 2. Creating Issues
Before creating any issues, please look through the current list of issues and
pull requests, and ensure that the issue hasn't already been reported. If an
@@ -23,3 +49,125 @@ operating system, or any other information you think might be helpful.
Please describe your issue in clear, grammatically correct, and easy to
understand English. You are more likely to see an issue resolved if others
can understand you.
<a name="pull-requests"></a>
## 3. Creating Pull Requests
For code you write, make sure to credit yourself at the top of files you add,
and probably those you modify. You can write some comments at the top of your
VIM files.
```vim
" Author: John Smith <john.smith@gmail.com>
" Description: This file adds support for awesomelinter for the best language ever.
```
If you want to credit multiple authors, you can comma separate them.
```vim
" Author: John Smith <john.smith@gmail.com>, Jane Doe <https://jane-doe.info>
```
<a name="adding-a-new-linter"></a>
### 3.i. Adding a New Linter
If you add a new linter, look for existing handlers first in the
[handlers](autoload/ale/handlers) directory. One of the handlers there may
already be able to handle your lines of output. If you find that your new
linter replicates an existing error handler, consider pulling it up into the
[handlers](autoload/ale/handlers) directory, and use the generic handler in
both places.
When you add a linter, make sure the language for the linter and the linter
itself are present in the table in the [README.md](README.md) file and in the
Vim [help file](doc/ale.txt). The programs and linters should be sorted
alphabetically in the table and list.
<a name="adding-new-options"></a>
### 3.ii. Adding New Options
If you add new options to the plugin, make sure to document those new options
in the [README.md](README.md) file, and also in the [help file](doc/ale.txt).
Follow the format of other options in each. Global options should appear in the
README file, and in the relevant section in the help file. Options specific
to a particular linter should appear in the section for that linter.
Linter options for customizing general argument lists should be named
`g:ale_<filetype>_<linter>_options`, so that all linters can have similar
global variable names.
Any options for linters should be set to some default value so it is always
easy to see what the default is with `:echo g:ale...`.
<a name="writing-documentation"></a>
## 4. Writing Documentation
If you are adding new linters, changing the API, adding new options, etc., you
_must_ write some documentation describing it in the `doc/ale.txt` file. New
linters _must_ be added to the `README.md` file too, so other users can get a
quick overview of the supported tools.
<a name="documenting-new-linters"></a>
### 4.i Documenting New Linters
If you add a new linter to the project, edit the table in the `README.md` file,
and edit the list of linters at the top of the `doc/ale.txt` file. The linters
should be sorted vertically in lexicographic (alphabetical) order by the
programming language name or filetype, and the tools for each language should
be sorted in lexicographic order horizontally. Sorting in this manner is a fair
manner of presenting all of the information in an easy to scan way, without
giving some unfair preference to any particular tool or language.
<a name="editing-online-documentation"></a>
### 4.ii Editing the Online Documentation
The "online documentation" file used for this project lives in `doc/ale.txt`.
This is the file used for generating `:help` text inside Vim itself. There are
some guidelines to follow for this file.
1. Keep all text within a column size of 79 characters, inclusive.
2. Open a section with 79 `=` or `-` characters, for headings and subheadings.
3. Sections should have a _single_ blank line before or after.
4. Between descriptions of variables/functions/commands, use _two_ blank lines.
5. Up-indent the description of a variable/function/command by two spaces.
6. Place tags at the ends of lines, with the final characters on column 79.
All of the tags should line up perfectly on the same column as you scan
down through the document.
7. Keep the table of contents balanced so the longest tag link ends on column
79, and so all links line up perfectly on their first character, on the
left.
<a name="documenting-linter-options"></a>
### 4.iii Documenting Linter Options
For documenting new linter options, please add a new sub-section under the
"Linter Specific Options" section describing all of the global options added
for each linter, and what the default values of the options are. All global
options for linters should be set to some default value. This will allow users
to look up the default value easily by typing `:echo g:ale_...`.
<a name="in-case-of-busses"></a>
## 5. In Case of Busses
Should the principal author of the ALE project and all collaborators with the
required access needed to properly administrate the project on GitHub or any
other website either perish or disappear, whether by tragic traffic accident
or government abduction, etc., action should be taken to ensure that the
project continues. If no one is left to administer the project where it is
hosted, please fork the project and nominate someone capable to administer it.
Preferably, in such an event, a single fork of the project will replace the
original, and life will go on, except the life of whoever vanished, because
then they will probably be dead.
Should w0rp suddenly disappear, then he was probably killed in a traffic
accident, or the government finally decided to kill him and make it look like
suicide. In the latter event, please subvert said government and restore
order to the universe, and ensure peace for mankind.

View File

@@ -1,8 +1,7 @@
FROM tweekmonster/vim-testbed:latest
RUN install_vim -tag v8.0.0027 -build \
-tag neovim:v0.2.0 -build \
-tag neovim:v0.3.0 -build
-tag neovim:v0.1.7 -build
ENV PACKAGES="\
bash \
@@ -13,7 +12,7 @@ ENV PACKAGES="\
RUN apk --update add $PACKAGES && \
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
RUN pip install vim-vint==0.3.15
RUN pip install vim-vint==0.3.9
RUN git clone https://github.com/junegunn/vader.vim vader && \
cd vader && git checkout c6243dd81c98350df4dec608fa972df98fa2a3af

28
ISSUE_TEMPLATE.md Normal file
View File

@@ -0,0 +1,28 @@
<!--
This is a template for bug reports. If you want to request a new feature,
you can clear this entire form field and write a short description of what
you want.
-->
## Information
**VIM version**
PASTE JUST THE FIRST TWO LINES OF `:version` HERE.
Operating System: WHAT OS WERE YOU USING?
### :ALEInfo
PASTE OUTPUT OF `:ALEInfo` HERE. YOU CAN TRY `:ALEInfoToClipboard`.
## What went wrong
WRITE WHAT WENT WRONG HERE.
## Reproducing the bug
Steps for repeating the bug:
1. Write a list of steps.
2. Otherwise nobody will fix the bug.

View File

@@ -1,8 +1,21 @@
<!--
Before creating a pull request, do the following.
READ THIS: Before creating a pull request, please consider the following first.
* The most important thing you can do is write tests. Code without tests
probably doesn't work, and will almost certainly stop working later on. Pull
requests without tests probably won't be accepted, although there are some
exceptions.
* Read the Contributing guide linked above first.
* Read the documentation that comes with ALE with `:help ale-development`.
Have fun!
* If you are adding a new linter, remember to update the README.md file and
doc/ale.txt first.
* If you add or modify a function for converting error lines into loclist items
that ALE can work with, please add Vader tests for them. Look at existing
tests in the test/handler directory, etc.
* If you add or modify a function for computing a command line string for
running a command, please add Vader tests for that.
* Generally try and cover anything with Vader tests, although some things just
can't be tested with Vader, or at least they can be hard to test. Consider
breaking up your code so that some parts can be tested, and generally open up
a discussion about it.
* Have fun!
-->

180
README.md
View File

@@ -4,7 +4,7 @@
![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true)
ALE (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim
0.2.0+ and Vim 8 while you edit your text files.
and Vim 8 while you edit your text files.
![linting example](img/example.gif?raw=true)
@@ -16,22 +16,8 @@ back to a filesystem.
In other words, this plugin allows you to lint while you type.
ALE offers support for fixing code with command line tools in a non-blocking
manner with the `:ALEFix` feature, supporting tools in many languages, like
`prettier`, `eslint`, `autopep8`, and more.
ALE acts as a "language client" to support a variety of Language Server Protocol
features, including:
* Diagnostics (via Language Server Protocol linters)
* Go To Definition (`:ALEGoToDefinition`)
* Completion (`let g:ale_completion_enabled = 1`)
* Finding references (`:ALEFindReferences`)
* Hover information (`:ALEHover`)
If you don't care about Language Server Protocol, ALE won't load any of the code
for working with it unless needed. One of ALE's general missions is that you
won't pay for the features that you don't use.
In addition to linting support, ALE offers some support for fixing code with
formatting tools, and some Language Server Protocol and `tsserver` features.
## Table of Contents
@@ -41,8 +27,6 @@ won't pay for the features that you don't use.
2. [Fixing](#usage-fixing)
3. [Completion](#usage-completion)
4. [Go To Definition](#usage-go-to-definition)
5. [Find References](#usage-find-references)
6. [Hovering](#usage-hover)
3. [Installation](#installation)
1. [Installation with Vim package management](#standard-installation)
2. [Installation with Pathogen](#installation-with-pathogen)
@@ -94,26 +78,24 @@ formatting.
| API Blueprint | [drafter](https://github.com/apiaryio/drafter) |
| AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good) |
| Awk | [gawk](https://www.gnu.org/software/gawk/)|
| Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) |
| Bash | shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) |
| Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) |
| C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) |
| C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) |
| C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) |
| CUDA | [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) |
| C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details, [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) !! see:`help ale-cs-mcsc` for details and configuration|
| Chef | [foodcritic](http://www.foodcritic.io/) |
| Clojure | [joker](https://github.com/candid82/joker) |
| CloudFormation | [cfn-python-lint](https://github.com/awslabs/cfn-python-lint) |
| CMake | [cmakelint](https://github.com/richq/cmake-lint) |
| CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) |
| Crystal | [crystal](https://crystal-lang.org/) !! |
| CSS | [csslint](http://csslint.net/), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) |
| Cucumber | [cucumber](https://cucumber.io/) |
| Cython (pyrex filetype) | [cython](http://cython.org/) |
| D | [dmd](https://dlang.org/dmd-linux.html) |
| Dafny | [dafny](https://rise4fun.com/Dafny) !! |
| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) |
| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server) |
| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) |
| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!|
| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma) !!|
| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) |
| Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) |
| Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) |
@@ -130,8 +112,8 @@ formatting.
| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [stack-ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt) |
| HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) |
| Idris | [idris](http://www.idris-lang.org/) |
| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/) |
| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo)
| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format) |
| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo)
| JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) |
| Kotlin | [kotlinc](https://kotlinlang.org) !!, [ktlint](https://ktlint.github.io) !! see `:help ale-integration-kotlin` for configuration instructions |
| LaTeX | [alex](https://github.com/wooorm/alex) !!, [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) |
@@ -142,15 +124,13 @@ formatting.
| Make | [checkmake](https://github.com/mrtazz/checkmake) |
| Markdown | [alex](https://github.com/wooorm/alex) !!, [markdownlint](https://github.com/DavidAnson/markdownlint) !!, [mdl](https://github.com/mivok/markdownlint), [prettier](https://github.com/prettier/prettier), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [remark-lint](https://github.com/wooorm/remark-lint) !!, [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) |
| MATLAB | [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) |
| Mercury | [mmc](http://mercurylang.org) !! |
| NASM | [nasm](https://www.nasm.us/) !! |
| Nim | [nim check](https://nim-lang.org/docs/nimc.html) !! |
| nix | [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) |
| nroff | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)|
| Objective-C | [clang](http://clang.llvm.org/) |
| Objective-C++ | [clang](http://clang.llvm.org/) |
| OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server) |
| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic), [perltidy](https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy) |
| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic) |
| PHP | [hack](http://hacklang.org/), [hackfmt](https://github.com/facebook/flow/tree/master/hack/hackfmt), [langserver](https://github.com/felixfbecker/php-language-server), [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions, [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), [phpmd](https://phpmd.org), [phpstan](https://github.com/phpstan/phpstan), [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer), [php-cs-fixer](http://cs.sensiolabs.org/) |
| PO | [alex](https://github.com/wooorm/alex) !!, [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html), [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) |
| Pod | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) |
@@ -158,8 +138,8 @@ formatting.
| proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) |
| Pug | [pug-lint](https://github.com/pugjs/pug-lint) |
| Puppet | [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) |
| Python | [autopep8](https://github.com/hhatto/autopep8), [black](https://github.com/ambv/black), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](http://github.com/landscapeio/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pyre](https://github.com/facebook/pyre-check), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) |
| QML | [qmlfmt](https://github.com/jesperhh/qmlfmt), [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) |
| Python | [autopep8](https://github.com/hhatto/autopep8), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](http://github.com/landscapeio/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) |
| QML | [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) |
| R | [lintr](https://github.com/jimhester/lintr) |
| ReasonML | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server), [refmt](https://github.com/reasonml/reason-cli) |
| reStructuredText | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [rstcheck](https://github.com/myint/rstcheck), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) |
@@ -169,7 +149,7 @@ formatting.
| Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) |
| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) |
| SCSS | [prettier](https://github.com/prettier/prettier), [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) |
| Scala | [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html), [scalac](http://scala-lang.org), [scalafmt](https://scalameta.org/scalafmt/), [scalastyle](http://www.scalastyle.org) |
| Scala | [scalac](http://scala-lang.org), [scalastyle](http://www.scalastyle.org) |
| Slim | [slim-lint](https://github.com/sds/slim-lint) |
| SML | [smlnj](http://www.smlnj.org/) |
| Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) |
@@ -215,42 +195,24 @@ ale-linter-options` for options specified to particular linters.
### 2.ii Fixing
ALE can fix files with the `ALEFix` command. Functions need to be configured
either in each buffer with a `b:ale_fixers`, or globally with `g:ale_fixers`.
The recommended way to configure fixers is to define a List in an ftplugin file.
for different filetypes with the `g:ale_fixers` variable. For example, the
following code can be used to fix JavaScript code with ESLint:
```vim
" In ~/.vim/ftplugin/javascript.vim, or somewhere similar.
" Fix files with prettier, and then ESLint.
let b:ale_fixers = ['prettier', 'eslint']
" Equivalent to the above.
let b:ale_fixers = {'javascript': ['prettier', 'eslint']}
```
You can also configure your fixers from vimrc using `g:ale_fixers`, before
or after ALE has been loaded.
```vim
" In ~/.vim/vimrc, or somewhere similar.
" Put this in vimrc or a plugin file of your own.
" After this is configured, :ALEFix will try and fix your JS code with ESLint.
let g:ale_fixers = {
\ 'javascript': ['eslint'],
\}
```
If you want to automatically fix files when you save them, you need to turn
a setting on in vimrc.
```vim
" Set this variable to 1 to fix files when you save them.
" Set this setting in vimrc if you want to fix files automatically on save.
" This is off by default.
let g:ale_fix_on_save = 1
```
The `:ALEFixSuggest` command will suggest some supported tools for fixing code.
Both `g:ale_fixers` and `b:ale_fixers` can also accept functions, including
lambda functions, as fixers, for fixing files with custom tools.
See `:help ale-fix` for complete information on how to fix files with ALE.
The `:ALEFixSuggest` command will suggest some supported tools for fixing code,
but fixers can be also implemented with functions, including lambda functions
too. See `:help ale-fix` for detailed information.
<a name="usage-completion"></a>
@@ -258,7 +220,9 @@ See `:help ale-fix` for complete information on how to fix files with ALE.
ALE offers some support for completion via hijacking of omnicompletion while you
type. All of ALE's completion information must come from Language Server
Protocol linters, or from `tsserver` for TypeScript.
Protocol linters, or similar protocols. At the moment, completion is only
supported for TypeScript code with `tsserver`, when `tsserver` is enabled. You
can enable completion like so:
```vim
" Enable completion where available.
@@ -272,34 +236,10 @@ See `:help ale-completion` for more information.
### 2.iv Go To Definition
ALE supports jumping to the definition of words under your cursor with the
`:ALEGoToDefinition` command using any enabled Language Server Protocol linters
and `tsserver`.
`:ALEGoToDefinition` command using any enabled LSP linters and `tsserver`.
See `:help ale-go-to-definition` for more information.
<a name="usage-find-references"></a>
### 2.v Find References
ALE supports finding references for words under your cursor with the
`:ALEFindReferences` command using any enabled Language Server Protocol linters
and `tsserver`.
See `:help ale-find-references` for more information.
<a name="usage-hover"></a>
### 2.vi Hovering
ALE supports "hover" information for printing brief information about symbols at
the cursor taken from Language Server Protocol linters and `tsserver` with the
`ALEHover` command.
On vim/gvim with `balloon` support you can see the information in a tooltip
that appears under the mouse when you mouseover a symbol.
See `:help ale-hover` for more information.
<a name="installation"></a>
## 3. Installation
@@ -408,28 +348,12 @@ on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels
### 5.i. How do I disable particular linters?
By default, all available tools for all supported languages will be run. If you
want to only select a subset of the tools, you can define `b:ale_linters` for a
single buffer, or `g:ale_linters` globally.
The recommended way to configure linters is to define a List in an ftplugin
file.
By default, all available tools for all supported languages will be run.
If you want to only select a subset of the tools, simply create a
`g:ale_linters` dictionary in your vimrc file mapping filetypes
to lists of linters to run.
```vim
" In ~/.vim/ftplugin/javascript.vim, or somewhere similar.
" Enable ESLint only for JavaScript.
let b:ale_linters = ['eslint']
" Equivalent to the above.
let b:ale_linters = {'javascript': ['eslint']}
```
You can also declare which linters you want to run in your vimrc file, before or
after ALE has been loaded.
```vim
" In ~/.vim/vimrc, or somewhere similar.
let g:ale_linters = {
\ 'javascript': ['eslint'],
\}
@@ -440,14 +364,6 @@ be run for those languages, just as when the dictionary is not defined.
Running many linters should not typically obstruct editing in Vim,
as they will all be executed in separate processes simultaneously.
If you don't want ALE to run anything other than what you've explicitly asked
for, you can set `g:ale_linters_explicit` to `1`.
```vim
" Only run linters named in ale_linters settings.
let g:ale_linters_explicit = 1
```
This plugin will look for linters in the [`ale_linters`](ale_linters) directory.
Each directory within corresponds to a particular filetype in Vim, and each file
in each directory corresponds to the name of a particular linter.
@@ -566,8 +482,6 @@ There are 3 global options that allow customizing the echoed message.
- `g:ale_echo_msg_format` where:
* `%s` is the error message itself
* `%...code...%` is an optional error code, and most characters can be
written between the `%` characters.
* `%linter%` is the linter name
* `%severity` is the severity type
- `g:ale_echo_msg_error_str` is the string used for error severity.
@@ -585,28 +499,22 @@ Will give you:
![Echoed message](img/echo.png)
See `:help g:ale_echo_msg_format` for more information.
<a name="faq-autocmd"></a>
### 5.viii. How can I execute some code when ALE starts or stops linting?
ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html)
events when a lint or fix cycle are started and stopped. There is also an event
that runs when a linter job has been successfully started. These events can be
used to call arbitrary functions during these respective parts of the ALE's
operation.
events when a lint or fix cycle are started and stopped. These events can be
used to call arbitrary functions before and after ALE stops linting.
```vim
augroup YourGroup
autocmd!
autocmd User ALELintPre call YourFunction()
autocmd User ALELintPost call YourFunction()
autocmd User ALELintPre call YourFunction()
autocmd User ALELintPost call YourFunction()
autocmd User ALEJobStarted call YourFunction()
autocmd User ALEFixPre call YourFunction()
autocmd User ALEFixPost call YourFunction()
autocmd User ALEFixPre call YourFunction()
autocmd User ALEFixPost call YourFunction()
augroup END
```
@@ -697,18 +605,9 @@ augroup END
```
Supposing the filetype has been set correctly, you can set the following
options in a jsx.vim ftplugin file.
options in your vimrc file:
```vim
" In ~/.vim/ftplugin/jsx.vim, or somewhere similar.
let b:ale_linters = ['stylelint', 'eslint']
let b:ale_linter_aliases = ['css']
```
Or if you want, you can configure the linters from your vimrc file.
```vim
" In ~/.vim/vimrc, or somewhere similar.
let g:ale_linters = {'jsx': ['stylelint', 'eslint']}
let g:ale_linter_aliases = {'jsx': 'css'}
```
@@ -754,9 +653,8 @@ ALE cannot easily detect which compiler flags to use.
Some tools and build configurations can generate
[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
files. The `cppcheck`, `clangcheck`, `clangtidy` and `cquery` linters can read
these files for automatically determining the appropriate compiler flags to
use.
files. The `cppcheck`, `clangcheck` and `clangtidy` linters can read these
files for automatically determining the appropriate compiler flags to use.
For linting with compilers like `gcc` and `clang`, and with other tools, you
will need to tell ALE which compiler flags to use yourself. You can use

37
after/plugin/ale.vim Normal file
View File

@@ -0,0 +1,37 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Follow-up checks for the plugin: warn about conflicting plugins.
" A flag for ensuring that this is not run more than one time.
if exists('g:loaded_ale_after')
finish
endif
" Set the flag so this file is not run more than one time.
let g:loaded_ale_after = 1
" Check if the flag is available and set to 0 to disable checking for and
" emitting conflicting plugin warnings.
if exists('g:ale_emit_conflict_warnings') && !g:ale_emit_conflict_warnings
finish
endif
" Conflicting Plugins Checks
function! s:GetConflictingPluginWarning(plugin_name) abort
return 'ALE conflicts with ' . a:plugin_name
\ . '. Uninstall it, or disable this warning with '
\ . '`let g:ale_emit_conflict_warnings = 0` in your vimrc file, '
\ . '*before* plugins are loaded.'
endfunction
if exists('g:loaded_syntastic_plugin')
throw s:GetConflictingPluginWarning('Syntastic')
endif
if exists('g:loaded_neomake')
throw s:GetConflictingPluginWarning('Neomake')
endif
if exists('g:loaded_validator_plugin')
throw s:GetConflictingPluginWarning('Validator')
endif

View File

@@ -8,15 +8,15 @@ function! ale_linters#c#clang#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_clang_executable')
endfunction
function! ale_linters#c#clang#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
function! ale_linters#c#clang#GetCommand(buffer) abort
let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#c#clang#GetExecutable(a:buffer))
\ . ' -S -x c -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
\ . l:cflags
\ . ale#c#IncludeOptions(l:paths)
\ . ale#Var(a:buffer, 'c_clang_options') . ' -'
endfunction
@@ -24,9 +24,6 @@ call ale#linter#Define('c', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#c#clang#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#c#clang#GetCommand'}
\ ],
\ 'command_callback': 'ale_linters#c#clang#GetCommand',
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})

View File

@@ -8,15 +8,15 @@ function! ale_linters#c#gcc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_gcc_executable')
endfunction
function! ale_linters#c#gcc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
function! ale_linters#c#gcc#GetCommand(buffer) abort
let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#c#gcc#GetExecutable(a:buffer))
\ . ' -S -x c -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
\ . l:cflags
\ . ale#c#IncludeOptions(l:paths)
\ . ale#Var(a:buffer, 'c_gcc_options') . ' -'
endfunction
@@ -24,9 +24,6 @@ call ale#linter#Define('c', {
\ 'name': 'gcc',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#c#gcc#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#c#gcc#GetCommand'}
\ ],
\ 'command_callback': 'ale_linters#c#gcc#GetCommand',
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})

View File

@@ -1,35 +0,0 @@
" Author: Yasuhiro Kiyota <yasuhiroki.duck@gmail.com>
" Description: Support cfn-python-lint for AWS Cloudformation template file
function! ale_linters#cloudformation#cfn_python_lint#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" sample.template.yaml:96:7:96:15:E3012:Property Resources/Sample/Properties/FromPort should be of type Integer
let l:pattern = '\v^(.*):(\d+):(\d+):(\d+):(\d+):([[:alnum:]]+):(.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:code = l:match[6]
if ale#path#IsBufferPath(a:buffer, l:match[1])
call add(l:output, {
\ 'lnum': l:match[2],
\ 'col': l:match[3],
\ 'end_lnum': l:match[4],
\ 'end_col': l:match[5],
\ 'code': l:code,
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
\ 'text': l:match[7]
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('cloudformation', {
\ 'name': 'cloudformation',
\ 'executable': 'cfn-lint',
\ 'command': 'cfn-lint --template %t --format parseable',
\ 'callback': 'ale_linters#cloudformation#cfn_python_lint#Handle',
\})

View File

@@ -8,15 +8,15 @@ function! ale_linters#cpp#clang#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_clang_executable')
endfunction
function! ale_linters#cpp#clang#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
function! ale_linters#cpp#clang#GetCommand(buffer) abort
let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#cpp#clang#GetExecutable(a:buffer))
\ . ' -S -x c++ -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
\ . l:cflags
\ . ale#c#IncludeOptions(l:paths)
\ . ale#Var(a:buffer, 'cpp_clang_options') . ' -'
endfunction
@@ -24,9 +24,6 @@ call ale#linter#Define('cpp', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#cpp#clang#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#cpp#clang#GetCommand'},
\ ],
\ 'command_callback': 'ale_linters#cpp#clang#GetCommand',
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})

View File

@@ -1,34 +0,0 @@
" Author: Ben Falconer <ben@falconers.me.uk>
" Description: A language server for C++
call ale#Set('cpp_cquery_executable', 'cquery')
call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery'))
function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#cpp#cquery#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_cquery_executable')
endfunction
function! ale_linters#cpp#cquery#GetCommand(buffer) abort
let l:executable = ale_linters#cpp#cquery#GetExecutable(a:buffer)
return ale#Escape(l:executable)
endfunction
function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort
return {'cacheDirectory': ale#Var(a:buffer, 'cpp_cquery_cache_directory')}
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'cquery',
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#cpp#cquery#GetExecutable',
\ 'command_callback': 'ale_linters#cpp#cquery#GetCommand',
\ 'project_root_callback': 'ale_linters#cpp#cquery#GetProjectRoot',
\ 'initialization_options_callback': 'ale_linters#cpp#cquery#GetInitializationOptions',
\ 'language': 'cpp',
\})

View File

@@ -8,26 +8,22 @@ function! ale_linters#cpp#gcc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_gcc_executable')
endfunction
function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
function! ale_linters#cpp#gcc#GetCommand(buffer) abort
let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#cpp#gcc#GetExecutable(a:buffer))
\ . ' -S -x c++ -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
\ . l:cflags
\ . ale#c#IncludeOptions(l:paths)
\ . ale#Var(a:buffer, 'cpp_gcc_options') . ' -'
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'gcc',
\ 'aliases': ['g++'],
\ 'name': 'g++',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#cpp#gcc#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#cpp#gcc#GetCommand'},
\ ],
\ 'command_callback': 'ale_linters#cpp#gcc#GetCommand',
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})

View File

@@ -2,7 +2,7 @@
call ale#Set('css_stylelint_executable', 'stylelint')
call ale#Set('css_stylelint_options', '')
call ale#Set('css_stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('css_stylelint_use_global', 0)
function! ale_linters#css#stylelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'css_stylelint', [

View File

@@ -1,45 +0,0 @@
" Author: Eddie Lebow https://github.com/elebow
" Description: Cucumber, a BDD test tool
function! ale_linters#cucumber#cucumber#GetCommand(buffer) abort
let l:features_dir = ale#path#FindNearestDirectory(a:buffer, 'features')
if !empty(l:features_dir)
let l:features_arg = '-r ' . ale#Escape(l:features_dir)
else
let l:features_arg = ''
endif
return 'cucumber --dry-run --quiet --strict --format=json '
\ . l:features_arg . ' %t'
endfunction
function! ale_linters#cucumber#cucumber#Handle(buffer, lines) abort
try
let l:json = ale#util#FuzzyJSONDecode(a:lines, {})[0]
catch
return []
endtry
let l:output = []
for l:element in get(l:json, 'elements', [])
for l:step in l:element['steps']
if l:step['result']['status'] is# 'undefined'
call add(l:output, {
\ 'lnum': l:step['line'],
\ 'code': 'E',
\ 'text': 'Undefined step'
\})
endif
endfor
endfor
return l:output
endfunction
call ale#linter#Define('cucumber', {
\ 'name': 'cucumber',
\ 'executable': 'cucumber',
\ 'command_callback': 'ale_linters#cucumber#cucumber#GetCommand',
\ 'callback': 'ale_linters#cucumber#cucumber#Handle'
\})

View File

@@ -46,7 +46,7 @@ function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort
endif
endfor
return 'dmd '. join(l:import_list) . ' -o- -wi -vcolumns -c %t'
return 'dmd '. join(l:import_list) . ' -o- -vcolumns -c %t'
endfunction
function! ale_linters#d#dmd#Handle(buffer, lines) abort

View File

@@ -7,6 +7,10 @@ function! ale_linters#dart#language_server#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'dart_language_server_executable')
endfunction
function! ale_linters#dart#language_server#GetLanguage(buffer) abort
return 'dart'
endfunction
function! ale_linters#dart#language_server#GetProjectRoot(buffer) abort
" Note: pub only looks for pubspec.yaml, there's no point in adding
" support for pubspec.yml
@@ -20,6 +24,7 @@ call ale#linter#Define('dart', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#dart#language_server#GetExecutable',
\ 'command_callback': 'ale_linters#dart#language_server#GetExecutable',
\ 'language': 'dart',
\ 'language_callback': 'ale_linters#dart#language_server#GetLanguage',
\ 'project_root_callback': 'ale_linters#dart#language_server#GetProjectRoot',
\})

View File

@@ -1,61 +0,0 @@
" Author: evnu - https://github.com/evnu
" Author: colbydehart - https://github.com/colbydehart
" Description: Mix compile checking for Elixir files
function! ale_linters#elixir#mix#Handle(buffer, lines) abort
" Matches patterns like the following:
"
" Error format
" ** (CompileError) apps/sim/lib/sim/server.ex:87: undefined function update_in/4
"
" TODO: Warning format
" warning: variable "foobar" does not exist and is being expanded to "foobar()", please use parentheses to remove the ambiguity or change the variable name
let l:pattern = '\v\(([^\)]+Error)\) ([^:]+):([^:]+): (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:type = 'E'
let l:text = l:match[4]
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:match[3] + 0,
\ 'col': 0,
\ 'type': l:type,
\ 'text': l:text,
\})
endfor
return l:output
endfunction
function! ale_linters#elixir#mix#FindProjectRoot(buffer) abort
let l:mix_file = ale#path#FindNearestFile(a:buffer, 'mix.exs')
if !empty(l:mix_file)
return fnamemodify(l:mix_file, ':p:h')
endif
return '.'
endfunction
function! ale_linters#elixir#mix#GetCommand(buffer) abort
let l:project_root = ale_linters#elixir#mix#FindProjectRoot(a:buffer)
let l:temp_dir = ale#engine#CreateDirectory(a:buffer)
let l:mix_build_path = has('win32')
\ ? 'set MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) . ' &&'
\ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir)
return ale#path#CdString(l:project_root)
\ . l:mix_build_path
\ . ' mix compile %s'
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'mix',
\ 'executable': 'mix',
\ 'command_callback': 'ale_linters#elixir#mix#GetCommand',
\ 'callback': 'ale_linters#elixir#mix#Handle',
\ 'lint_file': 1,
\})

View File

@@ -1,26 +1,45 @@
" Author: buffalocoder - https://github.com/buffalocoder, soywod - https://github.com/soywod, hecrj - https://github.com/hecrj
" Author: buffalocoder - https://github.com/buffalocoder, soywod - https://github.com/soywod
" Description: Elm linting in Ale. Closely follows the Syntastic checker in https://github.com/ElmCast/elm-vim.
call ale#Set('elm_make_executable', 'elm')
call ale#Set('elm_make_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('elm_make_executable', 'elm-make')
call ale#Set('elm_make_use_global', 0)
function! ale_linters#elm#make#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'elm_make', [
\ 'node_modules/.bin/elm',
\ 'node_modules/.bin/elm-make',
\])
endfunction
function! ale_linters#elm#make#Handle(buffer, lines) abort
let l:output = []
let l:is_windows = has('win32')
let l:temp_dir = l:is_windows ? $TMP : $TMPDIR
let l:unparsed_lines = []
for l:line in a:lines
if l:line[0] is# '{'
" Elm 0.19
call ale_linters#elm#make#HandleElm019Line(l:line, l:output)
elseif l:line[0] is# '['
" Elm 0.18
call ale_linters#elm#make#HandleElm018Line(l:line, l:output)
if l:line[0] is# '['
let l:errors = json_decode(l:line)
for l:error in l:errors
" Check if file is from the temp directory.
" Filters out any errors not related to the buffer.
if l:is_windows
let l:file_is_buffer = l:error.file[0:len(l:temp_dir) - 1] is? l:temp_dir
else
let l:file_is_buffer = l:error.file[0:len(l:temp_dir) - 1] is# l:temp_dir
endif
if l:file_is_buffer
call add(l:output, {
\ 'lnum': l:error.region.start.line,
\ 'col': l:error.region.start.column,
\ 'end_lnum': l:error.region.end.line,
\ 'end_col': l:error.region.end.column,
\ 'type': (l:error.type is? 'error') ? 'E' : 'W',
\ 'text': l:error.overview,
\ 'detail': l:error.overview . "\n\n" . l:error.details
\})
endif
endfor
elseif l:line isnot# 'Successfully generated /dev/null'
call add(l:unparsed_lines, l:line)
endif
@@ -38,142 +57,23 @@ function! ale_linters#elm#make#Handle(buffer, lines) abort
return l:output
endfunction
function! ale_linters#elm#make#HandleElm019Line(line, output) abort
let l:report = json_decode(a:line)
if l:report.type is? 'error'
" General problem
let l:details = ale_linters#elm#make#ParseMessage(l:report.message)
if empty(l:report.path)
let l:report.path = 'Elm'
endif
if ale_linters#elm#make#FileIsBuffer(l:report.path)
call add(a:output, {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': l:details,
\})
else
call add(a:output, {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': l:report.path .' - '. l:details,
\ 'detail': l:report.path ." ----------\n\n". l:details,
\})
endif
else
" Compilation errors
for l:error in l:report.errors
let l:file_is_buffer = ale_linters#elm#make#FileIsBuffer(l:error.path)
for l:problem in l:error.problems
let l:details = ale_linters#elm#make#ParseMessage(l:problem.message)
if l:file_is_buffer
" Buffer module has problems
call add(a:output, {
\ 'lnum': l:problem.region.start.line,
\ 'col': l:problem.region.start.column,
\ 'end_lnum': l:problem.region.end.line,
\ 'end_col': l:problem.region.end.column,
\ 'type': 'E',
\ 'text': l:details,
\})
else
" Imported module has problems
let l:location = l:error.path .':'. l:problem.region.start.line
call add(a:output, {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': l:location .' - '. l:details,
\ 'detail': l:location ." ----------\n\n". l:details,
\})
endif
endfor
endfor
endif
endfunction
function! ale_linters#elm#make#HandleElm018Line(line, output) abort
let l:errors = json_decode(a:line)
for l:error in l:errors
let l:file_is_buffer = ale_linters#elm#make#FileIsBuffer(l:error.file)
if l:file_is_buffer
" Current buffer has problems
call add(a:output, {
\ 'lnum': l:error.region.start.line,
\ 'col': l:error.region.start.column,
\ 'end_lnum': l:error.region.end.line,
\ 'end_col': l:error.region.end.column,
\ 'type': (l:error.type is? 'error') ? 'E' : 'W',
\ 'text': l:error.overview,
\ 'detail': l:error.overview . "\n\n" . l:error.details
\})
elseif l:error.type is? 'error'
" Imported module has errors
let l:location = l:error.file .':'. l:error.region.start.line
call add(a:output, {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': l:location .' - '. l:error.overview,
\ 'detail': l:location ." ----------\n\n". l:error.overview . "\n\n" . l:error.details
\})
endif
endfor
endfunction
function! ale_linters#elm#make#FileIsBuffer(path) abort
let l:is_windows = has('win32')
let l:temp_dir = l:is_windows ? $TMP : $TMPDIR
if has('win32')
return a:path[0:len(l:temp_dir) - 1] is? l:temp_dir
else
return a:path[0:len(l:temp_dir) - 1] is# l:temp_dir
endif
endfunction
function! ale_linters#elm#make#ParseMessage(message) abort
return join(map(copy(a:message), 'ale_linters#elm#make#ParseMessageItem(v:val)'), '')
endfunction
function! ale_linters#elm#make#ParseMessageItem(item) abort
if type(a:item) == type('')
return a:item
else
return a:item.string
endif
endfunction
" Return the command to execute the linter in the projects directory.
" If it doesn't, then this will fail when imports are needed.
function! ale_linters#elm#make#GetCommand(buffer) abort
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
let l:elm_package = ale#path#FindNearestFile(a:buffer, 'elm-package.json')
let l:elm_exe = ale_linters#elm#make#GetExecutable(a:buffer)
if empty(l:elm_json)
" Fallback to Elm 0.18
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm-package.json')
endif
if empty(l:elm_json)
if empty(l:elm_package)
let l:dir_set_cmd = ''
else
let l:root_dir = fnamemodify(l:elm_json, ':p:h')
let l:root_dir = fnamemodify(l:elm_package, ':p:h')
let l:dir_set_cmd = 'cd ' . ale#Escape(l:root_dir) . ' && '
endif
" The elm compiler, at the time of this writing, uses '/dev/null' as
" The elm-make compiler, at the time of this writing, uses '/dev/null' as
" a sort of flag to tell the compiler not to generate an output file,
" which is why this is hard coded here.
" Source: https://github.com/elm-lang/elm-compiler/blob/19d5a769b30ec0b2fc4475985abb4cd94cd1d6c3/builder/src/Generate/Output.hs#L253
" which is why this is hard coded here. It does not use NUL on Windows.
" Source: https://github.com/elm-lang/elm-make/blob/master/src/Flags.hs
let l:elm_cmd = ale#Escape(l:elm_exe)
\ . ' make'
\ . ' --report=json'
\ . ' --output=/dev/null'

View File

@@ -4,7 +4,7 @@
let g:ale_gitcommit_gitlint_executable =
\ get(g:, 'ale_gitcommit_gitlint_executable', 'gitlint')
let g:ale_gitcommit_gitlint_options = get(g:, 'ale_gitcommit_gitlint_options', '')
let g:ale_gitcommit_gitlint_use_global = get(g:, 'ale_gitcommit_gitlint_use_global', get(g:, 'ale_use_global_executables', 0))
let g:ale_gitcommit_gitlint_use_global = get(g:, 'ale_gitcommit_gitlint_use_global', 0)
function! ale_linters#gitcommit#gitlint#GetExecutable(buffer) abort
@@ -28,10 +28,6 @@ function! ale_linters#gitcommit#gitlint#Handle(buffer, lines) abort
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:code = l:match[2]
if l:code is# 'T2' && !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
continue
endif
let l:item = {
\ 'lnum': l:match[1] + 0,
\ 'text': l:match[3],

View File

@@ -18,6 +18,10 @@ function! ale_linters#glsl#glslls#GetCommand(buffer) abort
return ale#Escape(l:executable) . l:logfile_args . ' --stdin'
endfunction
function! ale_linters#glsl#glslls#GetLanguage(buffer) abort
return 'glsl'
endfunction
function! ale_linters#glsl#glslls#GetProjectRoot(buffer) abort
let l:project_root = ale#c#FindProjectRoot(a:buffer)
@@ -29,6 +33,6 @@ call ale#linter#Define('glsl', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#glsl#glslls#GetExecutable',
\ 'command_callback': 'ale_linters#glsl#glslls#GetCommand',
\ 'language': 'glsl',
\ 'language_callback': 'ale_linters#glsl#glslls#GetLanguage',
\ 'project_root_callback': 'ale_linters#glsl#glslls#GetProjectRoot',
\})

View File

@@ -2,7 +2,7 @@
" Description: Ember-template-lint for checking Handlebars files
call ale#Set('handlebars_embertemplatelint_executable', 'ember-template-lint')
call ale#Set('handlebars_embertemplatelint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('handlebars_embertemplatelint_use_global', 0)
function! ale_linters#handlebars#embertemplatelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'handlebars_embertemplatelint', [

View File

@@ -2,7 +2,7 @@
" Description: hdevtools for Haskell files
call ale#Set('haskell_hdevtools_executable', 'hdevtools')
call ale#Set('haskell_hdevtools_options', get(g:, 'hdevtools_options', '-g -Wall'))
call ale#Set('haskell_hdevtools_options', '-g -Wall')
function! ale_linters#haskell#hdevtools#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'haskell_hdevtools_executable')

View File

@@ -3,7 +3,7 @@
call ale#Set('html_htmlhint_options', '')
call ale#Set('html_htmlhint_executable', 'htmlhint')
call ale#Set('html_htmlhint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('html_htmlhint_use_global', 0)
function! ale_linters#html#htmlhint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'html_htmlhint', [

View File

@@ -1,8 +1,11 @@
" Author: KabbAmine <amine.kabb@gmail.com>
" Description: This file adds support for checking HTML code with tidy.
" CLI options
let g:ale_html_tidy_executable = get(g:, 'ale_html_tidy_executable', 'tidy')
let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', '-q -e -language en')
" Look for the old _args variable first.
let s:default_options = get(g:, 'ale_html_tidy_args', '-q -e -language en')
let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', s:default_options)
function! ale_linters#html#tidy#GetCommand(buffer) abort
" Specify file encoding in options

View File

@@ -3,9 +3,8 @@
let s:classpath_sep = has('unix') ? ':' : ';'
call ale#Set('java_javac_executable', 'javac')
call ale#Set('java_javac_options', '')
call ale#Set('java_javac_classpath', '')
let g:ale_java_javac_options = get(g:, 'ale_java_javac_options', '')
let g:ale_java_javac_classpath = get(g:, 'ale_java_javac_classpath', '')
function! ale_linters#java#javac#GetImportPaths(buffer) abort
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
@@ -36,10 +35,6 @@ function! s:BuildClassPathOption(buffer, import_paths) abort
\ : ''
endfunction
function! ale_linters#java#javac#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'java_javac_executable')
endfunction
function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort
let l:cp_option = s:BuildClassPathOption(a:buffer, a:import_paths)
let l:sp_option = ''
@@ -77,13 +72,11 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort
" Create .class files in a temporary directory, which we will delete later.
let l:class_file_directory = ale#engine#CreateDirectory(a:buffer)
let l:executable = ale_linters#java#javac#GetExecutable(a:buffer)
" Always run javac from the directory the file is in, so we can resolve
" relative paths correctly.
return ale#path#BufferCdString(a:buffer)
\ . ale#Escape(l:executable)
\ . ' -Xlint'
\ . 'javac -Xlint'
\ . ' ' . l:cp_option
\ . ' ' . l:sp_option
\ . ' -d ' . ale#Escape(l:class_file_directory)
@@ -126,7 +119,7 @@ endfunction
call ale#linter#Define('java', {
\ 'name': 'javac',
\ 'executable_callback': 'ale_linters#java#javac#GetExecutable',
\ 'executable': 'javac',
\ 'command_chain': [
\ {'callback': 'ale_linters#java#javac#GetImportPaths', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#java#javac#GetCommand', 'output_stream': 'stderr'},

View File

@@ -1,36 +0,0 @@
" Author: Johannes Wienke <languitar@semipol.de>
" Description: PMD for Java files
function! ale_linters#java#pmd#Handle(buffer, lines) abort
let l:pattern = '"\(\d\+\)",".\+","\(.\+\)","\(\d\+\)","\(\d\+\)","\(.\+\)","\(.\+\)","\(.\+\)"$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'type': 'W',
\ 'lnum': l:match[4] + 0,
\ 'text': l:match[5],
\ 'code': l:match[6] . ' - ' . l:match[7],
\})
endfor
return l:output
endfunction
function! ale_linters#java#pmd#GetCommand(buffer) abort
return 'pmd '
\ . ale#Var(a:buffer, 'java_pmd_options')
\ . ' -f csv'
\ . ' -d %t'
endfunction
if !exists('g:ale_java_pmd_options')
let g:ale_java_pmd_options = '-R category/java/bestpractices.xml'
endif
call ale#linter#Define('java', {
\ 'name': 'pmd',
\ 'executable': 'pmd',
\ 'command_callback': 'ale_linters#java#pmd#GetCommand',
\ 'callback': 'ale_linters#java#pmd#Handle',
\})

View File

@@ -4,8 +4,7 @@
call ale#Set('javascript_flow_executable', 'flow')
call ale#Set('javascript_flow_use_home_config', 0)
call ale#Set('javascript_flow_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('javascript_flow_use_respect_pragma', 1)
call ale#Set('javascript_flow_use_global', 0)
function! ale_linters#javascript#flow#GetExecutable(buffer) abort
let l:flow_config = ale#path#FindNearestFile(a:buffer, '.flowconfig')
@@ -48,8 +47,8 @@ function! ale_linters#javascript#flow#GetCommand(buffer, version_lines) abort
" If we can parse the version number, then only use --respect-pragma
" if the version is >= 0.36.0, which added the argument.
let l:use_respect_pragma = ale#Var(a:buffer, 'javascript_flow_use_respect_pragma')
\ && (empty(l:version) || ale#semver#GTE(l:version, [0, 36]))
let l:use_respect_pragma = empty(l:version)
\ || ale#semver#GTE(l:version, [0, 36])
return ale#Escape(l:executable)
\ . ' check-contents'

View File

@@ -2,7 +2,7 @@
" Description: jscs for JavaScript files
call ale#Set('javascript_jscs_executable', 'jscs')
call ale#Set('javascript_jscs_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('javascript_jscs_use_global', 0)
function! ale_linters#javascript#jscs#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_jscs', [

View File

@@ -2,7 +2,7 @@
" Description: JSHint for Javascript files
call ale#Set('javascript_jshint_executable', 'jshint')
call ale#Set('javascript_jshint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('javascript_jshint_use_global', 0)
function! ale_linters#javascript#jshint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_jshint', [

View File

@@ -2,7 +2,7 @@
" Description: standardjs for JavaScript files
call ale#Set('javascript_standard_executable', 'standard')
call ale#Set('javascript_standard_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('javascript_standard_use_global', 0)
call ale#Set('javascript_standard_options', '')
function! ale_linters#javascript#standard#GetExecutable(buffer) abort

View File

@@ -1,26 +0,0 @@
" Author: Chaucerbao, w0rp <devw0rp@gmail.com>
" Description: tsserver integration for ALE
call ale#Set('javascript_tsserver_executable', 'tsserver')
call ale#Set('javascript_tsserver_config_path', '')
call ale#Set('javascript_tsserver_use_global', get(g:, 'ale_use_global_executables', 0))
" These functions need to be defined just to comply with the API for LSP.
function! ale_linters#javascript#tsserver#GetProjectRoot(buffer) abort
return ''
endfunction
function! ale_linters#javascript#tsserver#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_tsserver', [
\ 'node_modules/.bin/tsserver',
\])
endfunction
call ale#linter#Define('javascript', {
\ 'name': 'tsserver',
\ 'lsp': 'tsserver',
\ 'executable_callback': 'ale_linters#javascript#tsserver#GetExecutable',
\ 'command_callback': 'ale_linters#javascript#tsserver#GetExecutable',
\ 'project_root_callback': 'ale_linters#javascript#tsserver#GetProjectRoot',
\ 'language': '',
\})

View File

@@ -2,7 +2,7 @@
" Description: xo for JavaScript files
call ale#Set('javascript_xo_executable', 'xo')
call ale#Set('javascript_xo_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('javascript_xo_use_global', 0)
call ale#Set('javascript_xo_options', '')
function! ale_linters#javascript#xo#GetExecutable(buffer) abort

View File

@@ -3,7 +3,7 @@
call ale#Set('less_lessc_executable', 'lessc')
call ale#Set('less_lessc_options', '')
call ale#Set('less_lessc_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('less_lessc_use_global', 0)
function! ale_linters#less#lessc#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'less_lessc', [

View File

@@ -2,7 +2,7 @@
call ale#Set('less_stylelint_executable', 'stylelint')
call ale#Set('less_stylelint_options', '')
call ale#Set('less_stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('less_stylelint_use_global', 0)
function! ale_linters#less#stylelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'less_stylelint', [

View File

@@ -10,13 +10,9 @@ endfunction
function! ale_linters#markdown#mdl#GetCommand(buffer) abort
let l:executable = ale_linters#markdown#mdl#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'bundle$'
\ ? ' exec mdl'
\ : ''
let l:options = ale#Var(a:buffer, 'markdown_mdl_options')
return ale#Escape(l:executable) . l:exec_args
return ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
endfunction

View File

@@ -1,45 +0,0 @@
" Author: stewy33 <slocumstewy@gmail.com>
" Description: Lints mercury files using mmc
call ale#Set('mercury_mmc_executable', 'mmc')
call ale#Set('mercury_mmc_options', '--make --output-compile-error-lines 100')
function! ale_linters#mercury#mmc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'mercury_mmc_executable')
endfunction
function! ale_linters#mercury#mmc#GetCommand(buffer) abort
let l:module_name = expand('#' . a:buffer . ':t:r')
return ale#path#BufferCdString(a:buffer)
\ . ale_linters#mercury#mmc#GetExecutable(a:buffer)
\ . ' --errorcheck-only '
\ . ale#Var(a:buffer, 'mercury_mmc_options')
\ . ' ' . l:module_name
endfunction
function! ale_linters#mercury#mmc#Handle(buffer, lines) abort
" output format
" <filename>:<line>: <issue type>: <message>
let l:pattern = '\v^\w+\.m:(\d+):\s+([W|w]arning|.*[E|e]rror.*): (.*)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': substitute(l:match[1], '\v^0*', '', '') + 0,
\ 'type': l:match[2][0] =~? 'W' ? 'W' : 'E',
\ 'text': l:match[2] . ': ' . l:match[3]
\})
endfor
return l:output
endfunction
call ale#linter#Define('mercury', {
\ 'name': 'mmc',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#mercury#mmc#GetExecutable',
\ 'command_callback': 'ale_linters#mercury#mmc#GetCommand',
\ 'callback': 'ale_linters#mercury#mmc#Handle',
\ 'lint_file': 1,
\})

View File

@@ -1,50 +0,0 @@
" Author: Oyvind Ingvaldsen <oyvind.ingvaldsen@gmail.com>
" Description: NASM linter for asmsyntax nasm.
call ale#Set('nasm_nasm_executable', 'nasm')
call ale#Set('nasm_nasm_options', '')
function! ale_linters#nasm#nasm#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'nasm_nasm_executable')
endfunction
function! ale_linters#nasm#nasm#GetOptions(buffer) abort
return ale#Var(a:buffer, 'nasm_nasm_options')
endfunction
function! ale_linters#nasm#nasm#GetCommand(buffer) abort
" Note that NASM require a trailing slash to the -I option.
let l:executable = ale#Escape(ale_linters#nasm#nasm#GetExecutable(a:buffer))
let l:separator = has('win32') ? '\' : '/'
let l:path = ale#Escape(fnamemodify(bufname(a:buffer), ':p:h') . l:separator)
let l:options = ale_linters#nasm#nasm#GetOptions(a:buffer)
return l:executable
\ . ' -X gnu'
\ . ' -I ' . l:path
\ . ' ' . l:options
\ . ' %s'
endfunction
function! ale_linters#nasm#nasm#Handle(buffer, lines) abort
" Note that we treat 'fatal' as errors.
let l:pattern = '^.\+:\(\d\+\): \([^:]\+\): \(.\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'type': l:match[2] =~? 'error\|fatal' ? 'E' : 'W',
\ 'text': l:match[3],
\})
endfor
return l:output
endfunction
call ale#linter#Define('nasm', {
\ 'name': 'nasm',
\ 'executable': 'nasm',
\ 'output_stream': 'stderr',
\ 'lint_file': 1,
\ 'command_callback': 'ale_linters#nasm#nasm#GetCommand',
\ 'callback': 'ale_linters#nasm#nasm#Handle',
\})

View File

@@ -2,7 +2,7 @@
" Description: A language server for OCaml
call ale#Set('ocaml_ols_executable', 'ocaml-language-server')
call ale#Set('ocaml_ols_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('ocaml_ols_use_global', 0)
call ale#linter#Define('ocaml', {
\ 'name': 'ols',

View File

@@ -18,9 +18,9 @@ function! ale_linters#perl#perlcritic#GetExecutable(buffer) abort
endfunction
function! ale_linters#perl#perlcritic#GetProfile(buffer) abort
" first see if we've been overridden
let l:profile = ale#Var(a:buffer, 'perl_perlcritic_profile')
if l:profile is? ''
return ''
endif
@@ -31,7 +31,6 @@ endfunction
function! ale_linters#perl#perlcritic#GetCommand(buffer) abort
let l:critic_verbosity = '%l:%c %m\n'
if ale#Var(a:buffer, 'perl_perlcritic_showrules')
let l:critic_verbosity = '%l:%c %m [%p]\n'
endif
@@ -39,11 +38,17 @@ function! ale_linters#perl#perlcritic#GetCommand(buffer) abort
let l:profile = ale_linters#perl#perlcritic#GetProfile(a:buffer)
let l:options = ale#Var(a:buffer, 'perl_perlcritic_options')
return ale#Escape(ale_linters#perl#perlcritic#GetExecutable(a:buffer))
\ . ' --verbose ' . ale#Escape(l:critic_verbosity)
\ . ' --nocolor'
\ . (!empty(l:profile) ? ' --profile ' . ale#Escape(l:profile) : '')
\ . (!empty(l:options) ? ' ' . l:options : '')
let l:command = ale#Escape(ale_linters#perl#perlcritic#GetExecutable(a:buffer))
\ . " --verbose '". l:critic_verbosity . "' --nocolor"
if l:profile isnot? ''
let l:command .= ' --profile ' . ale#Escape(l:profile)
endif
if l:options isnot? ''
let l:command .= ' ' . l:options
endif
return l:command
endfunction

View File

@@ -2,7 +2,7 @@
" Description: PHP Language server integration for ALE
call ale#Set('php_langserver_executable', 'php-language-server.php')
call ale#Set('php_langserver_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('php_langserver_use_global', 0)
function! ale_linters#php#langserver#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'php_langserver', [
@@ -14,6 +14,10 @@ function! ale_linters#php#langserver#GetCommand(buffer) abort
return 'php ' . ale#Escape(ale_linters#php#langserver#GetExecutable(a:buffer))
endfunction
function! ale_linters#php#langserver#GetLanguage(buffer) abort
return 'php'
endfunction
function! ale_linters#php#langserver#GetProjectRoot(buffer) abort
let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
@@ -25,6 +29,6 @@ call ale#linter#Define('php', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#php#langserver#GetExecutable',
\ 'command_callback': 'ale_linters#php#langserver#GetCommand',
\ 'language': 'php',
\ 'language_callback': 'ale_linters#php#langserver#GetLanguage',
\ 'project_root_callback': 'ale_linters#php#langserver#GetProjectRoot',
\})

View File

@@ -1,65 +1,28 @@
" Author: diegoholiveira <https://github.com/diegoholiveira>, haginaga <https://github.com/haginaga>
" Author: diegoholiveira <https://github.com/diegoholiveira>
" Description: static analyzer for PHP
" Define the minimum severity
let g:ale_php_phan_minimum_severity = get(g:, 'ale_php_phan_minimum_severity', 0)
let g:ale_php_phan_executable = get(g:, 'ale_php_phan_executable', 'phan')
let g:ale_php_phan_use_client = get(g:, 'ale_php_phan_use_client', 0)
function! ale_linters#php#phan#GetExecutable(buffer) abort
let l:executable = ale#Var(a:buffer, 'php_phan_executable')
if ale#Var(a:buffer, 'php_phan_use_client') == 1 && l:executable is# 'phan'
let l:executable = 'phan_client'
endif
return l:executable
endfunction
function! ale_linters#php#phan#GetCommand(buffer) abort
if ale#Var(a:buffer, 'php_phan_use_client') == 1
let l:args = '-l '
\ . ' %s'
else
let l:args = '-y '
\ . ale#Var(a:buffer, 'php_phan_minimum_severity')
\ . ' %s'
endif
let l:executable = ale_linters#php#phan#GetExecutable(a:buffer)
return ale#Escape(l:executable) . ' ' . l:args
return 'phan -y '
\ . ale#Var(a:buffer, 'php_phan_minimum_severity')
\ . ' %s'
endfunction
function! ale_linters#php#phan#Handle(buffer, lines) abort
" Matches against lines like the following:
if ale#Var(a:buffer, 'php_phan_use_client') == 1
" Phan error: ERRORTYPE: message in /path/to/some-filename.php on line nnn
let l:pattern = '^Phan error: \(\w\+\): \(.\+\) in \(.\+\) on line \(\d\+\)$'
else
" /path/to/some-filename.php:18 ERRORTYPE message
let l:pattern = '^.*:\(\d\+\)\s\(\w\+\)\s\(.\+\)$'
endif
"
" /path/to/some-filename.php:18 ERRORTYPE message
let l:pattern = '^.*:\(\d\+\)\s\(\w\+\)\s\(.\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
if ale#Var(a:buffer, 'php_phan_use_client') == 1
let l:dict = {
\ 'lnum': l:match[4] + 0,
\ 'text': l:match[2],
\ 'type': 'W',
\}
else
let l:dict = {
\ 'lnum': l:match[1] + 0,
\ 'text': l:match[3],
\ 'type': 'W',
\}
endif
call add(l:output, l:dict)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'text': l:match[3],
\ 'type': 'W',
\})
endfor
return l:output
@@ -67,7 +30,7 @@ endfunction
call ale#linter#Define('php', {
\ 'name': 'phan',
\ 'executable_callback': 'ale_linters#php#phan#GetExecutable',
\ 'executable': 'phan',
\ 'command_callback': 'ale_linters#php#phan#GetCommand',
\ 'callback': 'ale_linters#php#phan#Handle',
\})

View File

@@ -4,7 +4,7 @@
let g:ale_php_phpcs_standard = get(g:, 'ale_php_phpcs_standard', '')
call ale#Set('php_phpcs_executable', 'phpcs')
call ale#Set('php_phpcs_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('php_phpcs_use_global', 0)
function! ale_linters#php#phpcs#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'php_phpcs', [

View File

@@ -1,30 +1,10 @@
" Author: Cian Butler https://github.com/butlerx
" Description: msgfmt for PO files
function! ale_linters#po#msgfmt#Handle(buffer, lines) abort
let l:results = ale#handlers#unix#HandleAsWarning(a:buffer, a:lines)
let l:index = 0
for l:item in l:results
if l:index > 0 && l:item.text =~? 'this is the location of the first definition'
let l:last_item = l:results[l:index - 1]
if l:last_item.text =~? 'duplicate message definition'
let l:last_item.text = 'duplicate of message at line ' . l:item.lnum
let l:item.text = 'first location of duplicate of message at line ' . l:last_item.lnum
endif
endif
let l:index += 1
endfor
return l:results
endfunction
call ale#linter#Define('po', {
\ 'name': 'msgfmt',
\ 'executable': 'msgfmt',
\ 'output_stream': 'stderr',
\ 'command': 'msgfmt --statistics --output-file=- %t',
\ 'callback': 'ale_linters#po#msgfmt#Handle',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})

View File

@@ -3,7 +3,7 @@
call ale#Set('pug_puglint_options', '')
call ale#Set('pug_puglint_executable', 'pug-lint')
call ale#Set('pug_puglint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('pug_puglint_use_global', 0)
function! ale_linters#pug#puglint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'pug_puglint', [

View File

@@ -4,15 +4,14 @@ function! ale_linters#puppet#puppet#Handle(buffer, lines) abort
" Matches patterns like the following:
" Error: Could not parse for environment production: Syntax error at ':' at /root/puppetcode/modules/nginx/manifests/init.pp:43:12
" Error: Could not parse for environment production: Syntax error at '='; expected '}' at /root/puppetcode/modules/pancakes/manifests/init.pp:5"
" Error: Could not parse for environment production: Syntax error at 'parameter1' (file: /tmp/modules/mariadb/manifests/slave.pp, line: 4, column: 5)
let l:pattern = '^Error: .*: \(.\+\) \((file:\|at\) .\+\.pp\(, line: \|:\)\(\d\+\)\(, column: \|:\)\=\(\d*\)'
let l:pattern = '^Error: .*: \(.\+\) at .\+\.pp:\(\d\+\):\=\(\d*\)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[4] + 0,
\ 'col': l:match[6] + 0,
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[1],
\})
endfor

View File

@@ -1,43 +1,10 @@
" Author: w0rp <devw0rp@gmail.com>,
" Nicolas Pauss <https://github.com/nicopauss>
" Author: w0rp <devw0rp@gmail.com>
" Description: cython syntax checking for cython files.
call ale#Set('pyrex_cython_executable', 'cython')
call ale#Set('pyrex_cython_options', '--warning-extra')
function! ale_linters#pyrex#cython#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'pyrex_cython_executable')
endfunction
function! ale_linters#pyrex#cython#GetCommand(buffer) abort
let l:local_dir = ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
return ale#Escape(ale_linters#pyrex#cython#GetExecutable(a:buffer))
\ . ' --working ' . l:local_dir . ' --include-dir ' . l:local_dir
\ . ' ' . ale#Var(a:buffer, 'pyrex_cython_options')
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'
endfunction
function! ale_linters#pyrex#cython#Handle(buffer, lines) abort
let l:pattern = '\v^(\w+: )?[^:]+:(\d+):?(\d+)?:? ?(.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4],
\ 'type': l:match[1][0] is# 'w' ? 'W' : 'E',
\})
endfor
return l:output
endfunction
call ale#linter#Define('pyrex', {
\ 'name': 'cython',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#pyrex#cython#GetExecutable',
\ 'command_callback': 'ale_linters#pyrex#cython#GetCommand',
\ 'callback': 'ale_linters#pyrex#cython#Handle',
\ 'executable': 'cython',
\ 'command': 'cython --warning-extra -o ' . g:ale#util#nul_file . ' %t',
\ 'callback': 'ale#handlers#unix#HandleAsError',
\})

View File

@@ -1,10 +1,14 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: flake8 for python files
call ale#Set('python_flake8_executable', 'flake8')
call ale#Set('python_flake8_options', '')
call ale#Set('python_flake8_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_flake8_change_directory', 1)
let g:ale_python_flake8_executable =
\ get(g:, 'ale_python_flake8_executable', 'flake8')
" Support an old setting as a fallback.
let s:default_options = get(g:, 'ale_python_flake8_args', '')
let g:ale_python_flake8_options =
\ get(g:, 'ale_python_flake8_options', s:default_options)
let g:ale_python_flake8_use_global = get(g:, 'ale_python_flake8_use_global', 0)
function! s:UsingModule(buffer) abort
return ale#Var(a:buffer, 'python_flake8_options') =~# ' *-m flake8'
@@ -35,16 +39,9 @@ function! ale_linters#python#flake8#VersionCheck(buffer) abort
endfunction
function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory')
\ ? ale#path#BufferCdString(a:buffer)
\ : ''
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run flake8'
\ : ''
" Only include the --stdin-display-name argument if we can parse the
" flake8 version, and it is recent enough to support it.
let l:display_name_args = ale#semver#GTE(l:version, [3, 0, 0])
@@ -53,8 +50,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
let l:options = ale#Var(a:buffer, 'python_flake8_options')
return l:cd_string
\ . ale#Escape(l:executable) . l:exec_args
return ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --format=default'
\ . l:display_name_args . ' -'

View File

@@ -4,7 +4,7 @@
call ale#Set('python_mypy_executable', 'mypy')
call ale#Set('python_mypy_ignore_invalid_syntax', 0)
call ale#Set('python_mypy_options', '')
call ale#Set('python_mypy_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_mypy_use_global', 0)
function! ale_linters#python#mypy#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_mypy', ['mypy'])
@@ -23,14 +23,10 @@ function! ale_linters#python#mypy#GetCommand(buffer) abort
let l:dir = s:GetDir(a:buffer)
let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run mypy'
\ : ''
" We have to always switch to an explicit directory for a command so
" we can know with certainty the base path for the 'filename' keys below.
return ale#path#CdString(l:dir)
\ . ale#Escape(l:executable) . l:exec_args
\ . ale#Escape(l:executable)
\ . ' --show-column-numbers '
\ . ale#Var(a:buffer, 'python_mypy_options')
\ . ' --shadow-file %s %t %s'

View File

@@ -7,21 +7,14 @@ let g:ale_python_prospector_executable =
let g:ale_python_prospector_options =
\ get(g:, 'ale_python_prospector_options', '')
let g:ale_python_prospector_use_global = get(g:, 'ale_python_prospector_use_global', get(g:, 'ale_use_global_executables', 0))
let g:ale_python_prospector_use_global = get(g:, 'ale_python_prospector_use_global', 0)
function! ale_linters#python#prospector#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_prospector', ['prospector'])
endfunction
function! ale_linters#python#prospector#GetCommand(buffer) abort
let l:executable = ale_linters#python#prospector#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run prospector'
\ : ''
return ale#Escape(l:executable)
\ . l:exec_args
return ale#Escape(ale_linters#python#prospector#GetExecutable(a:buffer))
\ . ' ' . ale#Var(a:buffer, 'python_prospector_options')
\ . ' --messages-only --absolute-paths --zero-exit --output-format json'
\ . ' %s'
@@ -30,10 +23,6 @@ endfunction
function! ale_linters#python#prospector#Handle(buffer, lines) abort
let l:output = []
if empty(a:lines)
return []
endif
let l:prospector_error = json_decode(join(a:lines, ''))
for l:error in l:prospector_error.messages

View File

@@ -3,20 +3,14 @@
call ale#Set('python_pycodestyle_executable', 'pycodestyle')
call ale#Set('python_pycodestyle_options', '')
call ale#Set('python_pycodestyle_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pycodestyle_use_global', 0)
function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_pycodestyle', ['pycodestyle'])
endfunction
function! ale_linters#python#pycodestyle#GetCommand(buffer) abort
let l:executable = ale_linters#python#pycodestyle#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run pycodestyle'
\ : ''
return ale#Escape(l:executable) . l:exec_args
return ale#Escape(ale_linters#python#pycodestyle#GetExecutable(a:buffer))
\ . ' '
\ . ale#Var(a:buffer, 'python_pycodestyle_options')
\ . ' -'

View File

@@ -2,7 +2,7 @@
" Description: pyflakes for python files
call ale#Set('python_pyflakes_executable', 'pyflakes')
call ale#Set('python_pyflakes_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pyflakes_use_global', 0)
function! ale_linters#python#pyflakes#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_pyflakes', ['pyflakes'])
@@ -11,13 +11,7 @@ endfunction
function! ale_linters#python#pyflakes#GetCommand(buffer) abort
let l:executable = ale_linters#python#pyflakes#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run pyflakes'
\ : ''
return ale#Escape(l:executable)
\ . l:exec_args
\ . ' %t'
return ale#Escape(l:executable) . ' %t'
endfunction
function! ale_linters#python#pyflakes#Handle(buffer, lines) abort

View File

@@ -1,28 +1,20 @@
" Author: keith <k@keith.so>
" Description: pylint for python files
call ale#Set('python_pylint_executable', 'pylint')
call ale#Set('python_pylint_options', '')
call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pylint_change_directory', 1)
let g:ale_python_pylint_executable =
\ get(g:, 'ale_python_pylint_executable', 'pylint')
let g:ale_python_pylint_options =
\ get(g:, 'ale_python_pylint_options', '')
let g:ale_python_pylint_use_global = get(g:, 'ale_python_pylint_use_global', 0)
function! ale_linters#python#pylint#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint'])
endfunction
function! ale_linters#python#pylint#GetCommand(buffer) abort
let l:cd_string = ale#Var(a:buffer, 'python_pylint_change_directory')
\ ? ale#path#BufferCdString(a:buffer)
\ : ''
let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run pylint'
\ : ''
return l:cd_string
\ . ale#Escape(l:executable) . l:exec_args
return ale#Escape(ale_linters#python#pylint#GetExecutable(a:buffer))
\ . ' ' . ale#Var(a:buffer, 'python_pylint_options')
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n'
\ . ' %s'

View File

@@ -2,7 +2,7 @@
" Description: A language server for Python
call ale#Set('python_pyls_executable', 'pyls')
call ale#Set('python_pyls_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pyls_use_global', 0)
function! ale_linters#python#pyls#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_pyls', ['pyls'])
@@ -11,11 +11,11 @@ endfunction
function! ale_linters#python#pyls#GetCommand(buffer) abort
let l:executable = ale_linters#python#pyls#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run pyls'
\ : ''
return ale#Escape(l:executable)
endfunction
return ale#Escape(l:executable) . l:exec_args
function! ale_linters#python#pyls#GetLanguage(buffer) abort
return 'python'
endfunction
call ale#linter#Define('python', {
@@ -23,7 +23,6 @@ call ale#linter#Define('python', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#python#pyls#GetExecutable',
\ 'command_callback': 'ale_linters#python#pyls#GetCommand',
\ 'language': 'python',
\ 'language_callback': 'ale_linters#python#pyls#GetLanguage',
\ 'project_root_callback': 'ale#python#FindProjectRoot',
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\})

View File

@@ -1,29 +0,0 @@
" Author: dsifford <dereksifford@gmail.com>
" Description: A performant type-checker supporting LSP for Python 3 created by Facebook
call ale#Set('python_pyre_executable', 'pyre')
call ale#Set('python_pyre_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#python#pyre#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_pyre', ['pyre'])
endfunction
function! ale_linters#python#pyre#GetCommand(buffer) abort
let l:executable = ale_linters#python#pyre#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run pyre persistent'
\ : ' persistent'
return ale#Escape(l:executable) . l:exec_args
endfunction
call ale#linter#Define('python', {
\ 'name': 'pyre',
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#python#pyre#GetExecutable',
\ 'command_callback': 'ale_linters#python#pyre#GetCommand',
\ 'language': 'python',
\ 'project_root_callback': 'ale#python#FindProjectRoot',
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\})

View File

@@ -1,40 +0,0 @@
" Author: pylipp (www.github.com/pylipp)
" Description: qmlfmt for QML files
let g:ale_qml_qmlfmt_executable = get(g:, 'ale_qml_qmlfmt_executable', 'qmlfmt')
function! ale_linters#qml#qmlfmt#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'qml_qmlfmt_executable')
endfunction
function! ale_linters#qml#qmlfmt#GetCommand(buffer) abort
return ale#Escape(ale_linters#qml#qmlfmt#GetExecutable(a:buffer))
\ . ' -e'
endfunction
" Find lines like
" Error:11:1: Expected token `}'
function! ale_linters#qml#qmlfmt#Handle(buffer, lines) abort
let l:pattern = '\v^(Error|Warning):(\d+):(\d+): (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:item = {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4],
\ 'type': l:match[1] is# 'Warning' ? 'W' : 'E',
\}
call add(l:output, l:item)
endfor
return l:output
endfunction
call ale#linter#Define('qml', {
\ 'name': 'qmlfmt',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#qml#qmlfmt#GetExecutable',
\ 'command_callback': 'ale_linters#qml#qmlfmt#GetCommand',
\ 'callback': 'ale_linters#qml#qmlfmt#Handle',
\})

View File

@@ -22,7 +22,7 @@ function! ale_linters#r#lintr#GetCommand(buffer) abort
\ . l:lint_cmd
return ale#path#BufferCdString(a:buffer)
\ . 'Rscript --vanilla -e '
\ . 'Rscript -e '
\ . ale#Escape(l:cmd_string) . ' %t'
endfunction

View File

@@ -2,7 +2,7 @@
" Description: A language server for Reason
call ale#Set('reason_ols_executable', 'ocaml-language-server')
call ale#Set('reason_ols_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('reason_ols_use_global', 0)
call ale#linter#Define('reason', {
\ 'name': 'ols',

View File

@@ -4,45 +4,6 @@
call ale#Set('ruby_reek_show_context', 0)
call ale#Set('ruby_reek_show_wiki_link', 0)
function! ale_linters#ruby#reek#VersionCheck(buffer) abort
" If we have previously stored the version number in a cache, then
" don't look it up again.
if ale#semver#HasVersion('reek')
" Returning an empty string skips this command.
return ''
endif
return 'reek --version'
endfunction
function! ale_linters#ruby#reek#GetCommand(buffer, version_output) abort
let l:version = ale#semver#GetVersion('reek', a:version_output)
" Tell reek what the filename is if the version of reek is new enough.
let l:display_name_args = ale#semver#GTE(l:version, [5, 0, 0])
\ ? ' --stdin-filename %s'
\ : ''
return 'reek -f json --no-progress --no-color'
\ . l:display_name_args
endfunction
function! s:BuildText(buffer, error) abort
let l:parts = []
if ale#Var(a:buffer, 'ruby_reek_show_context')
call add(l:parts, a:error.context)
endif
call add(l:parts, a:error.message)
if ale#Var(a:buffer, 'ruby_reek_show_wiki_link')
call add(l:parts, '[' . a:error.wiki_link . ']')
endif
return join(l:parts, ' ')
endfunction
function! ale_linters#ruby#reek#Handle(buffer, lines) abort
let l:output = []
@@ -60,12 +21,25 @@ function! ale_linters#ruby#reek#Handle(buffer, lines) abort
return l:output
endfunction
function! s:BuildText(buffer, error) abort
let l:parts = []
if ale#Var(a:buffer, 'ruby_reek_show_context')
call add(l:parts, a:error.context)
endif
call add(l:parts, a:error.message)
if ale#Var(a:buffer, 'ruby_reek_show_wiki_link')
call add(l:parts, '[' . a:error.wiki_link . ']')
endif
return join(l:parts, ' ')
endfunction
call ale#linter#Define('ruby', {
\ 'name': 'reek',
\ 'executable': 'reek',
\ 'command_chain': [
\ {'callback': 'ale_linters#ruby#reek#VersionCheck'},
\ {'callback': 'ale_linters#ruby#reek#GetCommand'},
\ ],
\ 'name': 'reek',
\ 'executable': 'reek',
\ 'command': 'reek -f json --no-progress --no-color',
\ 'callback': 'ale_linters#ruby#reek#Handle',
\})

View File

@@ -4,9 +4,6 @@
call ale#Set('rust_cargo_use_check', 1)
call ale#Set('rust_cargo_check_all_targets', 0)
call ale#Set('rust_cargo_check_examples', 0)
call ale#Set('rust_cargo_check_tests', 0)
call ale#Set('rust_cargo_avoid_whole_workspace', 1)
call ale#Set('rust_cargo_default_feature_behavior', 'default')
call ale#Set('rust_cargo_include_features', '')
@@ -34,30 +31,12 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
let l:use_all_targets = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
\ && ale#semver#GTE(l:version, [0, 22, 0])
let l:use_examples = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_examples')
\ && ale#semver#GTE(l:version, [0, 22, 0])
let l:use_tests = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_tests')
\ && ale#semver#GTE(l:version, [0, 22, 0])
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
if !empty(l:include_features)
let l:include_features = ' --features ' . ale#Escape(l:include_features)
endif
let l:avoid_whole_workspace = ale#Var(a:buffer, 'rust_cargo_avoid_whole_workspace')
let l:nearest_cargo_prefix = ''
if l:avoid_whole_workspace
let l:nearest_cargo = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
let l:nearest_cargo_dir = fnamemodify(l:nearest_cargo, ':h')
if l:nearest_cargo_dir isnot# '.'
let l:nearest_cargo_prefix = 'cd '. ale#Escape(l:nearest_cargo_dir) .' && '
endif
endif
let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior')
if l:default_feature_behavior is# 'all'
let l:include_features = ''
@@ -68,11 +47,9 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
let l:default_feature = ''
endif
return l:nearest_cargo_prefix . 'cargo '
return 'cargo '
\ . (l:use_check ? 'check' : 'build')
\ . (l:use_all_targets ? ' --all-targets' : '')
\ . (l:use_examples ? ' --examples' : '')
\ . (l:use_tests ? ' --tests' : '')
\ . ' --frozen --message-format=json -q'
\ . l:default_feature
\ . l:include_features

View File

@@ -12,11 +12,12 @@ function! ale_linters#rust#rls#GetCommand(buffer) abort
let l:executable = ale_linters#rust#rls#GetExecutable(a:buffer)
let l:toolchain = ale#Var(a:buffer, 'rust_rls_toolchain')
if empty(l:toolchain)
return ale#Escape(l:executable)
else
return ale#Escape(l:executable) . ' +' . ale#Escape(l:toolchain)
endif
return ale#Escape(l:executable)
\ . ' +' . ale#Escape(l:toolchain)
endfunction
function! ale_linters#rust#rls#GetLanguage(buffer) abort
return 'rust'
endfunction
function! ale_linters#rust#rls#GetProjectRoot(buffer) abort
@@ -30,6 +31,6 @@ call ale#linter#Define('rust', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#rust#rls#GetExecutable',
\ 'command_callback': 'ale_linters#rust#rls#GetCommand',
\ 'language': 'rust',
\ 'language_callback': 'ale_linters#rust#rls#GetLanguage',
\ 'project_root_callback': 'ale_linters#rust#rls#GetProjectRoot',
\})

View File

@@ -1,9 +1,8 @@
" Author: KabbAmine - https://github.com/KabbAmine,
" Ben Falconer <ben@falconers.me.uk>
" Author: KabbAmine - https://github.com/KabbAmine
call ale#linter#Define('sass', {
\ 'name': 'sasslint',
\ 'executable': 'sass-lint',
\ 'command_callback': 'ale#handlers#sasslint#GetCommand',
\ 'command': 'sass-lint -v -q -f compact %t',
\ 'callback': 'ale#handlers#css#HandleCSSLintFormat',
\})

View File

@@ -1,7 +1,7 @@
" Author: diartyz <diartyz@gmail.com>
call ale#Set('sass_stylelint_executable', 'stylelint')
call ale#Set('sass_stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('sass_stylelint_use_global', 0)
function! ale_linters#sass#stylelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'sass_stylelint', [

View File

@@ -1,29 +0,0 @@
" Author: Nils Leuzinger - https://github.com/PawkyPenguin
" Description: Basic scala support using fsc
"
function! ale_linters#scala#fsc#GetExecutable(buffer) abort
if index(split(getbufvar(a:buffer, '&filetype'), '\.'), 'sbt') >= 0
" Don't check sbt files
return ''
endif
return 'fsc'
endfunction
function! ale_linters#scala#fsc#GetCommand(buffer) abort
let l:executable = ale_linters#scala#fsc#GetExecutable(a:buffer)
if empty(l:executable)
return ''
endif
return ale#Escape(l:executable) . ' -Ystop-after:parser %t'
endfunction
call ale#linter#Define('scala', {
\ 'name': 'fsc',
\ 'executable_callback': 'ale_linters#scala#fsc#GetExecutable',
\ 'command_callback': 'ale_linters#scala#fsc#GetCommand',
\ 'callback': 'ale#handlers#scala#HandleScalacLintFormat',
\ 'output_stream': 'stderr',
\})

View File

@@ -4,7 +4,7 @@
function! ale_linters#scala#scalac#GetExecutable(buffer) abort
if index(split(getbufvar(a:buffer, '&filetype'), '\.'), 'sbt') >= 0
" Don't check sbt files
" Don't check sbt files with scalac.
return ''
endif
@@ -21,10 +21,45 @@ function! ale_linters#scala#scalac#GetCommand(buffer) abort
return ale#Escape(l:executable) . ' -Ystop-after:parser %t'
endfunction
function! ale_linters#scala#scalac#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" /var/folders/5q/20rgxx3x1s34g3m14n5bq0x80000gn/T/vv6pSsy/0:26: error: expected class or object definition
let l:pattern = '^.\+:\(\d\+\): \(\w\+\): \(.\+\)'
let l:output = []
let l:ln = 0
for l:line in a:lines
let l:ln = l:ln + 1
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
let l:text = l:match[3]
let l:type = l:match[2] is# 'error' ? 'E' : 'W'
let l:col = 0
if l:ln + 1 < len(a:lines)
let l:col = stridx(a:lines[l:ln + 1], '^')
endif
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:col + 1,
\ 'text': l:text,
\ 'type': l:type,
\})
endfor
return l:output
endfunction
call ale#linter#Define('scala', {
\ 'name': 'scalac',
\ 'executable_callback': 'ale_linters#scala#scalac#GetExecutable',
\ 'command_callback': 'ale_linters#scala#scalac#GetCommand',
\ 'callback': 'ale#handlers#scala#HandleScalacLintFormat',
\ 'callback': 'ale_linters#scala#scalac#Handle',
\ 'output_stream': 'stderr',
\})

View File

@@ -1,18 +1,8 @@
" Author: KabbAmine - https://github.com/KabbAmine, Ben Falconer
" <ben@falconers.me.uk>
function! ale_linters#scss#sasslint#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer)
\ . ale#Escape('sass-lint')
\ . ' -v'
\ . ' -q'
\ . ' -f compact'
\ . ' %t'
endfunction
" Author: KabbAmine - https://github.com/KabbAmine
call ale#linter#Define('scss', {
\ 'name': 'sasslint',
\ 'executable': 'sass-lint',
\ 'command_callback': 'ale_linters#scss#sasslint#GetCommand',
\ 'command': 'sass-lint -v -q -f compact %t',
\ 'callback': 'ale#handlers#css#HandleCSSLintFormat',
\})

View File

@@ -1,7 +1,7 @@
" Author: diartyz <diartyz@gmail.com>
call ale#Set('scss_stylelint_executable', 'stylelint')
call ale#Set('scss_stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('scss_stylelint_use_global', 0)
function! ale_linters#scss#stylelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'scss_stylelint', [

View File

@@ -1,33 +0,0 @@
" Author: Christian Höltje (https://docwhat.org/)
" Description: BASH Language server integration for ALE
scriptencoding utf-8
call ale#Set('sh_language_server_executable', 'bash-language-server')
call ale#Set('sh_language_server_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#sh#language_server#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'sh_language_server', [
\ 'node_modules/.bin/bash-language-server',
\])
endfunction
function! ale_linters#sh#language_server#GetCommand(buffer) abort
let l:exe = ale#Escape(ale_linters#sh#language_server#GetExecutable(a:buffer))
return l:exe . ' start'
endfunction
function! ale_linters#sh#language_server#GetProjectRoot(buffer) abort
let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
endfunction
call ale#linter#Define('sh', {
\ 'name': 'language_server',
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#sh#language_server#GetExecutable',
\ 'command_callback': 'ale_linters#sh#language_server#GetCommand',
\ 'language': 'sh',
\ 'project_root_callback': 'ale_linters#sh#language_server#GetProjectRoot',
\})

View File

@@ -2,7 +2,7 @@
call ale#Set('stylus_stylelint_executable', 'stylelint')
call ale#Set('stylus_stylelint_options', '')
call ale#Set('stylus_stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('stylus_stylelint_use_global', 0)
function! ale_linters#stylus#stylelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'stylus_stylelint', [

View File

@@ -4,7 +4,7 @@
call ale#Set('typescript_tslint_executable', 'tslint')
call ale#Set('typescript_tslint_config_path', '')
call ale#Set('typescript_tslint_rules_dir', '')
call ale#Set('typescript_tslint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('typescript_tslint_use_global', 0)
call ale#Set('typescript_tslint_ignore_empty_files', 0)
function! ale_linters#typescript#tslint#GetExecutable(buffer) abort

View File

@@ -3,13 +3,17 @@
call ale#Set('typescript_tsserver_executable', 'tsserver')
call ale#Set('typescript_tsserver_config_path', '')
call ale#Set('typescript_tsserver_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('typescript_tsserver_use_global', 0)
" These functions need to be defined just to comply with the API for LSP.
function! ale_linters#typescript#tsserver#GetProjectRoot(buffer) abort
return ''
endfunction
function! ale_linters#typescript#tsserver#GetLanguage(buffer) abort
return ''
endfunction
function! ale_linters#typescript#tsserver#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'typescript_tsserver', [
\ 'node_modules/.bin/tsserver',
@@ -22,5 +26,5 @@ call ale#linter#Define('typescript', {
\ 'executable_callback': 'ale_linters#typescript#tsserver#GetExecutable',
\ 'command_callback': 'ale_linters#typescript#tsserver#GetExecutable',
\ 'project_root_callback': 'ale_linters#typescript#tsserver#GetProjectRoot',
\ 'language': '',
\ 'language_callback': 'ale_linters#typescript#tsserver#GetLanguage',
\})

View File

@@ -2,38 +2,31 @@
" Description: This file adds support for checking Vim code with Vint.
" This flag can be used to change enable/disable style issues.
call ale#Set('vim_vint_show_style_issues', 1)
call ale#Set('vim_vint_executable', 'vint')
let s:enable_neovim = has('nvim') ? ' --enable-neovim' : ''
let g:ale_vim_vint_show_style_issues =
\ get(g:, 'ale_vim_vint_show_style_issues', 1)
let s:enable_neovim = has('nvim') ? ' --enable-neovim ' : ''
let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})"'
function! ale_linters#vim#vint#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'vim_vint_executable')
endfunction
function! ale_linters#vim#vint#VersionCommand(buffer) abort
let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer)
" Check the Vint version if we haven't checked it already.
return !ale#semver#HasVersion(l:executable)
\ ? ale#Escape(l:executable) . ' --version'
return !ale#semver#HasVersion('vint')
\ ? 'vint --version'
\ : ''
endfunction
function! ale_linters#vim#vint#GetCommand(buffer, version_output) abort
let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:version = ale#semver#GetVersion('vint', a:version_output)
let l:can_use_no_color_flag = empty(l:version)
\ || ale#semver#GTE(l:version, [0, 3, 7])
let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w'
return ale#Escape(l:executable)
\ . ' ' . l:warning_flag
\ . (l:can_use_no_color_flag ? ' --no-color' : '')
return 'vint '
\ . l:warning_flag . ' '
\ . (l:can_use_no_color_flag ? '--no-color ' : '')
\ . s:enable_neovim
\ . ' ' . s:format
\ . s:format
\ . ' %t'
endfunction
@@ -65,7 +58,7 @@ endfunction
call ale#linter#Define('vim', {
\ 'name': 'vint',
\ 'executable_callback': 'ale_linters#vim#vint#GetExecutable',
\ 'executable': 'vint',
\ 'command_chain': [
\ {'callback': 'ale_linters#vim#vint#VersionCommand', 'output_stream': 'stderr'},
\ {'callback': 'ale_linters#vim#vint#GetCommand', 'output_stream': 'stdout'},

View File

@@ -2,7 +2,7 @@
" Description: This file adds support for linting Swagger / OpenAPI documents using swaglint
call ale#Set('yaml_swaglint_executable', 'swaglint')
call ale#Set('yaml_swaglint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('yaml_swaglint_use_global', 0)
function! ale_linters#yaml#swaglint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'yaml_swaglint', [

View File

@@ -20,31 +20,21 @@ function! ale_linters#yaml#yamllint#Handle(buffer, lines) abort
" Matches patterns line the following:
" something.yaml:1:1: [warning] missing document start "---" (document-start)
" something.yml:2:1: [error] syntax error: expected the node content, but found '<stream end>'
let l:pattern = '\v^.*:(\d+):(\d+): \[(error|warning)\] (.+)$'
let l:pattern = '^.*:\(\d\+\):\(\d\+\): \[\(error\|warning\)\] \(.\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:item = {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[4],
\ 'type': l:match[3] is# 'error' ? 'E' : 'W',
\}
let l:line = l:match[1] + 0
let l:col = l:match[2] + 0
let l:type = l:match[3]
let l:text = l:match[4]
let l:code_match = matchlist(l:item.text, '\v^(.+) \(([^)]+)\)$')
if !empty(l:code_match)
if l:code_match[2] is# 'trailing-spaces'
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
" Skip warnings for trailing whitespace if the option is off.
continue
endif
let l:item.text = l:code_match[1]
let l:item.code = l:code_match[2]
endif
call add(l:output, l:item)
call add(l:output, {
\ 'lnum': l:line,
\ 'col': l:col,
\ 'text': l:text,
\ 'type': l:type is# 'error' ? 'E' : 'W',
\})
endfor
return l:output

View File

@@ -2,20 +2,42 @@
" Description: Primary code path for the plugin
" Manages execution of linters when requested by autocommands
" Strings used for severity in the echoed message
let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
" Ignoring linters, for disabling some, or ignoring LSP diagnostics.
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
let s:lint_timer = -1
let s:queued_buffer_number = -1
let s:should_lint_file_for_buffer = {}
let s:error_delay_ms = 1000 * 60 * 2
let s:timestamp_map = {}
" Given a key for a script variable for tracking the time to wait until
" a given function should be called, a funcref for a function to call, and
" a List of arguments, call the function and return whatever value it returns.
"
" If the function throws an exception, then the function will not be called
" for a while, and 0 will be returned instead.
function! ale#CallWithCooldown(timestamp_key, func, arglist) abort
let l:now = ale#util#ClockMilliseconds()
if l:now < get(s:timestamp_map, a:timestamp_key, -1)
return 0
endif
let s:timestamp_map[a:timestamp_key] = l:now + s:error_delay_ms
let l:return_value = call(a:func, a:arglist)
let s:timestamp_map[a:timestamp_key] = -1
return l:return_value
endfunction
" Return 1 if a file is too large for ALE to handle.
function! ale#FileTooLarge(buffer) abort
let l:max = getbufvar(a:buffer, 'ale_maximum_file_size', get(g:, 'ale_maximum_file_size', 0))
function! ale#FileTooLarge() abort
if !exists('g:ale_maximum_file_size')
return 0
endif
let l:max = ale#Var(bufnr(''), 'maximum_file_size')
return l:max > 0 ? (line2byte(line('$') + 1) > l:max) : 0
endfunction
@@ -38,37 +60,29 @@ function! ale#ShouldDoNothing(buffer) abort
return 1
endif
let l:filetype = getbufvar(a:buffer, '&filetype')
" Do nothing when there's no filetype.
if l:filetype is# ''
" Do nothing for blacklisted files
if index(get(g:, 'ale_filetype_blacklist', []), getbufvar(a:buffer, '&filetype')) >= 0
return 1
endif
" Do nothing for blacklisted files.
if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0
return 1
endif
" Do nothing if running from command mode.
" Do nothing if running from command mode
if s:getcmdwintype_exists && !empty(getcmdwintype())
return 1
endif
let l:filename = fnamemodify(bufname(a:buffer), ':t')
" Do nothing for directories.
if l:filename is# '.'
return 1
endif
" Do nothing if running in the sandbox.
" Do nothing if running in the sandbox
if ale#util#InSandbox()
return 1
endif
" Do nothing if the file is too large.
if ale#FileTooLarge(a:buffer)
if ale#FileTooLarge()
return 1
endif
@@ -91,22 +105,30 @@ function! ale#Queue(delay, ...) abort
let l:linting_flag = get(a:000, 0, '')
let l:buffer = get(a:000, 1, bufnr(''))
if l:linting_flag isnot# '' && l:linting_flag isnot# 'lint_file'
return ale#CallWithCooldown(
\ 'dont_queue_until',
\ function('s:ALEQueueImpl'),
\ [a:delay, l:linting_flag, l:buffer],
\)
endfunction
function! s:ALEQueueImpl(delay, linting_flag, buffer) abort
if a:linting_flag isnot# '' && a:linting_flag isnot# 'lint_file'
throw "linting_flag must be either '' or 'lint_file'"
endif
if type(l:buffer) != type(0)
if type(a:buffer) != type(0)
throw 'buffer_number must be a Number'
endif
if ale#ShouldDoNothing(l:buffer)
if ale#ShouldDoNothing(a:buffer)
return
endif
" Remember that we want to check files for this buffer.
" We will remember this until we finally run the linters, via any event.
if l:linting_flag is# 'lint_file'
let s:should_lint_file_for_buffer[l:buffer] = 1
if a:linting_flag is# 'lint_file'
let s:should_lint_file_for_buffer[a:buffer] = 1
endif
if s:lint_timer != -1
@@ -114,24 +136,24 @@ function! ale#Queue(delay, ...) abort
let s:lint_timer = -1
endif
let l:linters = ale#linter#Get(getbufvar(l:buffer, '&filetype'))
let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
" Don't set up buffer data and so on if there are no linters to run.
if empty(l:linters)
" If we have some previous buffer data, then stop any jobs currently
" running and clear everything.
if has_key(g:ale_buffer_info, l:buffer)
call ale#engine#RunLinters(l:buffer, [], 1)
if has_key(g:ale_buffer_info, a:buffer)
call ale#engine#RunLinters(a:buffer, [], 1)
endif
return
endif
if a:delay > 0
let s:queued_buffer_number = l:buffer
let s:queued_buffer_number = a:buffer
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
else
call ale#Lint(-1, l:buffer)
call ale#Lint(-1, a:buffer)
endif
endfunction
@@ -147,29 +169,30 @@ function! ale#Lint(...) abort
let l:buffer = bufnr('')
endif
if ale#ShouldDoNothing(l:buffer)
return ale#CallWithCooldown(
\ 'dont_lint_until',
\ function('s:ALELintImpl'),
\ [l:buffer],
\)
endfunction
function! s:ALELintImpl(buffer) abort
if ale#ShouldDoNothing(a:buffer)
return
endif
" Use the filetype from the buffer
let l:filetype = getbufvar(l:buffer, '&filetype')
let l:linters = ale#linter#Get(l:filetype)
let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
let l:should_lint_file = 0
" Check if we previously requested checking the file.
if has_key(s:should_lint_file_for_buffer, l:buffer)
unlet s:should_lint_file_for_buffer[l:buffer]
if has_key(s:should_lint_file_for_buffer, a:buffer)
unlet s:should_lint_file_for_buffer[a:buffer]
" Lint files if they exist.
let l:should_lint_file = filereadable(expand('#' . l:buffer . ':p'))
let l:should_lint_file = filereadable(expand('#' . a:buffer . ':p'))
endif
" Apply ignore lists for linters only if needed.
let l:ignore_config = ale#Var(l:buffer, 'linters_ignore')
let l:linters = !empty(l:ignore_config)
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config)
\ : l:linters
call ale#engine#RunLinters(l:buffer, l:linters, l:should_lint_file)
call ale#engine#RunLinters(a:buffer, l:linters, l:should_lint_file)
endfunction
" Reset flags indicating that files should be checked for all buffers.
@@ -177,6 +200,10 @@ function! ale#ResetLintFileMarkers() abort
let s:should_lint_file_for_buffer = {}
endfunction
function! ale#ResetErrorDelays() abort
let s:timestamp_map = {}
endfunction
let g:ale_has_override = get(g:, 'ale_has_override', {})
" Call has(), but check a global Dictionary so we can force flags on or off

View File

@@ -12,21 +12,7 @@ function! ale#balloon#MessageForPos(bufnr, lnum, col) abort
let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist
let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col)
" Show the diagnostics message if found, 'Hover' output otherwise
if l:index >= 0
return l:loclist[l:index].text
elseif exists('*balloon_show') || getbufvar(
\ a:bufnr,
\ 'ale_set_balloons_legacy_echo',
\ get(g:, 'ale_set_balloons_legacy_echo', 0)
\)
" Request LSP/tsserver hover information, but only if this version of
" Vim supports the balloon_show function, or if we turned a legacy
" setting on.
call ale#hover#Show(a:bufnr, a:lnum, a:col, {'called_from_balloonexpr': 1})
endif
return ''
return l:index >= 0 ? l:loclist[l:index].text : ''
endfunction
function! ale#balloon#Expr() abort
@@ -34,26 +20,9 @@ function! ale#balloon#Expr() abort
endfunction
function! ale#balloon#Disable() abort
if has('balloon_eval_term')
set noballoonevalterm
endif
set noballooneval
set balloonexpr=
set noballooneval balloonexpr=
endfunction
function! ale#balloon#Enable() abort
if !has('balloon_eval') && !has('balloon_eval_term')
return
endif
if has('balloon_eval')
set ballooneval
endif
if has('balloon_eval_term')
set balloonevalterm
endif
set balloonexpr=ale#balloon#Expr()
set ballooneval balloonexpr=ale#balloon#Expr()
endfunction

View File

@@ -1,7 +1,6 @@
" Author: gagbo <gagbobada@gmail.com>, w0rp <devw0rp@gmail.com>, roel0 <postelmansroel@gmail.com>
" Author: gagbo <gagbobada@gmail.com>, w0rp <devw0rp@gmail.com>
" Description: Functions for integrating with C-family linters.
call ale#Set('c_parse_makefile', 0)
let s:sep = has('win32') ? '\' : '/'
function! ale#c#FindProjectRoot(buffer) abort
@@ -23,88 +22,6 @@ function! ale#c#FindProjectRoot(buffer) abort
return ''
endfunction
function! ale#c#ParseCFlagsToList(path_prefix, cflags) abort
let l:cflags_list = []
let l:previous_options = []
for l:option in a:cflags
call add(l:previous_options, l:option)
" Check if cflag contained a '-' and should not have been splitted
let l:option_list = split(l:option, '\zs')
if l:option_list[-1] isnot# ' '
continue
endif
let l:option = join(l:previous_options, '-')
let l:previous_options = []
let l:option = '-' . substitute(l:option, '^\s*\(.\{-}\)\s*$', '\1', '')
" Fix relative paths if needed
if stridx(l:option, '-I') >= 0 &&
\ stridx(l:option, '-I' . s:sep) < 0
let l:rel_path = join(split(l:option, '\zs')[2:], '')
let l:rel_path = substitute(l:rel_path, '"', '', 'g')
let l:rel_path = substitute(l:rel_path, '''', '', 'g')
let l:option = ale#Escape('-I' . a:path_prefix .
\ s:sep . l:rel_path)
endif
" Parse the cflag
if stridx(l:option, '-I') >= 0 ||
\ stridx(l:option, '-D') >= 0
if index(l:cflags_list, l:option) < 0
call add(l:cflags_list, l:option)
endif
endif
endfor
return l:cflags_list
endfunction
function! ale#c#ParseCFlags(buffer, stdout_make) abort
if !g:ale_c_parse_makefile
return []
endif
let l:buffer_filename = expand('#' . a:buffer . ':t')
let l:cflags = []
for l:lines in split(a:stdout_make, '\\n')
if stridx(l:lines, l:buffer_filename) >= 0
let l:cflags = split(l:lines, '-')
break
endif
endfor
let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile')
return ale#c#ParseCFlagsToList(fnamemodify(l:makefile_path, ':p:h'), l:cflags)
endfunction
function! ale#c#GetCFlags(buffer, output) abort
let l:cflags = ' '
if g:ale_c_parse_makefile && !empty(a:output)
let l:cflags = join(ale#c#ParseCFlags(a:buffer, join(a:output, '\n')), ' ') . ' '
endif
if l:cflags is# ' '
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
endif
return l:cflags
endfunction
function! ale#c#GetMakeCommand(buffer) abort
if g:ale_c_parse_makefile
let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile')
if !empty(l:makefile_path)
return 'cd '. fnamemodify(l:makefile_path, ':p:h') . ' && make -n'
endif
endif
return ''
endfunction
" Given a buffer number, search for a project root, and output a List
" of directories to include based on some heuristics.
"

View File

@@ -1,10 +1,6 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Completion support for LSP linters
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 s:timer_id = -1
let s:last_done_pos = []
@@ -32,8 +28,6 @@ let s:LSP_COMPLETION_REFERENCE_KIND = 18
" the insert cursor is. If one of these matches, we'll check for completions.
let s:should_complete_map = {
\ '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$',
\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$',
\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
\}
" Regular expressions for finding the start column to replace with completion.
@@ -44,8 +38,6 @@ let s:omni_start_map = {
" A map of exact characters for triggering LSP completions.
let s:trigger_character_map = {
\ '<default>': ['.'],
\ 'typescript': ['.', '''', '"'],
\ 'rust': ['.', '::'],
\}
function! s:GetFiletypeValue(map, filetype) abort
@@ -82,49 +74,33 @@ function! ale#completion#GetTriggerCharacter(filetype, prefix) abort
return ''
endfunction
function! ale#completion#Filter(buffer, suggestions, prefix) abort
let l:excluded_words = ale#Var(a:buffer, 'completion_excluded_words')
function! ale#completion#Filter(suggestions, prefix) abort
" For completing...
" foo.
" ^
" We need to include all of the given suggestions.
if a:prefix is# '.'
let l:filtered_suggestions = a:suggestions
else
let l:filtered_suggestions = []
" Filter suggestions down to those starting with the prefix we used for
" finding suggestions in the first place.
"
" Some completion tools will include suggestions which don't even start
" with the characters we have already typed.
for l:item in a:suggestions
" A List of String values or a List of completion item Dictionaries
" is accepted here.
let l:word = type(l:item) == type('') ? l:item : l:item.word
" Add suggestions if the suggestion starts with a case-insensitive
" match for the prefix.
if l:word[: len(a:prefix) - 1] is? a:prefix
call add(l:filtered_suggestions, l:item)
endif
endfor
return a:suggestions
endif
if !empty(l:excluded_words)
" Copy the List if needed. We don't want to modify the argument.
" We shouldn't make a copy if we don't need to.
if l:filtered_suggestions is a:suggestions
let l:filtered_suggestions = copy(a:suggestions)
let l:filtered_suggestions = []
" Filter suggestions down to those starting with the prefix we used for
" finding suggestions in the first place.
"
" Some completion tools will include suggestions which don't even start
" with the characters we have already typed.
for l:item in a:suggestions
" A List of String values or a List of completion item Dictionaries
" is accepted here.
let l:word = type(l:item) == type('') ? l:item : l:item.word
" Add suggestions if the suggestion starts with a case-insensitive
" match for the prefix.
if l:word[: len(a:prefix) - 1] is? a:prefix
call add(l:filtered_suggestions, l:item)
endif
" Remove suggestions with words in the exclusion List.
call filter(
\ l:filtered_suggestions,
\ 'index(l:excluded_words, type(v:val) is type('''') ? v:val : v:val.word) < 0',
\)
endif
endfor
return l:filtered_suggestions
endfunction
@@ -202,9 +178,7 @@ function! ale#completion#ParseTSServerCompletions(response) abort
endfunction
function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
let l:buffer = bufnr('')
let l:results = []
let l:names_with_details = []
for l:suggestion in a:response.body
let l:displayParts = []
@@ -238,44 +212,10 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
\})
endfor
let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', [])
if !empty(l:names) && len(l:names) != len(l:results)
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',
\)
for l:name in l:missing_names
call add(l:results, {
\ 'word': l:name,
\ 'kind': 'v',
\ 'icase': 1,
\ 'menu': '',
\ 'info': '',
\})
endfor
endif
return l:results
endfunction
function! ale#completion#NullFilter(buffer, item) abort
return 1
endfunction
function! ale#completion#ParseLSPCompletions(response) abort
let l:buffer = bufnr('')
let l:info = get(b:, 'ale_completion_info', {})
let l:Filter = get(l:info, 'completion_filter', v:null)
if l:Filter is v:null
let l:Filter = function('ale#completion#NullFilter')
else
let l:Filter = ale#util#GetFunction(l:Filter)
endif
let l:item_list = []
if type(get(a:response, 'result')) is type([])
@@ -288,16 +228,6 @@ function! ale#completion#ParseLSPCompletions(response) abort
let l:results = []
for l:item in l:item_list
if !call(l:Filter, [l:buffer, l:item])
continue
endif
let l:word = matchstr(l:item.label, '\v^[^(]+')
if empty(l:word)
continue
endif
" See :help complete-items for Vim completion kinds
if l:item.kind is s:LSP_COMPLETION_METHOD_KIND
let l:kind = 'm'
@@ -314,18 +244,14 @@ function! ale#completion#ParseLSPCompletions(response) abort
endif
call add(l:results, {
\ 'word': l:word,
\ 'word': l:item.label,
\ 'kind': l:kind,
\ 'icase': 1,
\ 'menu': get(l:item, 'detail', ''),
\ 'info': get(l:item, 'documentation', ''),
\ 'menu': l:item.detail,
\ 'info': l:item.documentation,
\})
endfor
if has_key(l:info, 'prefix')
return ale#completion#Filter(l:buffer, l:results, l:info.prefix)
endif
return l:results
endfunction
@@ -338,25 +264,19 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
return
endif
let l:buffer = bufnr('')
let l:command = get(a:response, 'command', '')
if l:command is# 'completions'
let l:names = ale#completion#Filter(
\ l:buffer,
\ ale#completion#ParseTSServerCompletions(a:response),
\ b:ale_completion_info.prefix,
\)[: g:ale_completion_max_suggestions - 1]
" We need to remember some names for tsserver, as it doesn't send
" details back for everything we send.
call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names)
if !empty(l:names)
let b:ale_completion_info.request_id = ale#lsp#Send(
\ b:ale_completion_info.conn_id,
\ ale#lsp#tsserver_message#CompletionEntryDetails(
\ l:buffer,
\ bufnr(''),
\ b:ale_completion_info.line,
\ b:ale_completion_info.column,
\ l:names,
@@ -389,13 +309,14 @@ function! s:GetLSPCompletions(linter) abort
\ ? function('ale#completion#HandleTSServerResponse')
\ : function('ale#completion#HandleLSPResponse')
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
if empty(l:lsp_details)
return 0
endif
let l:id = l:lsp_details.connection_id
let l:root = l:lsp_details.project_root
if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Completions(
@@ -407,7 +328,7 @@ function! s:GetLSPCompletions(linter) abort
else
" Send a message saying the buffer has changed first, otherwise
" completions won't know what text is nearby.
call ale#lsp#NotifyForChanges(l:lsp_details)
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
" For LSP completions, we need to clamp the column to the length of
" the line. python-language-server and perhaps others do not implement
@@ -423,15 +344,11 @@ function! s:GetLSPCompletions(linter) abort
\)
endif
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
if l:request_id
let b:ale_completion_info.conn_id = l:id
let b:ale_completion_info.request_id = l:request_id
if has_key(a:linter, 'completion_filter')
let b:ale_completion_info.completion_filter = a:linter.completion_filter
endif
endif
endfunction
@@ -461,7 +378,10 @@ function! ale#completion#GetCompletions() abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:GetLSPCompletions(l:linter)
if l:linter.lsp is# 'tsserver'
\|| get(g:, 'ale_completion_experimental_lsp_support', 0)
call s:GetLSPCompletions(l:linter)
endif
endif
endfor
endfunction

View File

@@ -1,3 +0,0 @@
function! ale#completion#python#CompletionItemFilter(buffer, item) abort
return a:item.label !~# '\v^__[a-z_]+__'
endfunction

View File

@@ -1,11 +1,6 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Echoes lint message for the current line, if any
" Controls the milliseconds delay before echoing a message.
let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10)
" A string format for the echoed message.
let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s')
let s:cursor_timer = -1
let s:last_pos = [0, 0, 0]
@@ -56,6 +51,10 @@ function! s:StopCursorTimer() abort
endfunction
function! ale#cursor#EchoCursorWarning(...) abort
return ale#CallWithCooldown('dont_echo_until', function('s:EchoImpl'), [])
endfunction
function! s:EchoImpl() abort
if !g:ale_echo_cursor
return
endif

View File

@@ -51,7 +51,6 @@ let s:global_variable_list = [
\ 'ale_sign_warning',
\ 'ale_statusline_format',
\ 'ale_type_map',
\ 'ale_use_global_executables',
\ 'ale_warn_about_trailing_blank_lines',
\ 'ale_warn_about_trailing_whitespace',
\]
@@ -168,30 +167,6 @@ function! s:EchoLinterAliases(all_linters) abort
endfor
endfunction
function! s:EchoLSPErrorMessages(all_linter_names) abort
let l:lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
let l:header_echoed = 0
for l:linter_name in a:all_linter_names
let l:error_list = get(l:lsp_error_messages, l:linter_name, [])
if !empty(l:error_list)
if !l:header_echoed
call s:Echo(' LSP Error Messages:')
call s:Echo('')
endif
call s:Echo('(Errors for ' . l:linter_name . ')')
for l:message in l:error_list
for l:line in split(l:message, "\n")
call s:Echo(l:line)
endfor
endfor
endif
endfor
endfunction
function! ale#debugging#Info() abort
let l:filetype = &filetype
@@ -214,22 +189,16 @@ function! ale#debugging#Info() abort
" This must be done after linters are loaded.
let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names)
let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype)
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '')
call s:Echo(' Current Filetype: ' . l:filetype)
call s:Echo('Available Linters: ' . string(l:all_names))
call s:EchoLinterAliases(l:all_linters)
call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
call s:Echo(' Suggested Fixers: ' . l:fixers_string)
call s:Echo(' Linter Variables:')
call s:Echo('')
call s:EchoLinterVariables(l:variable_list)
call s:Echo(' Global Variables:')
call s:Echo('')
call s:EchoGlobalVariables()
call s:EchoLSPErrorMessages(l:all_names)
call s:Echo(' Command History:')
call s:Echo('')
call s:EchoCommandHistory()
@@ -242,14 +211,3 @@ function! ale#debugging#InfoToClipboard() abort
call s:Echo('ALEInfo copied to your clipboard')
endfunction
function! ale#debugging#InfoToFile(filename) abort
let l:expanded_filename = expand(a:filename)
redir => l:output
silent call ale#debugging#Info()
redir END
call writefile(split(l:output, "\n"), l:expanded_filename)
call s:Echo('ALEInfo written to ' . l:expanded_filename)
endfunction

View File

@@ -13,21 +13,37 @@ function! ale#definition#SetMap(map) abort
let s:go_to_definition_map = a:map
endfunction
" This function is used so we can check the execution of commands without
" running them.
function! ale#definition#Execute(expr) abort
execute a:expr
endfunction
function! ale#definition#ClearLSPData() abort
let s:go_to_definition_map = {}
endfunction
function! ale#definition#Open(options, filename, line, column) abort
if a:options.open_in_tab
call ale#definition#Execute('tabedit ' . fnameescape(a:filename))
else
call ale#definition#Execute('edit ' . fnameescape(a:filename))
endif
call cursor(a:line, a:column)
endfunction
function! ale#definition#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') is# 'definition'
\&& has_key(s:go_to_definition_map, a:response.request_seq)
let l:options = remove(s:go_to_definition_map, a:response.request_seq)
if get(a:response, 'success', v:false) is v:true && !empty(a:response.body)
if get(a:response, 'success', v:false) is v:true
let l:filename = a:response.body[0].file
let l:line = a:response.body[0].start.line
let l:column = a:response.body[0].start.offset
call ale#util#Open(l:filename, l:line, l:column, l:options)
call ale#definition#Open(l:options, l:filename, l:line, l:column)
endif
endif
endfunction
@@ -51,7 +67,7 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
let l:line = l:item.range.start.line + 1
let l:column = l:item.range.start.character
call ale#util#Open(l:filename, l:line, l:column, l:options)
call ale#definition#Open(l:options, l:filename, l:line, l:column)
break
endfor
endif
@@ -65,13 +81,14 @@ function! s:GoToLSPDefinition(linter, options) abort
\ ? function('ale#definition#HandleTSServerResponse')
\ : function('ale#definition#HandleLSPResponse')
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
if empty(l:lsp_details)
return 0
endif
let l:id = l:lsp_details.connection_id
let l:root = l:lsp_details.project_root
if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Definition(
@@ -82,7 +99,7 @@ function! s:GoToLSPDefinition(linter, options) abort
else
" Send a message saying the buffer has changed first, or the
" definition position probably won't make sense.
call ale#lsp#NotifyForChanges(l:lsp_details)
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
let l:column = min([l:column, len(getline(l:line))])
@@ -92,7 +109,7 @@ function! s:GoToLSPDefinition(linter, options) abort
let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column)
endif
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
let s:go_to_definition_map[l:request_id] = {
\ 'open_in_tab': get(a:options, 'open_in_tab', 0),

View File

@@ -2,9 +2,6 @@
" Description: Backend execution and job management
" Executes linters in the background, using NeoVim or Vim 8 jobs
" Remapping of linter problems.
let g:ale_type_map = get(g:, 'ale_type_map', {})
" Stores information for each job including:
"
" linter: The linter dictionary for the job.
@@ -14,6 +11,11 @@ if !has_key(s:, 'job_info_map')
let s:job_info_map = {}
endif
" Associates LSP connection IDs with linter names.
if !has_key(s:, 'lsp_linter_map')
let s:lsp_linter_map = {}
endif
if !has_key(s:, 'executable_cache_map')
let s:executable_cache_map = {}
endif
@@ -42,7 +44,7 @@ function! ale#engine#IsExecutable(buffer, executable) abort
" Cache the executable check if we found it, or if the option to cache
" failing checks is on.
if l:result || get(g:, 'ale_cache_executable_check_failures', 0)
if l:result || g:ale_cache_executable_check_failures
let s:executable_cache_map[a:executable] = l:result
endif
@@ -74,6 +76,11 @@ function! ale#engine#InitBufferInfo(buffer) abort
return 0
endfunction
" Clear LSP linter data for the linting engine.
function! ale#engine#ClearLSPData() abort
let s:lsp_linter_map = {}
endfunction
" This function is documented and part of the public API.
"
" Return 1 if ALE is busy checking a given buffer
@@ -86,13 +93,11 @@ endfunction
" Register a temporary file to be managed with the ALE engine for
" a current job run.
function! ale#engine#ManageFile(buffer, filename) abort
call ale#engine#InitBufferInfo(a:buffer)
call add(g:ale_buffer_info[a:buffer].temporary_file_list, a:filename)
endfunction
" Same as the above, but manage an entire directory.
function! ale#engine#ManageDirectory(buffer, directory) abort
call ale#engine#InitBufferInfo(a:buffer)
call add(g:ale_buffer_info[a:buffer].temporary_directory_list, a:directory)
endfunction
@@ -226,6 +231,70 @@ function! s:HandleExit(job_id, exit_code) abort
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist)
endfunction
function! s:HandleLSPDiagnostics(conn_id, response) abort
let l:linter_name = s:lsp_linter_map[a:conn_id]
let l:filename = ale#path#FromURI(a:response.params.uri)
let l:buffer = bufnr(l:filename)
if l:buffer <= 0
return
endif
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
endfunction
function! s:HandleTSServerDiagnostics(response, error_type) abort
let l:buffer = bufnr(a:response.body.file)
let l:info = get(g:ale_buffer_info, l:buffer, {})
if empty(l:info)
return
endif
let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response)
" tsserver sends syntax and semantic errors in separate messages, so we
" have to collect the messages separately for each buffer and join them
" back together again.
if a:error_type is# 'syntax'
let l:info.syntax_loclist = l:thislist
else
let l:info.semantic_loclist = l:thislist
endif
let l:loclist = get(l:info, 'semantic_loclist', [])
\ + get(l:info, 'syntax_loclist', [])
call ale#engine#HandleLoclist('tsserver', l:buffer, l:loclist)
endfunction
function! s:HandleLSPErrorMessage(error_message) abort
execute 'echoerr ''Error from LSP:'''
for l:line in split(a:error_message, "\n")
execute 'echoerr l:line'
endfor
endfunction
function! ale#engine#HandleLSPResponse(conn_id, response) abort
let l:method = get(a:response, 'method', '')
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
" Uncomment this line to print LSP error messages.
" call s:HandleLSPErrorMessage(a:response.error.message)
elseif l:method is# 'textDocument/publishDiagnostics'
call s:HandleLSPDiagnostics(a:conn_id, a:response)
elseif get(a:response, 'type', '') is# 'event'
\&& get(a:response, 'event', '') is# 'semanticDiag'
call s:HandleTSServerDiagnostics(a:response, 'semantic')
elseif get(a:response, 'type', '') is# 'event'
\&& get(a:response, 'event', '') is# 'syntaxDiag'
call s:HandleTSServerDiagnostics(a:response, 'syntax')
endif
endfunction
function! ale#engine#SetResults(buffer, loclist) abort
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
@@ -270,6 +339,8 @@ function! ale#engine#SetResults(buffer, loclist) abort
" Call user autocommands. This allows users to hook into ALE's lint cycle.
silent doautocmd <nomodeline> User ALELintPost
" Old DEPRECATED name; call it for backwards compatibility.
silent doautocmd <nomodeline> User ALELint
endif
endfunction
@@ -322,7 +393,7 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
\ 'text': l:old_item.text,
\ 'lnum': str2nr(l:old_item.lnum),
\ 'col': str2nr(get(l:old_item, 'col', 0)),
\ 'vcol': 0,
\ 'vcol': get(l:old_item, 'vcol', 0),
\ 'type': get(l:old_item, 'type', 'E'),
\ 'nr': get(l:old_item, 'nr', -1),
\ 'linter_name': a:linter_name,
@@ -382,20 +453,6 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
" When errors go beyond the end of the file, put them at the end.
" This is only done for the current buffer.
let l:item.lnum = l:last_line_number
elseif get(l:old_item, 'vcol', 0)
" Convert virtual column positions to byte positions.
" The positions will be off if the buffer has changed recently.
let l:line = getbufline(a:buffer, l:item.lnum)[0]
let l:item.col = ale#util#Col(l:line, l:item.col)
if has_key(l:item, 'end_col')
let l:end_line = get(l:item, 'end_lnum', l:line) != l:line
\ ? getbufline(a:buffer, l:item.end_lnum)[0]
\ : l:line
let l:item.end_col = ale#util#Col(l:end_line, l:item.end_col)
endif
endif
call add(l:new_loclist, l:item)
@@ -515,8 +572,6 @@ function! s:RunJob(options) abort
\ 'output': [],
\ 'next_chain_index': l:next_chain_index,
\}
silent doautocmd <nomodeline> User ALEJobStarted
endif
if g:ale_history_enabled
@@ -639,6 +694,44 @@ function! s:StopCurrentJobs(buffer, include_lint_file_jobs) abort
let l:info.active_linter_list = l:new_active_linter_list
endfunction
function! s:CheckWithLSP(buffer, linter) abort
let l:info = g:ale_buffer_info[a:buffer]
let l:lsp_details = ale#linter#StartLSP(
\ a:buffer,
\ a:linter,
\ function('ale#engine#HandleLSPResponse'),
\)
if empty(l:lsp_details)
return 0
endif
let l:id = l:lsp_details.connection_id
let l:root = l:lsp_details.project_root
" Remember the linter this connection is for.
let s:lsp_linter_map[l:id] = a:linter.name
let l:change_message = a:linter.lsp is# 'tsserver'
\ ? ale#lsp#tsserver_message#Geterr(a:buffer)
\ : ale#lsp#message#DidChange(a:buffer)
let l:request_id = ale#lsp#Send(l:id, l:change_message, l:root)
" If this was a file save event, also notify the server of that.
if a:linter.lsp isnot# 'tsserver'
\&& getbufvar(a:buffer, 'ale_save_event_fired', 0)
let l:save_message = ale#lsp#message#DidSave(a:buffer)
let l:request_id = ale#lsp#Send(l:id, l:save_message, l:root)
endif
if l:request_id != 0
if index(l:info.active_linter_list, a:linter.name) < 0
call add(l:info.active_linter_list, a:linter.name)
endif
endif
return l:request_id != 0
endfunction
function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
" Figure out which linters are still enabled, and remove
@@ -694,7 +787,7 @@ endfunction
" Returns 1 if the linter was successfully run.
function! s:RunLinter(buffer, linter) abort
if !empty(a:linter.lsp)
return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter)
return s:CheckWithLSP(a:buffer, a:linter)
else
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
@@ -776,7 +869,7 @@ endfunction
" The time taken will be a very rough approximation, and more time may be
" permitted than is specified.
function! ale#engine#WaitForJobs(deadline) abort
let l:start_time = ale#events#ClockMilliseconds()
let l:start_time = ale#util#ClockMilliseconds()
if l:start_time == 0
throw 'Failed to read milliseconds from the clock!'
@@ -807,7 +900,7 @@ function! ale#engine#WaitForJobs(deadline) abort
for l:job_id in l:job_list
if ale#job#IsRunning(l:job_id)
let l:now = ale#events#ClockMilliseconds()
let l:now = ale#util#ClockMilliseconds()
if l:now - l:start_time > a:deadline
" Stop waiting after a timeout, so we don't wait forever.
@@ -844,7 +937,7 @@ function! ale#engine#WaitForJobs(deadline) abort
if l:has_new_jobs
" We have to wait more. Offset the timeout by the time taken so far.
let l:now = ale#events#ClockMilliseconds()
let l:now = ale#util#ClockMilliseconds()
let l:new_deadline = a:deadline - (l:now - l:start_time)
if l:new_deadline <= 0

View File

@@ -1,46 +0,0 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Code for ignoring linters. Only loaded and if configured.
" Given a filetype and a configuration for ignoring linters, return a List of
" Strings for linter names to ignore.
function! ale#engine#ignore#GetList(filetype, config) abort
if type(a:config) is type([])
return a:config
endif
if type(a:config) is type({})
let l:names_to_remove = []
for l:part in split(a:filetype , '\.')
call extend(l:names_to_remove, get(a:config, l:part, []))
endfor
return l:names_to_remove
endif
return []
endfunction
" Given a List of linter descriptions, exclude the linters to be ignored.
function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort
let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config)
let l:filtered_linters = []
for l:linter in a:all_linters
let l:name_list = [l:linter.name] + l:linter.aliases
let l:should_include = 1
for l:name in l:name_list
if index(l:names_to_remove, l:name) >= 0
let l:should_include = 0
break
endif
endfor
if l:should_include
call add(l:filtered_linters, l:linter)
endif
endfor
return l:filtered_linters
endfunction

View File

@@ -1,25 +1,14 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: ALE functions for autocmd events.
" Get the number of milliseconds since some vague, but consistent, point in
" the past.
"
" This function can be used for timing execution, etc.
"
" The time will be returned as a Number.
function! ale#events#ClockMilliseconds() abort
return float2nr(reltimefloat(reltime()) * 1000)
endfunction
function! ale#events#QuitEvent(buffer) abort
" Remember when ALE is quitting for BufWrite, etc.
call setbufvar(a:buffer, 'ale_quitting', ale#events#ClockMilliseconds())
call setbufvar(a:buffer, 'ale_quitting', ale#util#ClockMilliseconds())
endfunction
function! ale#events#QuitRecently(buffer) abort
let l:time = getbufvar(a:buffer, 'ale_quitting', 0)
return l:time && ale#events#ClockMilliseconds() - l:time < 1000
return l:time && ale#util#ClockMilliseconds() - l:time < 1000
endfunction
function! ale#events#SaveEvent(buffer) abort
@@ -30,7 +19,7 @@ function! ale#events#SaveEvent(buffer) abort
endif
if ale#Var(a:buffer, 'fix_on_save')
let l:will_fix = ale#fix#Fix(a:buffer, 'save_file')
let l:will_fix = ale#fix#Fix('save_file')
let l:should_lint = l:should_lint && !l:will_fix
endif
@@ -78,56 +67,3 @@ function! ale#events#FileChangedEvent(buffer) abort
call s:LintOnEnter(a:buffer)
endif
endfunction
function! ale#events#Init() abort
" This value used to be a Boolean as a Number, and is now a String.
let l:text_changed = '' . g:ale_lint_on_text_changed
augroup ALEEvents
autocmd!
" These events always need to be set up.
autocmd BufEnter,BufRead * call ale#pattern_options#SetOptions(str2nr(expand('<abuf>')))
autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
if g:ale_enabled
if l:text_changed is? 'always' || l:text_changed is# '1'
autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay)
elseif l:text_changed is? 'normal'
autocmd TextChanged * call ale#Queue(g:ale_lint_delay)
elseif l:text_changed is? 'insert'
autocmd TextChangedI * call ale#Queue(g:ale_lint_delay)
endif
" Handle everything that needs to happen when buffers are entered.
autocmd BufEnter * call ale#events#EnterEvent(str2nr(expand('<abuf>')))
if g:ale_lint_on_enter
autocmd BufWinEnter,BufRead * call ale#Queue(0, 'lint_file', str2nr(expand('<abuf>')))
" Track when the file is changed outside of Vim.
autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('<abuf>')))
endif
if g:ale_lint_on_filetype_changed
" Only start linting if the FileType actually changes after
" opening a buffer. The FileType will fire when buffers are opened.
autocmd FileType * call ale#events#FileTypeEvent(
\ str2nr(expand('<abuf>')),
\ expand('<amatch>')
\)
endif
if g:ale_lint_on_insert_leave
autocmd InsertLeave * call ale#Queue(0)
endif
if g:ale_echo_cursor
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif
" Look for a warning to echo as soon as we leave Insert mode.
" The script's position variable used when moving the cursor will
" not be changed here.
autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarning() | endif
endif
endif
augroup END
endfunction

View File

@@ -28,6 +28,8 @@ function! ale#fix#ApplyQueuedFixes() abort
call remove(g:ale_fix_buffer_data, l:buffer)
if l:data.changes_made
call setline(1, l:data.output)
let l:start_line = len(l:data.output) + 1
let l:end_line = len(l:data.lines_before)
@@ -37,8 +39,6 @@ function! ale#fix#ApplyQueuedFixes() abort
call winrestview(l:save)
endif
call setline(1, l:data.output)
if l:data.should_save
if empty(&buftype)
noautocmd :w!
@@ -356,41 +356,25 @@ function! s:RunFixer(options) abort
call ale#fix#ApplyFixes(l:buffer, l:input)
endfunction
function! s:AddSubCallbacks(full_list, callbacks) abort
if type(a:callbacks) == type('')
call add(a:full_list, a:callbacks)
elseif type(a:callbacks) == type([])
call extend(a:full_list, a:callbacks)
else
return 0
endif
return 1
endfunction
function! s:GetCallbacks(buffer, fixers) abort
if len(a:fixers)
let l:callback_list = a:fixers
elseif type(get(b:, 'ale_fixers')) is type([])
function! s:GetCallbacks() abort
if type(get(b:, 'ale_fixers')) is type([])
" Lists can be used for buffer-local variables only
let l:callback_list = b:ale_fixers
else
" buffer and global options can use dictionaries mapping filetypes to
" callbacks to run.
let l:fixers = ale#Var(a:buffer, 'fixers')
let l:fixers = ale#Var(bufnr(''), 'fixers')
let l:callback_list = []
let l:matched = 0
for l:sub_type in split(&filetype, '\.')
if s:AddSubCallbacks(l:callback_list, get(l:fixers, l:sub_type))
let l:matched = 1
let l:sub_type_callacks = get(l:fixers, l:sub_type, [])
if type(l:sub_type_callacks) == type('')
call add(l:callback_list, l:sub_type_callacks)
else
call extend(l:callback_list, l:sub_type_callacks)
endif
endfor
" If we couldn't find fixers for a filetype, default to '*' fixers.
if !l:matched
call s:AddSubCallbacks(l:callback_list, get(l:fixers, '*'))
endif
endif
if empty(l:callback_list)
@@ -438,13 +422,19 @@ endfunction
" Accepts an optional argument for what to do when fixing.
"
" Returns 0 if no fixes can be applied, and 1 if fixing can be done.
function! ale#fix#Fix(buffer, fixing_flag, ...) abort
if a:fixing_flag isnot# '' && a:fixing_flag isnot# 'save_file'
function! ale#fix#Fix(...) abort
if len(a:0) > 1
throw 'too many arguments!'
endif
let l:fixing_flag = get(a:000, 0, '')
if l:fixing_flag isnot# '' && l:fixing_flag isnot# 'save_file'
throw "fixing_flag must be either '' or 'save_file'"
endif
try
let l:callback_list = s:GetCallbacks(a:buffer, a:000)
let l:callback_list = s:GetCallbacks()
catch /E700\|BADNAME/
let l:function_name = join(split(split(v:exception, ':')[3]))
let l:echo_message = printf(
@@ -457,27 +447,29 @@ function! ale#fix#Fix(buffer, fixing_flag, ...) abort
endtry
if empty(l:callback_list)
if a:fixing_flag is# ''
if l:fixing_flag is# ''
execute 'echom ''No fixers have been defined. Try :ALEFixSuggest'''
endif
return 0
endif
let l:buffer = bufnr('')
for l:job_id in keys(s:job_info_map)
call remove(s:job_info_map, l:job_id)
call ale#job#Stop(l:job_id)
endfor
" Clean up any files we might have left behind from a previous run.
call ale#fix#RemoveManagedFiles(a:buffer)
call ale#fix#InitBufferData(a:buffer, a:fixing_flag)
call ale#fix#RemoveManagedFiles(l:buffer)
call ale#fix#InitBufferData(l:buffer, l:fixing_flag)
silent doautocmd <nomodeline> User ALEFixPre
call s:RunFixer({
\ 'buffer': a:buffer,
\ 'input': g:ale_fix_buffer_data[a:buffer].lines_before,
\ 'buffer': l:buffer,
\ 'input': g:ale_fix_buffer_data[l:buffer].lines_before,
\ 'callback_index': 0,
\ 'callback_list': l:callback_list,
\})

View File

@@ -17,16 +17,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with autopep8.',
\ },
\ 'black': {
\ 'function': 'ale#fixers#black#Fix',
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with black.',
\ },
\ 'tidy': {
\ 'function': 'ale#fixers#tidy#Fix',
\ 'suggested_filetypes': ['html'],
\ 'description': 'Fix HTML files with tidy.',
\ },
\ 'prettier_standard': {
\ 'function': 'ale#fixers#prettier_standard#Fix',
\ 'suggested_filetypes': ['javascript'],
@@ -56,7 +46,7 @@ let s:default_registry = {
\ },
\ 'prettier': {
\ 'function': 'ale#fixers#prettier#Fix',
\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue'],
\ 'suggested_filetypes': ['javascript', 'typescript', 'json', 'css', 'scss', 'less', 'markdown', 'graphql', 'vue'],
\ 'description': 'Apply prettier to a file.',
\ },
\ 'prettier_eslint': {
@@ -100,11 +90,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['ruby'],
\ 'description': 'Fix ruby files with rufo',
\ },
\ 'scalafmt': {
\ 'function': 'ale#fixers#scalafmt#Fix',
\ 'suggested_filetypes': ['scala'],
\ 'description': 'Fix Scala files using scalafmt',
\ },
\ 'standard': {
\ 'function': 'ale#fixers#standard#Fix',
\ 'suggested_filetypes': ['javascript'],
@@ -195,26 +180,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['json'],
\ 'description': 'Fix JSON files with jq.',
\ },
\ 'perltidy': {
\ 'function': 'ale#fixers#perltidy#Fix',
\ 'suggested_filetypes': ['perl'],
\ 'description': 'Fix Perl files with perltidy.',
\ },
\ 'xo': {
\ 'function': 'ale#fixers#xo#Fix',
\ 'suggested_filetypes': ['javascript'],
\ 'description': 'Fix JavaScript files using xo --fix.',
\ },
\ 'qmlfmt': {
\ 'function': 'ale#fixers#qmlfmt#Fix',
\ 'suggested_filetypes': ['qml'],
\ 'description': 'Fix QML files with qmlfmt.',
\ },
\ 'dartfmt': {
\ 'function': 'ale#fixers#dartfmt#Fix',
\ 'suggested_filetypes': ['dart'],
\ 'description': 'Fix Dart files with dartfmt.',
\ },
\}
" Reset the function registry to the default entries.
@@ -307,14 +272,6 @@ function! s:ShouldSuggestForType(suggested_filetypes, type_list) abort
return 0
endfunction
function! s:IsGenericFixer(suggested_filetypes) abort
if empty(a:suggested_filetypes)
return 1
endif
return 0
endfunction
function! s:FormatEntry(key, entry) abort
let l:aliases_str = ''
@@ -334,28 +291,8 @@ function! s:FormatEntry(key, entry) abort
\)
endfunction
" Get list of applicable fixers for filetype, including generic fixers
function! ale#fix#registry#GetApplicableFixers(filetype) abort
let l:type_list = split(a:filetype, '\.')
let l:fixer_name_list = []
for l:key in sort(keys(s:entries))
let l:suggested_filetypes = s:entries[l:key].suggested_filetypes
if s:IsGenericFixer(l:suggested_filetypes) || s:ShouldSuggestForType(l:suggested_filetypes, l:type_list)
call add(l:fixer_name_list, l:key)
endif
endfor
return l:fixer_name_list
endfunction
" Function that returns autocomplete candidates for ALEFix command
function! ale#fix#registry#CompleteFixers(ArgLead, CmdLine, CursorPos) abort
return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead')
endfunction
function! ale#fix#registry#SuggestedFixers(filetype) abort
" Suggest functions to use from the registry.
function! ale#fix#registry#Suggest(filetype) abort
let l:type_list = split(a:filetype, '\.')
let l:filetype_fixer_list = []
@@ -373,7 +310,7 @@ function! ale#fix#registry#SuggestedFixers(filetype) abort
let l:generic_fixer_list = []
for l:key in sort(keys(s:entries))
if s:IsGenericFixer(s:entries[l:key].suggested_filetypes)
if empty(s:entries[l:key].suggested_filetypes)
call add(
\ l:generic_fixer_list,
\ s:FormatEntry(l:key, s:entries[l:key]),
@@ -381,15 +318,6 @@ function! ale#fix#registry#SuggestedFixers(filetype) abort
endif
endfor
return [l:filetype_fixer_list, l:generic_fixer_list]
endfunction
" Suggest functions to use from the registry.
function! ale#fix#registry#Suggest(filetype) abort
let l:suggested = ale#fix#registry#SuggestedFixers(a:filetype)
let l:filetype_fixer_list = l:suggested[0]
let l:generic_fixer_list = l:suggested[1]
let l:filetype_fixer_header = !empty(l:filetype_fixer_list)
\ ? ['Try the following fixers appropriate for the filetype:', '']
\ : []

View File

@@ -2,7 +2,7 @@
" Description: Fixing files with autopep8.
call ale#Set('python_autopep8_executable', 'autopep8')
call ale#Set('python_autopep8_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_autopep8_use_global', 0)
call ale#Set('python_autopep8_options', '')
function! ale#fixers#autopep8#Fix(buffer) abort

View File

@@ -1,26 +0,0 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Fixing Python files with black.
"
call ale#Set('python_black_executable', 'black')
call ale#Set('python_black_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_black_options', '')
function! ale#fixers#black#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_black',
\ ['black'],
\)
if !executable(l:executable)
return 0
endif
let l:options = ale#Var(a:buffer, 'python_black_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -',
\}
endfunction

View File

@@ -3,7 +3,7 @@ scriptencoding utf-8
" Description: Fixing C/C++ files with clang-format.
call ale#Set('c_clangformat_executable', 'clang-format')
call ale#Set('c_clangformat_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('c_clangformat_use_global', 0)
call ale#Set('c_clangformat_options', '')
function! ale#fixers#clangformat#GetExecutable(buffer) abort

View File

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

View File

@@ -2,7 +2,7 @@
" Description: Integration of elm-format with ALE.
call ale#Set('elm_format_executable', 'elm-format')
call ale#Set('elm_format_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('elm_format_use_global', 0)
call ale#Set('elm_format_options', '--yes')
function! ale#fixers#elm_format#GetExecutable(buffer) abort

View File

@@ -3,7 +3,7 @@
call ale#Set('json_fixjson_executable', 'fixjson')
call ale#Set('json_fixjson_options', '')
call ale#Set('json_fixjson_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('json_fixjson_use_global', 0)
function! ale#fixers#fixjson#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'json_fixjson', [

View File

@@ -2,7 +2,7 @@
" Description: Integration of Google-java-format with ALE.
call ale#Set('google_java_format_executable', 'google-java-format')
call ale#Set('google_java_format_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('google_java_format_use_global', 0)
call ale#Set('google_java_format_options', '')
function! ale#fixers#google_java_format#Fix(buffer) abort

View File

@@ -2,7 +2,7 @@
" Description: Fixing Python imports with isort.
call ale#Set('python_isort_executable', 'isort')
call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_isort_use_global', 0)
function! ale#fixers#isort#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(

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