mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-07 05:04:28 +08:00
Compare commits
125 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ee3dcdd62 | ||
|
|
465db4daa1 | ||
|
|
fb8c090971 | ||
|
|
d29e32d42d | ||
|
|
ab2b181012 | ||
|
|
033a6c1178 | ||
|
|
7d66293bbc | ||
|
|
1fc3a1563b | ||
|
|
a31f54d08f | ||
|
|
db85b931ec | ||
|
|
602e7fa00f | ||
|
|
e10e0934ab | ||
|
|
1d8b326f62 | ||
|
|
1565859eae | ||
|
|
7ce919e690 | ||
|
|
25a03dcea1 | ||
|
|
73d3030cf1 | ||
|
|
4987946175 | ||
|
|
e46474ac0a | ||
|
|
5aba55bb86 | ||
|
|
01c68fedd6 | ||
|
|
20ed48352f | ||
|
|
09a53fb363 | ||
|
|
b637b35ea8 | ||
|
|
ce7d648c7c | ||
|
|
8ac43b1936 | ||
|
|
1c5c4a4c8e | ||
|
|
059c5cfca4 | ||
|
|
23394bf4a5 | ||
|
|
ea6d720fec | ||
|
|
2a78401066 | ||
|
|
d456ac19ca | ||
|
|
9d98e6db0c | ||
|
|
06f61eeeb8 | ||
|
|
e5e14de9ae | ||
|
|
fee5107d43 | ||
|
|
cd8dd099d8 | ||
|
|
857a07f36a | ||
|
|
26aa0cf358 | ||
|
|
3c5b6d1825 | ||
|
|
ccfed164bc | ||
|
|
1487c8daa0 | ||
|
|
1990efdba7 | ||
|
|
b88bf6ecba | ||
|
|
ee81351a63 | ||
|
|
0b7a29d73b | ||
|
|
fc041ae090 | ||
|
|
d581fca35e | ||
|
|
8b407ed0e7 | ||
|
|
51a14a4ba8 | ||
|
|
d9e139ae23 | ||
|
|
980aa35566 | ||
|
|
b047271051 | ||
|
|
1ca2334846 | ||
|
|
4d935ff32a | ||
|
|
66820ed452 | ||
|
|
d05936a489 | ||
|
|
49d995a521 | ||
|
|
bedd30ee11 | ||
|
|
620951b6d3 | ||
|
|
755f1a4ccf | ||
|
|
17c1aefb5b | ||
|
|
0f377251dd | ||
|
|
935740cf93 | ||
|
|
8bca073763 | ||
|
|
22533f2c1f | ||
|
|
69eb2fe86a | ||
|
|
34755eecdd | ||
|
|
90dfe8e2a4 | ||
|
|
11f303f853 | ||
|
|
b8be25adb4 | ||
|
|
d7efb13203 | ||
|
|
f14e3bb109 | ||
|
|
b7db095221 | ||
|
|
0e1528ec34 | ||
|
|
9674132933 | ||
|
|
82ea36576c | ||
|
|
fd261d7a17 | ||
|
|
3a5887df2c | ||
|
|
e306e5cdb0 | ||
|
|
b8a1038a41 | ||
|
|
43ce8d7610 | ||
|
|
24fe195311 | ||
|
|
49a5d657ee | ||
|
|
bda89506ba | ||
|
|
bd4da116ee | ||
|
|
eabf5d55d6 | ||
|
|
f1b72218c3 | ||
|
|
5283faa511 | ||
|
|
87455a2ef4 | ||
|
|
d9746a4572 | ||
|
|
ae25d71fa8 | ||
|
|
22a9dcd03e | ||
|
|
fd7456fce0 | ||
|
|
864818a385 | ||
|
|
f0f569f14a | ||
|
|
42192c1593 | ||
|
|
252097bee0 | ||
|
|
10a9177b6b | ||
|
|
d1be72f438 | ||
|
|
67753de531 | ||
|
|
20db9ab719 | ||
|
|
641c0c797b | ||
|
|
1a4b08539b | ||
|
|
c49ea1a5e3 | ||
|
|
3a6a92283e | ||
|
|
ca88e67af0 | ||
|
|
b3da52d38d | ||
|
|
5addd3abef | ||
|
|
e272207114 | ||
|
|
4ec661b305 | ||
|
|
03d14324ea | ||
|
|
a8bbf49a31 | ||
|
|
0db12702f3 | ||
|
|
dd642b117c | ||
|
|
77d0ac58ed | ||
|
|
81739be0a0 | ||
|
|
786fc0a62f | ||
|
|
014d27c882 | ||
|
|
d760558007 | ||
|
|
fae9167083 | ||
|
|
201f8519d9 | ||
|
|
6a7e00d9ac | ||
|
|
801c12a881 | ||
|
|
3a1d21e5dd |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -2,6 +2,7 @@
|
|||||||
/CODE_OF_CONDUCT.md export-ignore
|
/CODE_OF_CONDUCT.md export-ignore
|
||||||
/CONTRIBUTING.md export-ignore
|
/CONTRIBUTING.md export-ignore
|
||||||
/Dockerfile export-ignore
|
/Dockerfile export-ignore
|
||||||
|
/ISSUE_TEMPLATE export-ignore
|
||||||
/ISSUE_TEMPLATE.md export-ignore
|
/ISSUE_TEMPLATE.md export-ignore
|
||||||
/Makefile export-ignore
|
/Makefile export-ignore
|
||||||
/PULL_REQUEST_TEMPLATE.md export-ignore
|
/PULL_REQUEST_TEMPLATE.md export-ignore
|
||||||
|
|||||||
40
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
40
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
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.
|
||||||
20
.github/ISSUE_TEMPLATE/suggest-a-new-linter-or-fixer.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/suggest-a-new-linter-or-fixer.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
7
.github/ISSUE_TEMPLATE/suggest-an-improvement.md
vendored
Normal file
7
.github/ISSUE_TEMPLATE/suggest-an-improvement.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
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. -->
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
sudo: required
|
sudo: required
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
language: python
|
language: generic
|
||||||
script: |
|
script: |
|
||||||
./run-tests
|
./run-tests -v
|
||||||
|
|||||||
156
CONTRIBUTING.md
156
CONTRIBUTING.md
@@ -1,37 +1,11 @@
|
|||||||
# Contributing to ALE
|
## Guidelines
|
||||||
|
|
||||||
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:.
|
Have fun, and work on whatever floats your boat. Take It Easy :tm:.
|
||||||
|
|
||||||
Don't forget to **write documentation** for whatever it is you are doing.
|
For help with contributing to ALE, see `:help ale-development` in Vim, or view
|
||||||
See the ["Writing Documentation"](#writing-documentation) section.
|
the help file online [here](/w0rp/ale/blob/master/doc/ale-development.txt).
|
||||||
|
|
||||||
Remember to write Vader tests for most of the code you write. You can look at
|
## Creating Issues
|
||||||
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
|
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
|
pull requests, and ensure that the issue hasn't already been reported. If an
|
||||||
@@ -49,125 +23,3 @@ operating system, or any other information you think might be helpful.
|
|||||||
Please describe your issue in clear, grammatically correct, and easy to
|
Please describe your issue in clear, grammatically correct, and easy to
|
||||||
understand English. You are more likely to see an issue resolved if others
|
understand English. You are more likely to see an issue resolved if others
|
||||||
can understand you.
|
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.
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
FROM tweekmonster/vim-testbed:latest
|
FROM tweekmonster/vim-testbed:latest
|
||||||
|
|
||||||
RUN install_vim -tag v8.0.0027 -build \
|
RUN install_vim -tag v8.0.0027 -build \
|
||||||
-tag neovim:v0.1.7 -build
|
-tag neovim:v0.2.0 -build \
|
||||||
|
-tag neovim:v0.3.0 -build
|
||||||
|
|
||||||
ENV PACKAGES="\
|
ENV PACKAGES="\
|
||||||
bash \
|
bash \
|
||||||
@@ -12,7 +13,7 @@ ENV PACKAGES="\
|
|||||||
RUN apk --update add $PACKAGES && \
|
RUN apk --update add $PACKAGES && \
|
||||||
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
|
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
RUN pip install vim-vint==0.3.9
|
RUN pip install vim-vint==0.3.15
|
||||||
|
|
||||||
RUN git clone https://github.com/junegunn/vader.vim vader && \
|
RUN git clone https://github.com/junegunn/vader.vim vader && \
|
||||||
cd vader && git checkout c6243dd81c98350df4dec608fa972df98fa2a3af
|
cd vader && git checkout c6243dd81c98350df4dec608fa972df98fa2a3af
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
<!--
|
|
||||||
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.
|
|
||||||
@@ -1,22 +1,8 @@
|
|||||||
<!--
|
<!--
|
||||||
READ THIS: Before creating a pull request, please consider the following first.
|
Before creating a pull request, do the following.
|
||||||
|
|
||||||
* 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 Contributing guide linked above first.
|
||||||
* If you are adding a new linter, remember to update the README.md file and
|
* Read the documentation that comes with ALE with `:help ale-development`.
|
||||||
doc/ale.txt first.
|
|
||||||
* If you add or modify a function for converting error lines into loclist items
|
Have fun!
|
||||||
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. Look at existing
|
|
||||||
tests in the test/command_callback directory, etc.
|
|
||||||
* 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!
|
|
||||||
-->
|
-->
|
||||||
|
|||||||
24
README.md
24
README.md
@@ -29,6 +29,10 @@ features, including:
|
|||||||
* Finding references (`:ALEFindReferences`)
|
* Finding references (`:ALEFindReferences`)
|
||||||
* Hover information (`:ALEHover`)
|
* 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.
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
1. [Supported Languages and Tools](#supported-languages)
|
1. [Supported Languages and Tools](#supported-languages)
|
||||||
@@ -90,14 +94,15 @@ formatting.
|
|||||||
| API Blueprint | [drafter](https://github.com/apiaryio/drafter) |
|
| 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) |
|
| 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/)|
|
| Awk | [gawk](https://www.gnu.org/software/gawk/)|
|
||||||
| 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) |
|
| 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) |
|
||||||
| Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [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 | [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) !!, [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/) |
|
||||||
| CUDA | [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) |
|
| 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|
|
| 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/) |
|
| Chef | [foodcritic](http://www.foodcritic.io/) |
|
||||||
| Clojure | [joker](https://github.com/candid82/joker) |
|
| 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) |
|
| CMake | [cmakelint](https://github.com/richq/cmake-lint) |
|
||||||
| CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) |
|
| CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) |
|
||||||
| Crystal | [crystal](https://crystal-lang.org/) !! |
|
| Crystal | [crystal](https://crystal-lang.org/) !! |
|
||||||
@@ -106,9 +111,9 @@ formatting.
|
|||||||
| Cython (pyrex filetype) | [cython](http://cython.org/) |
|
| Cython (pyrex filetype) | [cython](http://cython.org/) |
|
||||||
| D | [dmd](https://dlang.org/dmd-linux.html) |
|
| D | [dmd](https://dlang.org/dmd-linux.html) |
|
||||||
| Dafny | [dafny](https://rise4fun.com/Dafny) !! |
|
| 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) |
|
| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) |
|
||||||
| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) |
|
| 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) !!|
|
| 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) !!|
|
||||||
| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) |
|
| 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) |
|
| 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) |
|
| Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) |
|
||||||
@@ -153,7 +158,7 @@ formatting.
|
|||||||
| proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) |
|
| proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) |
|
||||||
| Pug | [pug-lint](https://github.com/pugjs/pug-lint) |
|
| Pug | [pug-lint](https://github.com/pugjs/pug-lint) |
|
||||||
| Puppet | [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) |
|
| 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), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) |
|
| 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) |
|
| QML | [qmlfmt](https://github.com/jesperhh/qmlfmt), [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) |
|
||||||
| R | [lintr](https://github.com/jimhester/lintr) |
|
| 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) |
|
| 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) |
|
||||||
@@ -164,7 +169,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) |
|
| 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) |
|
| 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) |
|
| 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), [scalastyle](http://www.scalastyle.org) |
|
| 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) |
|
||||||
| Slim | [slim-lint](https://github.com/sds/slim-lint) |
|
| Slim | [slim-lint](https://github.com/sds/slim-lint) |
|
||||||
| SML | [smlnj](http://www.smlnj.org/) |
|
| SML | [smlnj](http://www.smlnj.org/) |
|
||||||
| Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) |
|
| Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) |
|
||||||
@@ -253,7 +258,7 @@ 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
|
ALE offers some support for completion via hijacking of omnicompletion while you
|
||||||
type. All of ALE's completion information must come from Language Server
|
type. All of ALE's completion information must come from Language Server
|
||||||
Protocol linters, or from `tsserver` for TypeSript.
|
Protocol linters, or from `tsserver` for TypeScript.
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
" Enable completion where available.
|
" Enable completion where available.
|
||||||
@@ -749,8 +754,9 @@ ALE cannot easily detect which compiler flags to use.
|
|||||||
|
|
||||||
Some tools and build configurations can generate
|
Some tools and build configurations can generate
|
||||||
[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
||||||
files. The `cppcheck`, `clangcheck` and `clangtidy` linters can read these
|
files. The `cppcheck`, `clangcheck`, `clangtidy` and `cquery` linters can read
|
||||||
files for automatically determining the appropriate compiler flags to use.
|
these files for automatically determining the appropriate compiler flags to
|
||||||
|
use.
|
||||||
|
|
||||||
For linting with compilers like `gcc` and `clang`, and with other tools, you
|
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
|
will need to tell ALE which compiler flags to use yourself. You can use
|
||||||
|
|||||||
35
ale_linters/cloudformation/cfn_python_lint.vim
Normal file
35
ale_linters/cloudformation/cfn_python_lint.vim
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
" 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',
|
||||||
|
\})
|
||||||
34
ale_linters/cpp/cquery.vim
Normal file
34
ale_linters/cpp/cquery.vim
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
" 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',
|
||||||
|
\})
|
||||||
@@ -29,7 +29,7 @@ function! ale_linters#cs#mcsc#GetCommand(buffer) abort
|
|||||||
\ : ''
|
\ : ''
|
||||||
|
|
||||||
" register temporary module target file with ale
|
" register temporary module target file with ale
|
||||||
let l:out = tempname()
|
let l:out = ale#util#Tempname()
|
||||||
call ale#engine#ManageFile(a:buffer, l:out)
|
call ale#engine#ManageFile(a:buffer, l:out)
|
||||||
|
|
||||||
" The code is compiled as a module and the output is redirected to a
|
" The code is compiled as a module and the output is redirected to a
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ endfunction
|
|||||||
|
|
||||||
function! ale_linters#cuda#nvcc#GetCommand(buffer) abort
|
function! ale_linters#cuda#nvcc#GetCommand(buffer) abort
|
||||||
" Unused: use ale#util#nul_file
|
" Unused: use ale#util#nul_file
|
||||||
" let l:output_file = tempname() . '.ii'
|
" let l:output_file = ale#util#Tempname() . '.ii'
|
||||||
" call ale#engine#ManageFile(a:buffer, l:output_file)
|
" call ale#engine#ManageFile(a:buffer, l:output_file)
|
||||||
|
|
||||||
return ale#Escape(ale_linters#cuda#nvcc#GetExecutable(a:buffer))
|
return ale#Escape(ale_linters#cuda#nvcc#GetExecutable(a:buffer))
|
||||||
|
|||||||
61
ale_linters/elixir/mix.vim
Normal file
61
ale_linters/elixir/mix.vim
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
" 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,
|
||||||
|
\})
|
||||||
@@ -128,14 +128,7 @@ function! ale_linters#elm#make#HandleElm018Line(line, output) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#elm#make#FileIsBuffer(path) abort
|
function! ale_linters#elm#make#FileIsBuffer(path) abort
|
||||||
let l:is_windows = has('win32')
|
return ale#path#IsTempName(a:path)
|
||||||
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
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#elm#make#ParseMessage(message) abort
|
function! ale_linters#elm#make#ParseMessage(message) abort
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '')
|
let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '')
|
||||||
|
|
||||||
function! ale_linters#erlang#erlc#GetCommand(buffer) abort
|
function! ale_linters#erlang#erlc#GetCommand(buffer) abort
|
||||||
let l:output_file = tempname()
|
let l:output_file = ale#util#Tempname()
|
||||||
call ale#engine#ManageFile(a:buffer, l:output_file)
|
call ale#engine#ManageFile(a:buffer, l:output_file)
|
||||||
|
|
||||||
return 'erlc -o ' . ale#Escape(l:output_file)
|
return 'erlc -o ' . ale#Escape(l:output_file)
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ function! ale_linters#gitcommit#gitlint#Handle(buffer, lines) abort
|
|||||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||||
let l:code = l:match[2]
|
let l:code = l:match[2]
|
||||||
|
|
||||||
|
if l:code is# 'T2' && !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
let l:item = {
|
let l:item = {
|
||||||
\ 'lnum': l:match[1] + 0,
|
\ 'lnum': l:match[1] + 0,
|
||||||
\ 'text': l:match[3],
|
\ 'text': l:match[3],
|
||||||
|
|||||||
@@ -1,21 +1,10 @@
|
|||||||
" Author: KabbAmine <amine.kabb@gmail.com>
|
" Author: KabbAmine <amine.kabb@gmail.com>
|
||||||
" Description: This file adds support for checking HTML code with tidy.
|
" 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_executable = get(g:, 'ale_html_tidy_executable', 'tidy')
|
||||||
" remove in 2.0
|
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:deprecation_warning_echoed = 0
|
|
||||||
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
|
function! ale_linters#html#tidy#GetCommand(buffer) abort
|
||||||
" remove in 2.0
|
|
||||||
if exists('g:ale_html_tidy_args') && !s:deprecation_warning_echoed
|
|
||||||
execute 'echom ''Rename your g:ale_html_tidy_args setting to g:ale_html_tidy_options instead. Support for this will removed in ALE 2.0.'''
|
|
||||||
let s:deprecation_warning_echoed = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Specify file encoding in options
|
" Specify file encoding in options
|
||||||
" (Idea taken from https://github.com/scrooloose/syntastic/blob/master/syntax_checkers/html/tidy.vim)
|
" (Idea taken from https://github.com/scrooloose/syntastic/blob/master/syntax_checkers/html/tidy.vim)
|
||||||
let l:file_encoding = get({
|
let l:file_encoding = get({
|
||||||
|
|||||||
26
ale_linters/javascript/tsserver.vim
Normal file
26
ale_linters/javascript/tsserver.vim
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
" 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': '',
|
||||||
|
\})
|
||||||
@@ -4,14 +4,15 @@ function! ale_linters#puppet#puppet#Handle(buffer, lines) abort
|
|||||||
" Matches patterns like the following:
|
" 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 ':' 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 '='; 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: .*: \(.\+\) at .\+\.pp:\(\d\+\):\=\(\d*\)'
|
let l:pattern = '^Error: .*: \(.\+\) \((file:\|at\) .\+\.pp\(, line: \|:\)\(\d\+\)\(, column: \|:\)\=\(\d*\)'
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
|
||||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||||
call add(l:output, {
|
call add(l:output, {
|
||||||
\ 'lnum': l:match[2] + 0,
|
\ 'lnum': l:match[4] + 0,
|
||||||
\ 'col': l:match[3] + 0,
|
\ 'col': l:match[6] + 0,
|
||||||
\ 'text': l:match[1],
|
\ 'text': l:match[1],
|
||||||
\})
|
\})
|
||||||
endfor
|
endfor
|
||||||
|
|||||||
@@ -1,10 +1,43 @@
|
|||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>,
|
||||||
|
" Nicolas Pauss <https://github.com/nicopauss>
|
||||||
" Description: cython syntax checking for cython files.
|
" 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', {
|
call ale#linter#Define('pyrex', {
|
||||||
\ 'name': 'cython',
|
\ 'name': 'cython',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'cython',
|
\ 'executable_callback': 'ale_linters#pyrex#cython#GetExecutable',
|
||||||
\ 'command': 'cython --warning-extra -o ' . g:ale#util#nul_file . ' %t',
|
\ 'command_callback': 'ale_linters#pyrex#cython#GetCommand',
|
||||||
\ 'callback': 'ale#handlers#unix#HandleAsError',
|
\ 'callback': 'ale_linters#pyrex#cython#Handle',
|
||||||
\})
|
\})
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: flake8 for python files
|
" Description: flake8 for python files
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
" Support an old setting as a fallback.
|
|
||||||
let s:deprecation_warning_echoed = 0
|
|
||||||
let s:default_options = get(g:, 'ale_python_flake8_args', '')
|
|
||||||
|
|
||||||
call ale#Set('python_flake8_executable', 'flake8')
|
call ale#Set('python_flake8_executable', 'flake8')
|
||||||
call ale#Set('python_flake8_options', s:default_options)
|
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_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
call ale#Set('python_flake8_change_directory', 1)
|
call ale#Set('python_flake8_change_directory', 1)
|
||||||
|
|
||||||
@@ -40,18 +35,16 @@ function! ale_linters#python#flake8#VersionCheck(buffer) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
|
function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
|
||||||
" remove in 2.0
|
|
||||||
if exists('g:ale_python_flake8_args') && !s:deprecation_warning_echoed
|
|
||||||
execute 'echom ''Rename your g:ale_python_flake8_args setting to g:ale_python_flake8_options instead. Support for this will removed in ALE 2.0.'''
|
|
||||||
let s:deprecation_warning_echoed = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory')
|
let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory')
|
||||||
\ ? ale#path#BufferCdString(a:buffer)
|
\ ? ale#path#BufferCdString(a:buffer)
|
||||||
\ : ''
|
\ : ''
|
||||||
let l:executable = ale_linters#python#flake8#GetExecutable(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: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
|
" Only include the --stdin-display-name argument if we can parse the
|
||||||
" flake8 version, and it is recent enough to support it.
|
" flake8 version, and it is recent enough to support it.
|
||||||
let l:display_name_args = ale#semver#GTE(l:version, [3, 0, 0])
|
let l:display_name_args = ale#semver#GTE(l:version, [3, 0, 0])
|
||||||
@@ -61,7 +54,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
|
|||||||
let l:options = ale#Var(a:buffer, 'python_flake8_options')
|
let l:options = ale#Var(a:buffer, 'python_flake8_options')
|
||||||
|
|
||||||
return l:cd_string
|
return l:cd_string
|
||||||
\ . ale#Escape(l:executable)
|
\ . ale#Escape(l:executable) . l:exec_args
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' --format=default'
|
\ . ' --format=default'
|
||||||
\ . l:display_name_args . ' -'
|
\ . l:display_name_args . ' -'
|
||||||
|
|||||||
@@ -23,10 +23,14 @@ function! ale_linters#python#mypy#GetCommand(buffer) abort
|
|||||||
let l:dir = s:GetDir(a:buffer)
|
let l:dir = s:GetDir(a:buffer)
|
||||||
let l:executable = ale_linters#python#mypy#GetExecutable(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 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.
|
" we can know with certainty the base path for the 'filename' keys below.
|
||||||
return ale#path#CdString(l:dir)
|
return ale#path#CdString(l:dir)
|
||||||
\ . ale#Escape(l:executable)
|
\ . ale#Escape(l:executable) . l:exec_args
|
||||||
\ . ' --show-column-numbers '
|
\ . ' --show-column-numbers '
|
||||||
\ . ale#Var(a:buffer, 'python_mypy_options')
|
\ . ale#Var(a:buffer, 'python_mypy_options')
|
||||||
\ . ' --shadow-file %s %t %s'
|
\ . ' --shadow-file %s %t %s'
|
||||||
|
|||||||
@@ -14,7 +14,14 @@ function! ale_linters#python#prospector#GetExecutable(buffer) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#python#prospector#GetCommand(buffer) abort
|
function! ale_linters#python#prospector#GetCommand(buffer) abort
|
||||||
return ale#Escape(ale_linters#python#prospector#GetExecutable(a:buffer))
|
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
|
||||||
\ . ' ' . ale#Var(a:buffer, 'python_prospector_options')
|
\ . ' ' . ale#Var(a:buffer, 'python_prospector_options')
|
||||||
\ . ' --messages-only --absolute-paths --zero-exit --output-format json'
|
\ . ' --messages-only --absolute-paths --zero-exit --output-format json'
|
||||||
\ . ' %s'
|
\ . ' %s'
|
||||||
@@ -23,6 +30,10 @@ endfunction
|
|||||||
function! ale_linters#python#prospector#Handle(buffer, lines) abort
|
function! ale_linters#python#prospector#Handle(buffer, lines) abort
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
|
||||||
|
if empty(a:lines)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
let l:prospector_error = json_decode(join(a:lines, ''))
|
let l:prospector_error = json_decode(join(a:lines, ''))
|
||||||
|
|
||||||
for l:error in l:prospector_error.messages
|
for l:error in l:prospector_error.messages
|
||||||
|
|||||||
@@ -10,7 +10,13 @@ function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#python#pycodestyle#GetCommand(buffer) abort
|
function! ale_linters#python#pycodestyle#GetCommand(buffer) abort
|
||||||
return ale#Escape(ale_linters#python#pycodestyle#GetExecutable(a:buffer))
|
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
|
||||||
\ . ' '
|
\ . ' '
|
||||||
\ . ale#Var(a:buffer, 'python_pycodestyle_options')
|
\ . ale#Var(a:buffer, 'python_pycodestyle_options')
|
||||||
\ . ' -'
|
\ . ' -'
|
||||||
|
|||||||
@@ -11,7 +11,13 @@ endfunction
|
|||||||
function! ale_linters#python#pyflakes#GetCommand(buffer) abort
|
function! ale_linters#python#pyflakes#GetCommand(buffer) abort
|
||||||
let l:executable = ale_linters#python#pyflakes#GetExecutable(a:buffer)
|
let l:executable = ale_linters#python#pyflakes#GetExecutable(a:buffer)
|
||||||
|
|
||||||
return ale#Escape(l:executable) . ' %t'
|
let l:exec_args = l:executable =~? 'pipenv$'
|
||||||
|
\ ? ' run pyflakes'
|
||||||
|
\ : ''
|
||||||
|
|
||||||
|
return ale#Escape(l:executable)
|
||||||
|
\ . l:exec_args
|
||||||
|
\ . ' %t'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#python#pyflakes#Handle(buffer, lines) abort
|
function! ale_linters#python#pyflakes#Handle(buffer, lines) abort
|
||||||
|
|||||||
@@ -15,8 +15,14 @@ function! ale_linters#python#pylint#GetCommand(buffer) abort
|
|||||||
\ ? ale#path#BufferCdString(a:buffer)
|
\ ? 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
|
return l:cd_string
|
||||||
\ . ale#Escape(ale_linters#python#pylint#GetExecutable(a:buffer))
|
\ . ale#Escape(l:executable) . l:exec_args
|
||||||
\ . ' ' . ale#Var(a:buffer, 'python_pylint_options')
|
\ . ' ' . ale#Var(a:buffer, 'python_pylint_options')
|
||||||
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n'
|
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n'
|
||||||
\ . ' %s'
|
\ . ' %s'
|
||||||
|
|||||||
@@ -11,7 +11,11 @@ endfunction
|
|||||||
function! ale_linters#python#pyls#GetCommand(buffer) abort
|
function! ale_linters#python#pyls#GetCommand(buffer) abort
|
||||||
let l:executable = ale_linters#python#pyls#GetExecutable(a:buffer)
|
let l:executable = ale_linters#python#pyls#GetExecutable(a:buffer)
|
||||||
|
|
||||||
return ale#Escape(l:executable)
|
let l:exec_args = l:executable =~? 'pipenv$'
|
||||||
|
\ ? ' run pyls'
|
||||||
|
\ : ''
|
||||||
|
|
||||||
|
return ale#Escape(l:executable) . l:exec_args
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('python', {
|
call ale#linter#Define('python', {
|
||||||
|
|||||||
29
ale_linters/python/pyre.vim
Normal file
29
ale_linters/python/pyre.vim
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
" 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',
|
||||||
|
\})
|
||||||
@@ -22,7 +22,7 @@ function! ale_linters#r#lintr#GetCommand(buffer) abort
|
|||||||
\ . l:lint_cmd
|
\ . l:lint_cmd
|
||||||
|
|
||||||
return ale#path#BufferCdString(a:buffer)
|
return ale#path#BufferCdString(a:buffer)
|
||||||
\ . 'Rscript -e '
|
\ . 'Rscript --vanilla -e '
|
||||||
\ . ale#Escape(l:cmd_string) . ' %t'
|
\ . ale#Escape(l:cmd_string) . ' %t'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|||||||
@@ -4,21 +4,27 @@
|
|||||||
call ale#Set('ruby_reek_show_context', 0)
|
call ale#Set('ruby_reek_show_context', 0)
|
||||||
call ale#Set('ruby_reek_show_wiki_link', 0)
|
call ale#Set('ruby_reek_show_wiki_link', 0)
|
||||||
|
|
||||||
function! ale_linters#ruby#reek#Handle(buffer, lines) abort
|
function! ale_linters#ruby#reek#VersionCheck(buffer) abort
|
||||||
let l:output = []
|
" 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
|
||||||
|
|
||||||
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
return 'reek --version'
|
||||||
for l:location in l:error.lines
|
endfunction
|
||||||
call add(l:output, {
|
|
||||||
\ 'lnum': l:location,
|
|
||||||
\ 'type': 'W',
|
|
||||||
\ 'text': s:BuildText(a:buffer, l:error),
|
|
||||||
\ 'code': l:error.smell_type,
|
|
||||||
\})
|
|
||||||
endfor
|
|
||||||
endfor
|
|
||||||
|
|
||||||
return l:output
|
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
|
endfunction
|
||||||
|
|
||||||
function! s:BuildText(buffer, error) abort
|
function! s:BuildText(buffer, error) abort
|
||||||
@@ -37,9 +43,29 @@ function! s:BuildText(buffer, error) abort
|
|||||||
return join(l:parts, ' ')
|
return join(l:parts, ' ')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#ruby#reek#Handle(buffer, lines) abort
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
||||||
|
for l:location in l:error.lines
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'lnum': l:location,
|
||||||
|
\ 'type': 'W',
|
||||||
|
\ 'text': s:BuildText(a:buffer, l:error),
|
||||||
|
\ 'code': l:error.smell_type,
|
||||||
|
\})
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('ruby', {
|
call ale#linter#Define('ruby', {
|
||||||
\ 'name': 'reek',
|
\ 'name': 'reek',
|
||||||
\ 'executable': 'reek',
|
\ 'executable': 'reek',
|
||||||
\ 'command': 'reek -f json --no-progress --no-color',
|
\ 'command_chain': [
|
||||||
|
\ {'callback': 'ale_linters#ruby#reek#VersionCheck'},
|
||||||
|
\ {'callback': 'ale_linters#ruby#reek#GetCommand'},
|
||||||
|
\ ],
|
||||||
\ 'callback': 'ale_linters#ruby#reek#Handle',
|
\ 'callback': 'ale_linters#ruby#reek#Handle',
|
||||||
\})
|
\})
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
call ale#Set('rust_cargo_use_check', 1)
|
call ale#Set('rust_cargo_use_check', 1)
|
||||||
call ale#Set('rust_cargo_check_all_targets', 0)
|
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_default_feature_behavior', 'default')
|
||||||
call ale#Set('rust_cargo_include_features', '')
|
call ale#Set('rust_cargo_include_features', '')
|
||||||
|
|
||||||
@@ -31,12 +34,30 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
|
|||||||
let l:use_all_targets = l:use_check
|
let l:use_all_targets = l:use_check
|
||||||
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
|
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
|
||||||
\ && ale#semver#GTE(l:version, [0, 22, 0])
|
\ && 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')
|
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
|
||||||
if !empty(l:include_features)
|
if !empty(l:include_features)
|
||||||
let l:include_features = ' --features ' . ale#Escape(l:include_features)
|
let l:include_features = ' --features ' . ale#Escape(l:include_features)
|
||||||
endif
|
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')
|
let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior')
|
||||||
if l:default_feature_behavior is# 'all'
|
if l:default_feature_behavior is# 'all'
|
||||||
let l:include_features = ''
|
let l:include_features = ''
|
||||||
@@ -47,9 +68,11 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
|
|||||||
let l:default_feature = ''
|
let l:default_feature = ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return 'cargo '
|
return l:nearest_cargo_prefix . 'cargo '
|
||||||
\ . (l:use_check ? 'check' : 'build')
|
\ . (l:use_check ? 'check' : 'build')
|
||||||
\ . (l:use_all_targets ? ' --all-targets' : '')
|
\ . (l:use_all_targets ? ' --all-targets' : '')
|
||||||
|
\ . (l:use_examples ? ' --examples' : '')
|
||||||
|
\ . (l:use_tests ? ' --tests' : '')
|
||||||
\ . ' --frozen --message-format=json -q'
|
\ . ' --frozen --message-format=json -q'
|
||||||
\ . l:default_feature
|
\ . l:default_feature
|
||||||
\ . l:include_features
|
\ . l:include_features
|
||||||
|
|||||||
33
ale_linters/sh/language_server.vim
Normal file
33
ale_linters/sh/language_server.vim
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
" 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',
|
||||||
|
\})
|
||||||
@@ -20,7 +20,7 @@ function! ale_linters#thrift#thrift#GetCommand(buffer) abort
|
|||||||
let l:generators = ['cpp']
|
let l:generators = ['cpp']
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:output_dir = tempname()
|
let l:output_dir = ale#util#Tempname()
|
||||||
call mkdir(l:output_dir)
|
call mkdir(l:output_dir)
|
||||||
call ale#engine#ManageDirectory(a:buffer, l:output_dir)
|
call ale#engine#ManageDirectory(a:buffer, l:output_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ if !exists('g:ale_verilog_verilator_options')
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
function! ale_linters#verilog#verilator#GetCommand(buffer) abort
|
function! ale_linters#verilog#verilator#GetCommand(buffer) abort
|
||||||
let l:filename = tempname() . '_verilator_linted.v'
|
let l:filename = ale#util#Tempname() . '_verilator_linted.v'
|
||||||
|
|
||||||
" Create a special filename, so we can detect it in the handler.
|
" Create a special filename, so we can detect it in the handler.
|
||||||
call ale#engine#ManageFile(a:buffer, l:filename)
|
call ale#engine#ManageFile(a:buffer, l:filename)
|
||||||
|
|||||||
@@ -20,21 +20,31 @@ function! ale_linters#yaml#yamllint#Handle(buffer, lines) abort
|
|||||||
" Matches patterns line the following:
|
" Matches patterns line the following:
|
||||||
" something.yaml:1:1: [warning] missing document start "---" (document-start)
|
" 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>'
|
" something.yml:2:1: [error] syntax error: expected the node content, but found '<stream end>'
|
||||||
let l:pattern = '^.*:\(\d\+\):\(\d\+\): \[\(error\|warning\)\] \(.\+\)$'
|
let l:pattern = '\v^.*:(\d+):(\d+): \[(error|warning)\] (.+)$'
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
|
||||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||||
let l:line = l:match[1] + 0
|
let l:item = {
|
||||||
let l:col = l:match[2] + 0
|
\ 'lnum': l:match[1] + 0,
|
||||||
let l:type = l:match[3]
|
\ 'col': l:match[2] + 0,
|
||||||
let l:text = l:match[4]
|
\ 'text': l:match[4],
|
||||||
|
\ 'type': l:match[3] is# 'error' ? 'E' : 'W',
|
||||||
|
\}
|
||||||
|
|
||||||
call add(l:output, {
|
let l:code_match = matchlist(l:item.text, '\v^(.+) \(([^)]+)\)$')
|
||||||
\ 'lnum': l:line,
|
|
||||||
\ 'col': l:col,
|
if !empty(l:code_match)
|
||||||
\ 'text': l:text,
|
if l:code_match[2] is# 'trailing-spaces'
|
||||||
\ 'type': l:type is# 'error' ? 'E' : 'W',
|
\&& !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)
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
return l:output
|
return l:output
|
||||||
|
|||||||
@@ -6,35 +6,12 @@
|
|||||||
let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
|
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_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')
|
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:lint_timer = -1
|
||||||
let s:queued_buffer_number = -1
|
let s:queued_buffer_number = -1
|
||||||
let s:should_lint_file_for_buffer = {}
|
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.
|
" Return 1 if a file is too large for ALE to handle.
|
||||||
function! ale#FileTooLarge(buffer) abort
|
function! ale#FileTooLarge(buffer) abort
|
||||||
@@ -114,30 +91,22 @@ function! ale#Queue(delay, ...) abort
|
|||||||
let l:linting_flag = get(a:000, 0, '')
|
let l:linting_flag = get(a:000, 0, '')
|
||||||
let l:buffer = get(a:000, 1, bufnr(''))
|
let l:buffer = get(a:000, 1, bufnr(''))
|
||||||
|
|
||||||
return ale#CallWithCooldown(
|
if l:linting_flag isnot# '' && l:linting_flag isnot# 'lint_file'
|
||||||
\ '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'"
|
throw "linting_flag must be either '' or 'lint_file'"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if type(a:buffer) != type(0)
|
if type(l:buffer) != type(0)
|
||||||
throw 'buffer_number must be a Number'
|
throw 'buffer_number must be a Number'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ale#ShouldDoNothing(a:buffer)
|
if ale#ShouldDoNothing(l:buffer)
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Remember that we want to check files for this buffer.
|
" Remember that we want to check files for this buffer.
|
||||||
" We will remember this until we finally run the linters, via any event.
|
" We will remember this until we finally run the linters, via any event.
|
||||||
if a:linting_flag is# 'lint_file'
|
if l:linting_flag is# 'lint_file'
|
||||||
let s:should_lint_file_for_buffer[a:buffer] = 1
|
let s:should_lint_file_for_buffer[l:buffer] = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if s:lint_timer != -1
|
if s:lint_timer != -1
|
||||||
@@ -145,24 +114,24 @@ function! s:ALEQueueImpl(delay, linting_flag, buffer) abort
|
|||||||
let s:lint_timer = -1
|
let s:lint_timer = -1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
let l:linters = ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||||
|
|
||||||
" Don't set up buffer data and so on if there are no linters to run.
|
" Don't set up buffer data and so on if there are no linters to run.
|
||||||
if empty(l:linters)
|
if empty(l:linters)
|
||||||
" If we have some previous buffer data, then stop any jobs currently
|
" If we have some previous buffer data, then stop any jobs currently
|
||||||
" running and clear everything.
|
" running and clear everything.
|
||||||
if has_key(g:ale_buffer_info, a:buffer)
|
if has_key(g:ale_buffer_info, l:buffer)
|
||||||
call ale#engine#RunLinters(a:buffer, [], 1)
|
call ale#engine#RunLinters(l:buffer, [], 1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if a:delay > 0
|
if a:delay > 0
|
||||||
let s:queued_buffer_number = a:buffer
|
let s:queued_buffer_number = l:buffer
|
||||||
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
|
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
|
||||||
else
|
else
|
||||||
call ale#Lint(-1, a:buffer)
|
call ale#Lint(-1, l:buffer)
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -178,30 +147,29 @@ function! ale#Lint(...) abort
|
|||||||
let l:buffer = bufnr('')
|
let l:buffer = bufnr('')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ale#CallWithCooldown(
|
if ale#ShouldDoNothing(l:buffer)
|
||||||
\ 'dont_lint_until',
|
|
||||||
\ function('s:ALELintImpl'),
|
|
||||||
\ [l:buffer],
|
|
||||||
\)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ALELintImpl(buffer) abort
|
|
||||||
if ale#ShouldDoNothing(a:buffer)
|
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Use the filetype from the buffer
|
" Use the filetype from the buffer
|
||||||
let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
let l:filetype = getbufvar(l:buffer, '&filetype')
|
||||||
|
let l:linters = ale#linter#Get(l:filetype)
|
||||||
let l:should_lint_file = 0
|
let l:should_lint_file = 0
|
||||||
|
|
||||||
" Check if we previously requested checking the file.
|
" Check if we previously requested checking the file.
|
||||||
if has_key(s:should_lint_file_for_buffer, a:buffer)
|
if has_key(s:should_lint_file_for_buffer, l:buffer)
|
||||||
unlet s:should_lint_file_for_buffer[a:buffer]
|
unlet s:should_lint_file_for_buffer[l:buffer]
|
||||||
" Lint files if they exist.
|
" Lint files if they exist.
|
||||||
let l:should_lint_file = filereadable(expand('#' . a:buffer . ':p'))
|
let l:should_lint_file = filereadable(expand('#' . l:buffer . ':p'))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#engine#RunLinters(a:buffer, l:linters, l:should_lint_file)
|
" 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)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Reset flags indicating that files should be checked for all buffers.
|
" Reset flags indicating that files should be checked for all buffers.
|
||||||
@@ -209,10 +177,6 @@ function! ale#ResetLintFileMarkers() abort
|
|||||||
let s:should_lint_file_for_buffer = {}
|
let s:should_lint_file_for_buffer = {}
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#ResetErrorDelays() abort
|
|
||||||
let s:timestamp_map = {}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let g:ale_has_override = get(g:, 'ale_has_override', {})
|
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
|
" Call has(), but check a global Dictionary so we can force flags on or off
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
function! ale#autocmd#InitAuGroups() 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 ALEPatternOptionsGroup
|
|
||||||
autocmd!
|
|
||||||
autocmd BufEnter,BufRead * call ale#pattern_options#SetOptions(str2nr(expand('<abuf>')))
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnTextChangedGroup
|
|
||||||
autocmd!
|
|
||||||
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
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnEnterGroup
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled
|
|
||||||
" Handle everything that needs to happen when buffers are entered.
|
|
||||||
autocmd BufEnter * call ale#events#EnterEvent(str2nr(expand('<abuf>')))
|
|
||||||
endif
|
|
||||||
if g:ale_enabled && 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
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnFiletypeChangeGroup
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled && 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
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnSaveGroup
|
|
||||||
autocmd!
|
|
||||||
autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnInsertLeave
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled && g:ale_lint_on_insert_leave
|
|
||||||
autocmd InsertLeave * call ale#Queue(0)
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALECursorGroup
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled && g:ale_echo_cursor
|
|
||||||
autocmd CursorMoved,CursorHold * call ale#cursor#EchoCursorWarningWithDelay()
|
|
||||||
" 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 * call ale#cursor#EchoCursorWarning()
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
if !g:ale_enabled
|
|
||||||
augroup! ALERunOnTextChangedGroup
|
|
||||||
augroup! ALERunOnEnterGroup
|
|
||||||
augroup! ALERunOnInsertLeave
|
|
||||||
augroup! ALECursorGroup
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
@@ -34,7 +34,11 @@ function! ale#balloon#Expr() abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#balloon#Disable() abort
|
function! ale#balloon#Disable() abort
|
||||||
set noballooneval noballoonevalterm
|
if has('balloon_eval_term')
|
||||||
|
set noballoonevalterm
|
||||||
|
endif
|
||||||
|
|
||||||
|
set noballooneval
|
||||||
set balloonexpr=
|
set balloonexpr=
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ function! s:TemporaryFilename(buffer) abort
|
|||||||
|
|
||||||
" Create a temporary filename, <temp_dir>/<original_basename>
|
" Create a temporary filename, <temp_dir>/<original_basename>
|
||||||
" The file itself will not be created by this function.
|
" The file itself will not be created by this function.
|
||||||
return tempname() . (has('win32') ? '\' : '/') . l:filename
|
return ale#util#Tempname() . (has('win32') ? '\' : '/') . l:filename
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Given a command string, replace every...
|
" Given a command string, replace every...
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||||||
\ 'word': l:word,
|
\ 'word': l:word,
|
||||||
\ 'kind': l:kind,
|
\ 'kind': l:kind,
|
||||||
\ 'icase': 1,
|
\ 'icase': 1,
|
||||||
\ 'menu': l:item.detail,
|
\ 'menu': get(l:item, 'detail', ''),
|
||||||
\ 'info': get(l:item, 'documentation', ''),
|
\ 'info': get(l:item, 'documentation', ''),
|
||||||
\})
|
\})
|
||||||
endfor
|
endfor
|
||||||
@@ -389,14 +389,13 @@ function! s:GetLSPCompletions(linter) abort
|
|||||||
\ ? function('ale#completion#HandleTSServerResponse')
|
\ ? function('ale#completion#HandleTSServerResponse')
|
||||||
\ : function('ale#completion#HandleLSPResponse')
|
\ : function('ale#completion#HandleLSPResponse')
|
||||||
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
|
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
if empty(l:lsp_details)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
let l:id = l:lsp_details.connection_id
|
||||||
let l:root = l:lsp_details.project_root
|
|
||||||
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
if a:linter.lsp is# 'tsserver'
|
||||||
let l:message = ale#lsp#tsserver_message#Completions(
|
let l:message = ale#lsp#tsserver_message#Completions(
|
||||||
@@ -408,7 +407,7 @@ function! s:GetLSPCompletions(linter) abort
|
|||||||
else
|
else
|
||||||
" Send a message saying the buffer has changed first, otherwise
|
" Send a message saying the buffer has changed first, otherwise
|
||||||
" completions won't know what text is nearby.
|
" completions won't know what text is nearby.
|
||||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
|
call ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
|
||||||
" For LSP completions, we need to clamp the column to the length of
|
" For LSP completions, we need to clamp the column to the length of
|
||||||
" the line. python-language-server and perhaps others do not implement
|
" the line. python-language-server and perhaps others do not implement
|
||||||
@@ -424,7 +423,7 @@ function! s:GetLSPCompletions(linter) abort
|
|||||||
\)
|
\)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
|
||||||
|
|
||||||
if l:request_id
|
if l:request_id
|
||||||
let b:ale_completion_info.conn_id = l:id
|
let b:ale_completion_info.conn_id = l:id
|
||||||
|
|||||||
@@ -56,10 +56,6 @@ function! s:StopCursorTimer() abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#cursor#EchoCursorWarning(...) abort
|
function! ale#cursor#EchoCursorWarning(...) abort
|
||||||
return ale#CallWithCooldown('dont_echo_until', function('s:EchoImpl'), [])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:EchoImpl() abort
|
|
||||||
if !g:ale_echo_cursor
|
if !g:ale_echo_cursor
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -214,10 +214,15 @@ function! ale#debugging#Info() abort
|
|||||||
" This must be done after linters are loaded.
|
" This must be done after linters are loaded.
|
||||||
let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names)
|
let l:variable_list = s:GetLinterVariables(l:filetype, l: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(' Current Filetype: ' . l:filetype)
|
||||||
call s:Echo('Available Linters: ' . string(l:all_names))
|
call s:Echo('Available Linters: ' . string(l:all_names))
|
||||||
call s:EchoLinterAliases(l:all_linters)
|
call s:EchoLinterAliases(l:all_linters)
|
||||||
call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
|
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(' Linter Variables:')
|
||||||
call s:Echo('')
|
call s:Echo('')
|
||||||
call s:EchoLinterVariables(l:variable_list)
|
call s:EchoLinterVariables(l:variable_list)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function! ale#definition#HandleTSServerResponse(conn_id, response) abort
|
|||||||
\&& has_key(s:go_to_definition_map, a:response.request_seq)
|
\&& has_key(s:go_to_definition_map, a:response.request_seq)
|
||||||
let l:options = remove(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
|
if get(a:response, 'success', v:false) is v:true && !empty(a:response.body)
|
||||||
let l:filename = a:response.body[0].file
|
let l:filename = a:response.body[0].file
|
||||||
let l:line = a:response.body[0].start.line
|
let l:line = a:response.body[0].start.line
|
||||||
let l:column = a:response.body[0].start.offset
|
let l:column = a:response.body[0].start.offset
|
||||||
@@ -65,14 +65,13 @@ function! s:GoToLSPDefinition(linter, options) abort
|
|||||||
\ ? function('ale#definition#HandleTSServerResponse')
|
\ ? function('ale#definition#HandleTSServerResponse')
|
||||||
\ : function('ale#definition#HandleLSPResponse')
|
\ : function('ale#definition#HandleLSPResponse')
|
||||||
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
|
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
if empty(l:lsp_details)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
let l:id = l:lsp_details.connection_id
|
||||||
let l:root = l:lsp_details.project_root
|
|
||||||
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
if a:linter.lsp is# 'tsserver'
|
||||||
let l:message = ale#lsp#tsserver_message#Definition(
|
let l:message = ale#lsp#tsserver_message#Definition(
|
||||||
@@ -83,7 +82,7 @@ function! s:GoToLSPDefinition(linter, options) abort
|
|||||||
else
|
else
|
||||||
" Send a message saying the buffer has changed first, or the
|
" Send a message saying the buffer has changed first, or the
|
||||||
" definition position probably won't make sense.
|
" definition position probably won't make sense.
|
||||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
|
call ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
|
||||||
let l:column = min([l:column, len(getline(l:line))])
|
let l:column = min([l:column, len(getline(l:line))])
|
||||||
|
|
||||||
@@ -93,7 +92,7 @@ function! s:GoToLSPDefinition(linter, options) abort
|
|||||||
let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column)
|
let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
|
||||||
|
|
||||||
let s:go_to_definition_map[l:request_id] = {
|
let s:go_to_definition_map[l:request_id] = {
|
||||||
\ 'open_in_tab': get(a:options, 'open_in_tab', 0),
|
\ 'open_in_tab': get(a:options, 'open_in_tab', 0),
|
||||||
|
|||||||
@@ -14,11 +14,6 @@ if !has_key(s:, 'job_info_map')
|
|||||||
let s:job_info_map = {}
|
let s:job_info_map = {}
|
||||||
endif
|
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')
|
if !has_key(s:, 'executable_cache_map')
|
||||||
let s:executable_cache_map = {}
|
let s:executable_cache_map = {}
|
||||||
endif
|
endif
|
||||||
@@ -79,16 +74,6 @@ function! ale#engine#InitBufferInfo(buffer) abort
|
|||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Clear LSP linter data for the linting engine.
|
|
||||||
function! ale#engine#ClearLSPData() abort
|
|
||||||
let s:lsp_linter_map = {}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Just for tests.
|
|
||||||
function! ale#engine#SetLSPLinterMap(replacement_map) abort
|
|
||||||
let s:lsp_linter_map = a:replacement_map
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" This function is documented and part of the public API.
|
" This function is documented and part of the public API.
|
||||||
"
|
"
|
||||||
" Return 1 if ALE is busy checking a given buffer
|
" Return 1 if ALE is busy checking a given buffer
|
||||||
@@ -113,7 +98,7 @@ endfunction
|
|||||||
|
|
||||||
" Create a new temporary directory and manage it in one go.
|
" Create a new temporary directory and manage it in one go.
|
||||||
function! ale#engine#CreateDirectory(buffer) abort
|
function! ale#engine#CreateDirectory(buffer) abort
|
||||||
let l:temporary_directory = tempname()
|
let l:temporary_directory = ale#util#Tempname()
|
||||||
" Create the temporary directory for the file, unreadable by 'other'
|
" Create the temporary directory for the file, unreadable by 'other'
|
||||||
" users.
|
" users.
|
||||||
call mkdir(l:temporary_directory, '', 0750)
|
call mkdir(l:temporary_directory, '', 0750)
|
||||||
@@ -236,93 +221,16 @@ function! s:HandleExit(job_id, exit_code) abort
|
|||||||
call ale#history#RememberOutput(l:buffer, a:job_id, l:output[:])
|
call ale#history#RememberOutput(l:buffer, a:job_id, l:output[:])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
let l:loclist = ale#util#GetFunction(l:linter.callback)(l:buffer, l:output)
|
let l:loclist = ale#util#GetFunction(l:linter.callback)(l:buffer, l:output)
|
||||||
|
" Handle the function being unknown, or being deleted.
|
||||||
|
catch /E700/
|
||||||
|
let l:loclist = []
|
||||||
|
endtry
|
||||||
|
|
||||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
||||||
endfunction
|
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(linter_name, response) abort
|
|
||||||
if !g:ale_history_enabled || !g:ale_history_log_output
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if empty(a:linter_name)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:message = ale#lsp#response#GetErrorMessage(a:response)
|
|
||||||
|
|
||||||
if empty(l:message)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
" This global variable is set here so we don't load the debugging.vim file
|
|
||||||
" until someone uses :ALEInfo.
|
|
||||||
let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
|
|
||||||
|
|
||||||
if !has_key(g:ale_lsp_error_messages, a:linter_name)
|
|
||||||
let g:ale_lsp_error_messages[a:linter_name] = []
|
|
||||||
endif
|
|
||||||
|
|
||||||
call add(g:ale_lsp_error_messages[a:linter_name], l:message)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale#engine#HandleLSPResponse(conn_id, response) abort
|
|
||||||
let l:method = get(a:response, 'method', '')
|
|
||||||
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
|
|
||||||
|
|
||||||
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
|
|
||||||
call s:HandleLSPErrorMessage(l:linter_name, a:response)
|
|
||||||
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
|
function! ale#engine#SetResults(buffer, loclist) abort
|
||||||
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
|
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||||
|
|
||||||
@@ -367,9 +275,6 @@ function! ale#engine#SetResults(buffer, loclist) abort
|
|||||||
|
|
||||||
" Call user autocommands. This allows users to hook into ALE's lint cycle.
|
" Call user autocommands. This allows users to hook into ALE's lint cycle.
|
||||||
silent doautocmd <nomodeline> User ALELintPost
|
silent doautocmd <nomodeline> User ALELintPost
|
||||||
" remove in 2.0
|
|
||||||
" Old DEPRECATED name; call it for backwards compatibility.
|
|
||||||
silent doautocmd <nomodeline> User ALELint
|
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -739,44 +644,6 @@ function! s:StopCurrentJobs(buffer, include_lint_file_jobs) abort
|
|||||||
let l:info.active_linter_list = l:new_active_linter_list
|
let l:info.active_linter_list = l:new_active_linter_list
|
||||||
endfunction
|
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
|
function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
||||||
" Figure out which linters are still enabled, and remove
|
" Figure out which linters are still enabled, and remove
|
||||||
@@ -832,7 +699,7 @@ endfunction
|
|||||||
" Returns 1 if the linter was successfully run.
|
" Returns 1 if the linter was successfully run.
|
||||||
function! s:RunLinter(buffer, linter) abort
|
function! s:RunLinter(buffer, linter) abort
|
||||||
if !empty(a:linter.lsp)
|
if !empty(a:linter.lsp)
|
||||||
return s:CheckWithLSP(a:buffer, a:linter)
|
return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter)
|
||||||
else
|
else
|
||||||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||||
|
|
||||||
@@ -914,7 +781,7 @@ endfunction
|
|||||||
" The time taken will be a very rough approximation, and more time may be
|
" The time taken will be a very rough approximation, and more time may be
|
||||||
" permitted than is specified.
|
" permitted than is specified.
|
||||||
function! ale#engine#WaitForJobs(deadline) abort
|
function! ale#engine#WaitForJobs(deadline) abort
|
||||||
let l:start_time = ale#util#ClockMilliseconds()
|
let l:start_time = ale#events#ClockMilliseconds()
|
||||||
|
|
||||||
if l:start_time == 0
|
if l:start_time == 0
|
||||||
throw 'Failed to read milliseconds from the clock!'
|
throw 'Failed to read milliseconds from the clock!'
|
||||||
@@ -945,7 +812,7 @@ function! ale#engine#WaitForJobs(deadline) abort
|
|||||||
|
|
||||||
for l:job_id in l:job_list
|
for l:job_id in l:job_list
|
||||||
if ale#job#IsRunning(l:job_id)
|
if ale#job#IsRunning(l:job_id)
|
||||||
let l:now = ale#util#ClockMilliseconds()
|
let l:now = ale#events#ClockMilliseconds()
|
||||||
|
|
||||||
if l:now - l:start_time > a:deadline
|
if l:now - l:start_time > a:deadline
|
||||||
" Stop waiting after a timeout, so we don't wait forever.
|
" Stop waiting after a timeout, so we don't wait forever.
|
||||||
@@ -982,7 +849,7 @@ function! ale#engine#WaitForJobs(deadline) abort
|
|||||||
|
|
||||||
if l:has_new_jobs
|
if l:has_new_jobs
|
||||||
" We have to wait more. Offset the timeout by the time taken so far.
|
" We have to wait more. Offset the timeout by the time taken so far.
|
||||||
let l:now = ale#util#ClockMilliseconds()
|
let l:now = ale#events#ClockMilliseconds()
|
||||||
let l:new_deadline = a:deadline - (l:now - l:start_time)
|
let l:new_deadline = a:deadline - (l:now - l:start_time)
|
||||||
|
|
||||||
if l:new_deadline <= 0
|
if l:new_deadline <= 0
|
||||||
|
|||||||
46
autoload/ale/engine/ignore.vim
Normal file
46
autoload/ale/engine/ignore.vim
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
" 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
|
||||||
@@ -1,14 +1,25 @@
|
|||||||
" Author: w0rp <devw0rp@gmail.com>
|
" 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
|
function! ale#events#QuitEvent(buffer) abort
|
||||||
" Remember when ALE is quitting for BufWrite, etc.
|
" Remember when ALE is quitting for BufWrite, etc.
|
||||||
call setbufvar(a:buffer, 'ale_quitting', ale#util#ClockMilliseconds())
|
call setbufvar(a:buffer, 'ale_quitting', ale#events#ClockMilliseconds())
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#events#QuitRecently(buffer) abort
|
function! ale#events#QuitRecently(buffer) abort
|
||||||
let l:time = getbufvar(a:buffer, 'ale_quitting', 0)
|
let l:time = getbufvar(a:buffer, 'ale_quitting', 0)
|
||||||
|
|
||||||
return l:time && ale#util#ClockMilliseconds() - l:time < 1000
|
return l:time && ale#events#ClockMilliseconds() - l:time < 1000
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#events#SaveEvent(buffer) abort
|
function! ale#events#SaveEvent(buffer) abort
|
||||||
@@ -67,3 +78,56 @@ function! ale#events#FileChangedEvent(buffer) abort
|
|||||||
call s:LintOnEnter(a:buffer)
|
call s:LintOnEnter(a:buffer)
|
||||||
endif
|
endif
|
||||||
endfunction
|
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
|
||||||
|
|||||||
@@ -356,9 +356,21 @@ function! s:RunFixer(options) abort
|
|||||||
call ale#fix#ApplyFixes(l:buffer, l:input)
|
call ale#fix#ApplyFixes(l:buffer, l:input)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GetCallbacks(buffer, linters) abort
|
function! s:AddSubCallbacks(full_list, callbacks) abort
|
||||||
if len(a:linters)
|
if type(a:callbacks) == type('')
|
||||||
let l:callback_list = a:linters
|
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([])
|
elseif type(get(b:, 'ale_fixers')) is type([])
|
||||||
" Lists can be used for buffer-local variables only
|
" Lists can be used for buffer-local variables only
|
||||||
let l:callback_list = b:ale_fixers
|
let l:callback_list = b:ale_fixers
|
||||||
@@ -367,16 +379,18 @@ function! s:GetCallbacks(buffer, linters) abort
|
|||||||
" callbacks to run.
|
" callbacks to run.
|
||||||
let l:fixers = ale#Var(a:buffer, 'fixers')
|
let l:fixers = ale#Var(a:buffer, 'fixers')
|
||||||
let l:callback_list = []
|
let l:callback_list = []
|
||||||
|
let l:matched = 0
|
||||||
|
|
||||||
for l:sub_type in split(&filetype, '\.')
|
for l:sub_type in split(&filetype, '\.')
|
||||||
let l:sub_type_callacks = get(l:fixers, l:sub_type, [])
|
if s:AddSubCallbacks(l:callback_list, get(l:fixers, l:sub_type))
|
||||||
|
let l:matched = 1
|
||||||
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
|
endif
|
||||||
endfor
|
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
|
endif
|
||||||
|
|
||||||
if empty(l:callback_list)
|
if empty(l:callback_list)
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ let s:default_registry = {
|
|||||||
\ 'suggested_filetypes': ['python'],
|
\ 'suggested_filetypes': ['python'],
|
||||||
\ 'description': 'Fix PEP8 issues with black.',
|
\ 'description': 'Fix PEP8 issues with black.',
|
||||||
\ },
|
\ },
|
||||||
|
\ 'tidy': {
|
||||||
|
\ 'function': 'ale#fixers#tidy#Fix',
|
||||||
|
\ 'suggested_filetypes': ['html'],
|
||||||
|
\ 'description': 'Fix HTML files with tidy.',
|
||||||
|
\ },
|
||||||
\ 'prettier_standard': {
|
\ 'prettier_standard': {
|
||||||
\ 'function': 'ale#fixers#prettier_standard#Fix',
|
\ 'function': 'ale#fixers#prettier_standard#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript'],
|
\ 'suggested_filetypes': ['javascript'],
|
||||||
@@ -51,7 +56,7 @@ let s:default_registry = {
|
|||||||
\ },
|
\ },
|
||||||
\ 'prettier': {
|
\ 'prettier': {
|
||||||
\ 'function': 'ale#fixers#prettier#Fix',
|
\ 'function': 'ale#fixers#prettier#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript', 'typescript', 'json', 'css', 'scss', 'less', 'markdown', 'graphql', 'vue'],
|
\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue'],
|
||||||
\ 'description': 'Apply prettier to a file.',
|
\ 'description': 'Apply prettier to a file.',
|
||||||
\ },
|
\ },
|
||||||
\ 'prettier_eslint': {
|
\ 'prettier_eslint': {
|
||||||
@@ -95,6 +100,11 @@ let s:default_registry = {
|
|||||||
\ 'suggested_filetypes': ['ruby'],
|
\ 'suggested_filetypes': ['ruby'],
|
||||||
\ 'description': 'Fix ruby files with rufo',
|
\ 'description': 'Fix ruby files with rufo',
|
||||||
\ },
|
\ },
|
||||||
|
\ 'scalafmt': {
|
||||||
|
\ 'function': 'ale#fixers#scalafmt#Fix',
|
||||||
|
\ 'suggested_filetypes': ['scala'],
|
||||||
|
\ 'description': 'Fix Scala files using scalafmt',
|
||||||
|
\ },
|
||||||
\ 'standard': {
|
\ 'standard': {
|
||||||
\ 'function': 'ale#fixers#standard#Fix',
|
\ 'function': 'ale#fixers#standard#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript'],
|
\ 'suggested_filetypes': ['javascript'],
|
||||||
@@ -195,6 +205,16 @@ let s:default_registry = {
|
|||||||
\ 'suggested_filetypes': ['javascript'],
|
\ 'suggested_filetypes': ['javascript'],
|
||||||
\ 'description': 'Fix JavaScript files using xo --fix.',
|
\ '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.
|
" Reset the function registry to the default entries.
|
||||||
@@ -335,8 +355,7 @@ function! ale#fix#registry#CompleteFixers(ArgLead, CmdLine, CursorPos) abort
|
|||||||
return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead')
|
return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Suggest functions to use from the registry.
|
function! ale#fix#registry#SuggestedFixers(filetype) abort
|
||||||
function! ale#fix#registry#Suggest(filetype) abort
|
|
||||||
let l:type_list = split(a:filetype, '\.')
|
let l:type_list = split(a:filetype, '\.')
|
||||||
let l:filetype_fixer_list = []
|
let l:filetype_fixer_list = []
|
||||||
|
|
||||||
@@ -362,6 +381,15 @@ function! ale#fix#registry#Suggest(filetype) abort
|
|||||||
endif
|
endif
|
||||||
endfor
|
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)
|
let l:filetype_fixer_header = !empty(l:filetype_fixer_list)
|
||||||
\ ? ['Try the following fixers appropriate for the filetype:', '']
|
\ ? ['Try the following fixers appropriate for the filetype:', '']
|
||||||
\ : []
|
\ : []
|
||||||
|
|||||||
18
autoload/ale/fixers/dartfmt.vim
Normal file
18
autoload/ale/fixers/dartfmt.vim
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
" 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
|
||||||
@@ -30,8 +30,26 @@ endfunction
|
|||||||
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
|
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
|
||||||
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
|
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
|
||||||
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
||||||
|
|
||||||
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
|
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
|
||||||
|
let l:parser = ''
|
||||||
|
|
||||||
|
" Append the --parser flag depending on the current filetype (unless it's
|
||||||
|
" already set in g:javascript_prettier_options).
|
||||||
|
if empty(expand('#' . a:buffer . ':e')) && match(l:options, '--parser') == -1
|
||||||
|
let l:prettier_parsers = ['typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue']
|
||||||
|
let l:parser = 'babylon'
|
||||||
|
|
||||||
|
for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.')
|
||||||
|
if index(l:prettier_parsers, l:filetype) > -1
|
||||||
|
let l:parser = l:filetype
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !empty(l:parser)
|
||||||
|
let l:options = (!empty(l:options) ? l:options . ' ' : '') . '--parser ' . l:parser
|
||||||
|
endif
|
||||||
|
|
||||||
" 1.4.0 is the first version with --stdin-filepath
|
" 1.4.0 is the first version with --stdin-filepath
|
||||||
if ale#semver#GTE(l:version, [1, 4, 0])
|
if ale#semver#GTE(l:version, [1, 4, 0])
|
||||||
|
|||||||
11
autoload/ale/fixers/qmlfmt.vim
Normal file
11
autoload/ale/fixers/qmlfmt.vim
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
call ale#Set('qml_qmlfmt_executable', 'qmlfmt')
|
||||||
|
|
||||||
|
function! ale#fixers#qmlfmt#GetExecutable(buffer) abort
|
||||||
|
return ale#Var(a:buffer, 'qml_qmlfmt_executable')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#fixers#qmlfmt#Fix(buffer) abort
|
||||||
|
return {
|
||||||
|
\ 'command': ale#Escape(ale#fixers#qmlfmt#GetExecutable(a:buffer)),
|
||||||
|
\}
|
||||||
|
endfunction
|
||||||
26
autoload/ale/fixers/scalafmt.vim
Normal file
26
autoload/ale/fixers/scalafmt.vim
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
" Author: Jeffrey Lau https://github.com/zoonfafer
|
||||||
|
" Description: Integration of Scalafmt with ALE.
|
||||||
|
|
||||||
|
call ale#Set('scala_scalafmt_executable', 'scalafmt')
|
||||||
|
call ale#Set('scala_scalafmt_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
call ale#Set('scala_scalafmt_options', '')
|
||||||
|
|
||||||
|
function! ale#fixers#scalafmt#GetCommand(buffer) abort
|
||||||
|
let l:executable = ale#Var(a:buffer, 'scala_scalafmt_executable')
|
||||||
|
let l:options = ale#Var(a:buffer, 'scala_scalafmt_options')
|
||||||
|
let l:exec_args = l:executable =~? 'ng$'
|
||||||
|
\ ? ' scalafmt'
|
||||||
|
\ : ''
|
||||||
|
|
||||||
|
return ale#Escape(l:executable) . l:exec_args
|
||||||
|
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||||
|
\ . ' %t'
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#fixers#scalafmt#Fix(buffer) abort
|
||||||
|
return {
|
||||||
|
\ 'command': ale#fixers#scalafmt#GetCommand(a:buffer),
|
||||||
|
\ 'read_temporary_file': 1,
|
||||||
|
\}
|
||||||
|
endfunction
|
||||||
26
autoload/ale/fixers/tidy.vim
Normal file
26
autoload/ale/fixers/tidy.vim
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
" Author: meain <abinsimon10@gmail.com>
|
||||||
|
" Description: Fixing HTML files with tidy.
|
||||||
|
|
||||||
|
call ale#Set('html_tidy_executable', 'tidy')
|
||||||
|
call ale#Set('html_tidy_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
|
||||||
|
function! ale#fixers#tidy#Fix(buffer) abort
|
||||||
|
let l:executable = ale#node#FindExecutable(
|
||||||
|
\ a:buffer,
|
||||||
|
\ 'html_tidy',
|
||||||
|
\ ['tidy'],
|
||||||
|
\)
|
||||||
|
|
||||||
|
if !executable(l:executable)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:config = ale#path#FindNearestFile(a:buffer, '.tidyrc')
|
||||||
|
let l:config_options = !empty(l:config)
|
||||||
|
\ ? ' -q --tidy-mark no --show-errors 0 --show-warnings 0 -config ' . ale#Escape(l:config)
|
||||||
|
\ : ' -q --tidy-mark no --show-errors 0 --show-warnings 0'
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'command': ale#Escape(l:executable) . l:config_options,
|
||||||
|
\}
|
||||||
|
endfunction
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
" Description: Error handling for the format GHC outputs.
|
" Description: Error handling for the format GHC outputs.
|
||||||
|
|
||||||
" Remember the directory used for temporary files for Vim.
|
" Remember the directory used for temporary files for Vim.
|
||||||
let s:temp_dir = fnamemodify(tempname(), ':h')
|
let s:temp_dir = fnamemodify(ale#util#Tempname(), ':h')
|
||||||
" Build part of a regular expression for matching ALE temporary filenames.
|
" Build part of a regular expression for matching ALE temporary filenames.
|
||||||
let s:temp_regex_prefix =
|
let s:temp_regex_prefix =
|
||||||
\ '\M'
|
\ '\M'
|
||||||
|
|||||||
@@ -97,14 +97,14 @@ function! s:ShowDetails(linter, buffer, line, column, opt) abort
|
|||||||
\ ? function('ale#hover#HandleTSServerResponse')
|
\ ? function('ale#hover#HandleTSServerResponse')
|
||||||
\ : function('ale#hover#HandleLSPResponse')
|
\ : function('ale#hover#HandleLSPResponse')
|
||||||
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(a:buffer, a:linter, l:Callback)
|
let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter, l:Callback)
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
if empty(l:lsp_details)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
let l:id = l:lsp_details.connection_id
|
||||||
let l:root = l:lsp_details.project_root
|
let l:language_id = l:lsp_details.language_id
|
||||||
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
if a:linter.lsp is# 'tsserver'
|
||||||
let l:column = a:column
|
let l:column = a:column
|
||||||
@@ -117,14 +117,14 @@ function! s:ShowDetails(linter, buffer, line, column, opt) abort
|
|||||||
else
|
else
|
||||||
" Send a message saying the buffer has changed first, or the
|
" Send a message saying the buffer has changed first, or the
|
||||||
" hover position probably won't make sense.
|
" hover position probably won't make sense.
|
||||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(a:buffer), l:root)
|
call ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
|
||||||
let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])])
|
let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])])
|
||||||
|
|
||||||
let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column)
|
let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
|
||||||
|
|
||||||
let s:hover_map[l:request_id] = {
|
let s:hover_map[l:request_id] = {
|
||||||
\ 'buffer': a:buffer,
|
\ 'buffer': a:buffer,
|
||||||
|
|||||||
@@ -26,34 +26,11 @@ function! s:KillHandler(timer) abort
|
|||||||
call job_stop(l:job, 'kill')
|
call job_stop(l:job, 'kill')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Note that jobs and IDs are the same thing on NeoVim.
|
|
||||||
function! ale#job#JoinNeovimOutput(job, last_line, data, mode, callback) abort
|
|
||||||
if a:mode is# 'raw'
|
|
||||||
call a:callback(a:job, join(a:data, "\n"))
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:lines = a:data[:-2]
|
|
||||||
|
|
||||||
if len(a:data) > 1
|
|
||||||
let l:lines[0] = a:last_line . l:lines[0]
|
|
||||||
let l:new_last_line = a:data[-1]
|
|
||||||
else
|
|
||||||
let l:new_last_line = a:last_line . get(a:data, 0, '')
|
|
||||||
endif
|
|
||||||
|
|
||||||
for l:line in l:lines
|
|
||||||
call a:callback(a:job, l:line)
|
|
||||||
endfor
|
|
||||||
|
|
||||||
return l:new_last_line
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NeoVimCallback(job, data, event) abort
|
function! s:NeoVimCallback(job, data, event) abort
|
||||||
let l:info = s:job_map[a:job]
|
let l:info = s:job_map[a:job]
|
||||||
|
|
||||||
if a:event is# 'stdout'
|
if a:event is# 'stdout'
|
||||||
let l:info.out_cb_line = ale#job#JoinNeovimOutput(
|
let l:info.out_cb_line = ale#util#JoinNeovimOutput(
|
||||||
\ a:job,
|
\ a:job,
|
||||||
\ l:info.out_cb_line,
|
\ l:info.out_cb_line,
|
||||||
\ a:data,
|
\ a:data,
|
||||||
@@ -61,7 +38,7 @@ function! s:NeoVimCallback(job, data, event) abort
|
|||||||
\ ale#util#GetFunction(l:info.out_cb),
|
\ ale#util#GetFunction(l:info.out_cb),
|
||||||
\)
|
\)
|
||||||
elseif a:event is# 'stderr'
|
elseif a:event is# 'stderr'
|
||||||
let l:info.err_cb_line = ale#job#JoinNeovimOutput(
|
let l:info.err_cb_line = ale#util#JoinNeovimOutput(
|
||||||
\ a:job,
|
\ a:job,
|
||||||
\ l:info.err_cb_line,
|
\ l:info.err_cb_line,
|
||||||
\ a:data,
|
\ a:data,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ let s:default_ale_linter_aliases = {
|
|||||||
\ 'csh': 'sh',
|
\ 'csh': 'sh',
|
||||||
\ 'plaintex': 'tex',
|
\ 'plaintex': 'tex',
|
||||||
\ 'systemverilog': 'verilog',
|
\ 'systemverilog': 'verilog',
|
||||||
|
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
||||||
\ 'vimwiki': 'markdown',
|
\ 'vimwiki': 'markdown',
|
||||||
\ 'zsh': 'sh',
|
\ 'zsh': 'sh',
|
||||||
\}
|
\}
|
||||||
@@ -227,6 +228,21 @@ function! ale#linter#PreProcess(linter) abort
|
|||||||
throw '`completion_filter` must be a callback'
|
throw '`completion_filter` must be a callback'
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if has_key(a:linter, 'initialization_options_callback')
|
||||||
|
if has_key(a:linter, 'initialization_options')
|
||||||
|
throw 'Only one of `initialization_options` or '
|
||||||
|
\ . '`initialization_options_callback` should be set'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:obj.initialization_options_callback = a:linter.initialization_options_callback
|
||||||
|
|
||||||
|
if !s:IsCallback(l:obj.initialization_options_callback)
|
||||||
|
throw '`initialization_options_callback` must be a callback if defined'
|
||||||
|
endif
|
||||||
|
elseif has_key(a:linter, 'initialization_options')
|
||||||
|
let l:obj.initialization_options = a:linter.initialization_options
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:obj.output_stream = get(a:linter, 'output_stream', 'stdout')
|
let l:obj.output_stream = get(a:linter, 'output_stream', 'stdout')
|
||||||
@@ -436,72 +452,3 @@ function! ale#linter#GetAddress(buffer, linter) abort
|
|||||||
\ ? ale#util#GetFunction(a:linter.address_callback)(a:buffer)
|
\ ? ale#util#GetFunction(a:linter.address_callback)(a:buffer)
|
||||||
\ : a:linter.address
|
\ : a:linter.address
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Given a buffer, an LSP linter, and a callback to register for handling
|
|
||||||
" messages, start up an LSP linter and get ready to receive errors or
|
|
||||||
" completions.
|
|
||||||
function! ale#linter#StartLSP(buffer, linter, callback) abort
|
|
||||||
let l:command = ''
|
|
||||||
let l:address = ''
|
|
||||||
let l:root = ale#util#GetFunction(a:linter.project_root_callback)(a:buffer)
|
|
||||||
|
|
||||||
if empty(l:root) && a:linter.lsp isnot# 'tsserver'
|
|
||||||
" If there's no project root, then we can't check files with LSP,
|
|
||||||
" unless we are using tsserver, which doesn't use project roots.
|
|
||||||
return {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
if a:linter.lsp is# 'socket'
|
|
||||||
let l:address = ale#linter#GetAddress(a:buffer, a:linter)
|
|
||||||
let l:conn_id = ale#lsp#ConnectToAddress(
|
|
||||||
\ l:address,
|
|
||||||
\ l:root,
|
|
||||||
\ a:callback,
|
|
||||||
\)
|
|
||||||
else
|
|
||||||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
|
||||||
|
|
||||||
if !executable(l:executable)
|
|
||||||
return {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:command = ale#job#PrepareCommand(
|
|
||||||
\ a:buffer,
|
|
||||||
\ ale#linter#GetCommand(a:buffer, a:linter),
|
|
||||||
\)
|
|
||||||
let l:conn_id = ale#lsp#StartProgram(
|
|
||||||
\ l:executable,
|
|
||||||
\ l:command,
|
|
||||||
\ l:root,
|
|
||||||
\ a:callback,
|
|
||||||
\)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer)
|
|
||||||
|
|
||||||
if !l:conn_id
|
|
||||||
if g:ale_history_enabled && !empty(l:command)
|
|
||||||
call ale#history#Add(a:buffer, 'failed', l:conn_id, l:command)
|
|
||||||
endif
|
|
||||||
|
|
||||||
return {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
if ale#lsp#OpenDocumentIfNeeded(l:conn_id, a:buffer, l:root, l:language_id)
|
|
||||||
if g:ale_history_enabled && !empty(l:command)
|
|
||||||
call ale#history#Add(a:buffer, 'started', l:conn_id, l:command)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" The change message needs to be sent for tsserver before doing anything.
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
|
||||||
call ale#lsp#Send(l:conn_id, ale#lsp#tsserver_message#Change(a:buffer))
|
|
||||||
endif
|
|
||||||
|
|
||||||
return {
|
|
||||||
\ 'connection_id': l:conn_id,
|
|
||||||
\ 'command': l:command,
|
|
||||||
\ 'project_root': l:root,
|
|
||||||
\ 'language_id': l:language_id,
|
|
||||||
\}
|
|
||||||
endfunction
|
|
||||||
|
|||||||
@@ -3,21 +3,25 @@
|
|||||||
|
|
||||||
" A List of connections, used for tracking servers which have been connected
|
" A List of connections, used for tracking servers which have been connected
|
||||||
" to, and programs which are run.
|
" to, and programs which are run.
|
||||||
let s:connections = []
|
let s:connections = get(s:, 'connections', [])
|
||||||
let g:ale_lsp_next_message_id = 1
|
let g:ale_lsp_next_message_id = 1
|
||||||
|
|
||||||
function! s:NewConnection() abort
|
" Exposed only so tests can get at it.
|
||||||
|
" Do not call this function basically anywhere.
|
||||||
|
function! ale#lsp#NewConnection(initialization_options) abort
|
||||||
" id: The job ID as a Number, or the server address as a string.
|
" id: The job ID as a Number, or the server address as a string.
|
||||||
" data: The message data received so far.
|
" data: The message data received so far.
|
||||||
" executable: An executable only set for program connections.
|
" executable: An executable only set for program connections.
|
||||||
" open_documents: A list of buffers we told the server we opened.
|
" open_documents: A Dictionary mapping buffers to b:changedtick, keeping
|
||||||
|
" track of when documents were opened, and when we last changed them.
|
||||||
" callback_list: A list of callbacks for handling LSP responses.
|
" callback_list: A list of callbacks for handling LSP responses.
|
||||||
let l:conn = {
|
let l:conn = {
|
||||||
\ 'id': '',
|
\ 'id': '',
|
||||||
\ 'data': '',
|
\ 'data': '',
|
||||||
\ 'projects': {},
|
\ 'projects': {},
|
||||||
\ 'open_documents': [],
|
\ 'open_documents': {},
|
||||||
\ 'callback_list': [],
|
\ 'callback_list': [],
|
||||||
|
\ 'initialization_options': a:initialization_options,
|
||||||
\}
|
\}
|
||||||
|
|
||||||
call add(s:connections, l:conn)
|
call add(s:connections, l:conn)
|
||||||
@@ -25,9 +29,14 @@ function! s:NewConnection() abort
|
|||||||
return l:conn
|
return l:conn
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Remove an LSP connection with a given ID. This is only for tests.
|
||||||
|
function! ale#lsp#RemoveConnectionWithID(id) abort
|
||||||
|
call filter(s:connections, 'v:val.id isnot a:id')
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:FindConnection(key, value) abort
|
function! s:FindConnection(key, value) abort
|
||||||
for l:conn in s:connections
|
for l:conn in s:connections
|
||||||
if has_key(l:conn, a:key) && get(l:conn, a:key) == a:value
|
if has_key(l:conn, a:key) && get(l:conn, a:key) is# a:value
|
||||||
return l:conn
|
return l:conn
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
@@ -207,6 +216,11 @@ function! ale#lsp#HandleOtherInitializeResponses(conn, response) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp#HandleMessage(conn, message) abort
|
function! ale#lsp#HandleMessage(conn, message) abort
|
||||||
|
if type(a:message) != type('')
|
||||||
|
" Ignore messages that aren't strings.
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
let a:conn.data .= a:message
|
let a:conn.data .= a:message
|
||||||
|
|
||||||
" Parse the objects now if we can, and keep the remaining text.
|
" Parse the objects now if we can, and keep the remaining text.
|
||||||
@@ -227,9 +241,8 @@ function! ale#lsp#HandleMessage(conn, message) abort
|
|||||||
endfor
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleChannelMessage(channel, message) abort
|
function! s:HandleChannelMessage(channel_id, message) abort
|
||||||
let l:info = ch_info(a:channel)
|
let l:address = ale#socket#GetAddress(a:channel_id)
|
||||||
let l:address = l:info.hostname . l:info.address
|
|
||||||
let l:conn = s:FindConnection('id', l:address)
|
let l:conn = s:FindConnection('id', l:address)
|
||||||
|
|
||||||
call ale#lsp#HandleMessage(l:conn, a:message)
|
call ale#lsp#HandleMessage(l:conn, a:message)
|
||||||
@@ -266,7 +279,7 @@ endfunction
|
|||||||
"
|
"
|
||||||
" The job ID will be returned for for the program if it ran, otherwise
|
" The job ID will be returned for for the program if it ran, otherwise
|
||||||
" 0 will be returned.
|
" 0 will be returned.
|
||||||
function! ale#lsp#StartProgram(executable, command, project_root, callback) abort
|
function! ale#lsp#StartProgram(executable, command, project_root, callback, initialization_options) abort
|
||||||
if !executable(a:executable)
|
if !executable(a:executable)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
@@ -274,7 +287,7 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback) abor
|
|||||||
let l:conn = s:FindConnection('executable', a:executable)
|
let l:conn = s:FindConnection('executable', a:executable)
|
||||||
|
|
||||||
" Get the current connection or a new one.
|
" Get the current connection or a new one.
|
||||||
let l:conn = !empty(l:conn) ? l:conn : s:NewConnection()
|
let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:initialization_options)
|
||||||
let l:conn.executable = a:executable
|
let l:conn.executable = a:executable
|
||||||
|
|
||||||
if !has_key(l:conn, 'id') || !ale#job#IsRunning(l:conn.id)
|
if !has_key(l:conn, 'id') || !ale#job#IsRunning(l:conn.id)
|
||||||
@@ -300,21 +313,19 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback) abor
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Connect to an address and set up a callback for handling responses.
|
" Connect to an address and set up a callback for handling responses.
|
||||||
function! ale#lsp#ConnectToAddress(address, project_root, callback) abort
|
function! ale#lsp#ConnectToAddress(address, project_root, callback, initialization_options) abort
|
||||||
let l:conn = s:FindConnection('id', a:address)
|
let l:conn = s:FindConnection('id', a:address)
|
||||||
" Get the current connection or a new one.
|
" Get the current connection or a new one.
|
||||||
let l:conn = !empty(l:conn) ? l:conn : s:NewConnection()
|
let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:initialization_options)
|
||||||
|
|
||||||
if !has_key(l:conn, 'channel') || ch_status(l:conn.channel) isnot# 'open'
|
if !has_key(l:conn, 'channel_id') || !ale#socket#IsOpen(l:conn.channel_id)
|
||||||
let l:conn.channnel = ch_open(a:address, {
|
let l:conn.channel_id = ale#socket#Open(a:address, {
|
||||||
\ 'mode': 'raw',
|
|
||||||
\ 'waittime': 0,
|
|
||||||
\ 'callback': function('s:HandleChannelMessage'),
|
\ 'callback': function('s:HandleChannelMessage'),
|
||||||
\})
|
\})
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ch_status(l:conn.channnel) is# 'fail'
|
if l:conn.channel_id < 0
|
||||||
return 0
|
return ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:conn.id = a:address
|
let l:conn.id = a:address
|
||||||
@@ -322,15 +333,15 @@ function! ale#lsp#ConnectToAddress(address, project_root, callback) abort
|
|||||||
call uniq(sort(add(l:conn.callback_list, a:callback)))
|
call uniq(sort(add(l:conn.callback_list, a:callback)))
|
||||||
call ale#lsp#RegisterProject(l:conn, a:project_root)
|
call ale#lsp#RegisterProject(l:conn, a:project_root)
|
||||||
|
|
||||||
return 1
|
return a:address
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Stop all LSP connections, closing all jobs and channels, and removing any
|
" Stop all LSP connections, closing all jobs and channels, and removing any
|
||||||
" queued messages.
|
" queued messages.
|
||||||
function! ale#lsp#StopAll() abort
|
function! ale#lsp#StopAll() abort
|
||||||
for l:conn in s:connections
|
for l:conn in s:connections
|
||||||
if has_key(l:conn, 'channel')
|
if has_key(l:conn, 'channel_id')
|
||||||
call ch_close(l:conn.channel)
|
call ale#socket#Close(l:conn.channel_id)
|
||||||
else
|
else
|
||||||
call ale#job#Stop(l:conn.id)
|
call ale#job#Stop(l:conn.id)
|
||||||
endif
|
endif
|
||||||
@@ -342,9 +353,9 @@ endfunction
|
|||||||
function! s:SendMessageData(conn, data) abort
|
function! s:SendMessageData(conn, data) abort
|
||||||
if has_key(a:conn, 'executable')
|
if has_key(a:conn, 'executable')
|
||||||
call ale#job#SendRaw(a:conn.id, a:data)
|
call ale#job#SendRaw(a:conn.id, a:data)
|
||||||
elseif has_key(a:conn, 'channel') && ch_status(a:conn.channnel) is# 'open'
|
elseif has_key(a:conn, 'channel_id') && ale#socket#IsOpen(a:conn.channel_id)
|
||||||
" Send the message to the server
|
" Send the message to the server
|
||||||
call ch_sendraw(a:conn.channel, a:data)
|
call ale#socket#Send(a:conn.channel_id, a:data)
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
@@ -378,7 +389,7 @@ function! ale#lsp#Send(conn_id, message, ...) abort
|
|||||||
" Only send the init message once.
|
" Only send the init message once.
|
||||||
if !l:project.init_request_id
|
if !l:project.init_request_id
|
||||||
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
|
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
|
||||||
\ ale#lsp#message#Initialize(l:project_root),
|
\ ale#lsp#message#Initialize(l:project_root, l:conn.initialization_options),
|
||||||
\)
|
\)
|
||||||
|
|
||||||
let l:project.init_request_id = l:init_id
|
let l:project.init_request_id = l:init_id
|
||||||
@@ -400,21 +411,72 @@ function! ale#lsp#Send(conn_id, message, ...) abort
|
|||||||
return l:id == 0 ? -1 : l:id
|
return l:id == 0 ? -1 : l:id
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp#OpenDocumentIfNeeded(conn_id, buffer, project_root, language_id) abort
|
" The Document details Dictionary should contain the following keys.
|
||||||
let l:conn = s:FindConnection('id', a:conn_id)
|
"
|
||||||
|
" buffer - The buffer number for the document.
|
||||||
|
" connection_id - The connection ID for the LSP server.
|
||||||
|
" command - The command to run to start the LSP connection.
|
||||||
|
" project_root - The project root for the LSP project.
|
||||||
|
" language_id - The language ID for the project, like 'python', 'rust', etc.
|
||||||
|
|
||||||
|
" Create a new Dictionary containing more connection details, with the
|
||||||
|
" following information added:
|
||||||
|
"
|
||||||
|
" conn - An existing LSP connection for the document.
|
||||||
|
" document_open - 1 if the document is currently open, 0 otherwise.
|
||||||
|
function! s:ExtendDocumentDetails(details) abort
|
||||||
|
let l:extended = copy(a:details)
|
||||||
|
let l:conn = s:FindConnection('id', a:details.connection_id)
|
||||||
|
|
||||||
|
let l:extended.conn = l:conn
|
||||||
|
let l:extended.document_open = !empty(l:conn)
|
||||||
|
\ && has_key(l:conn.open_documents, a:details.buffer)
|
||||||
|
|
||||||
|
return l:extended
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Notify LSP servers or tsserver if a document is opened, if needed.
|
||||||
|
" If a document is opened, 1 will be returned, otherwise 0 will be returned.
|
||||||
|
function! ale#lsp#OpenDocument(basic_details) abort
|
||||||
|
let l:d = s:ExtendDocumentDetails(a:basic_details)
|
||||||
let l:opened = 0
|
let l:opened = 0
|
||||||
|
|
||||||
if !empty(l:conn) && index(l:conn.open_documents, a:buffer) < 0
|
if !empty(l:d.conn) && !l:d.document_open
|
||||||
if empty(a:language_id)
|
if empty(l:d.language_id)
|
||||||
let l:message = ale#lsp#tsserver_message#Open(a:buffer)
|
let l:message = ale#lsp#tsserver_message#Open(l:d.buffer)
|
||||||
else
|
else
|
||||||
let l:message = ale#lsp#message#DidOpen(a:buffer, a:language_id)
|
let l:message = ale#lsp#message#DidOpen(l:d.buffer, l:d.language_id)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#lsp#Send(a:conn_id, l:message, a:project_root)
|
call ale#lsp#Send(l:d.connection_id, l:message, l:d.project_root)
|
||||||
call add(l:conn.open_documents, a:buffer)
|
let l:d.conn.open_documents[l:d.buffer] = getbufvar(l:d.buffer, 'changedtick')
|
||||||
let l:opened = 1
|
let l:opened = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return l:opened
|
return l:opened
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Notify LSP servers or tsserver that a document has changed, if needed.
|
||||||
|
" If a notification is sent, 1 will be returned, otherwise 0 will be returned.
|
||||||
|
function! ale#lsp#NotifyForChanges(basic_details) abort
|
||||||
|
let l:d = s:ExtendDocumentDetails(a:basic_details)
|
||||||
|
let l:notified = 0
|
||||||
|
|
||||||
|
if l:d.document_open
|
||||||
|
let l:new_tick = getbufvar(l:d.buffer, 'changedtick')
|
||||||
|
|
||||||
|
if l:d.conn.open_documents[l:d.buffer] < l:new_tick
|
||||||
|
if empty(l:d.language_id)
|
||||||
|
let l:message = ale#lsp#tsserver_message#Change(l:d.buffer)
|
||||||
|
else
|
||||||
|
let l:message = ale#lsp#message#DidChange(l:d.buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call ale#lsp#Send(l:d.connection_id, l:message, l:d.project_root)
|
||||||
|
let l:d.conn.open_documents[l:d.buffer] = l:new_tick
|
||||||
|
let l:notified = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:notified
|
||||||
|
endfunction
|
||||||
|
|||||||
@@ -24,12 +24,15 @@ function! ale#lsp#message#GetNextVersionID() abort
|
|||||||
return l:id
|
return l:id
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp#message#Initialize(root_path) abort
|
function! ale#lsp#message#Initialize(root_path, initialization_options) abort
|
||||||
" TODO: Define needed capabilities.
|
" TODO: Define needed capabilities.
|
||||||
|
" NOTE: rootPath is deprecated in favour of rootUri
|
||||||
return [0, 'initialize', {
|
return [0, 'initialize', {
|
||||||
\ 'processId': getpid(),
|
\ 'processId': getpid(),
|
||||||
\ 'rootPath': a:root_path,
|
\ 'rootPath': a:root_path,
|
||||||
\ 'capabilities': {},
|
\ 'capabilities': {},
|
||||||
|
\ 'initializationOptions': a:initialization_options,
|
||||||
|
\ 'rootUri': ale#path#ToURI(a:root_path),
|
||||||
\}]
|
\}]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ function! ale#lsp#reset#StopAllLSPs() abort
|
|||||||
call ale#definition#ClearLSPData()
|
call ale#definition#ClearLSPData()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if exists('*ale#engine#ClearLSPData')
|
if exists('*ale#lsp_linter#ClearLSPData')
|
||||||
" Clear the mapping for connections, etc.
|
" Clear the mapping for connections, etc.
|
||||||
call ale#engine#ClearLSPData()
|
call ale#lsp_linter#ClearLSPData()
|
||||||
|
|
||||||
" Remove the problems for all of the LSP linters in every buffer.
|
" Remove the problems for all of the LSP linters in every buffer.
|
||||||
for l:buffer_string in keys(g:ale_buffer_info)
|
for l:buffer_string in keys(g:ale_buffer_info)
|
||||||
|
|||||||
@@ -105,12 +105,18 @@ function! ale#lsp#response#GetErrorMessage(response) abort
|
|||||||
return ''
|
return ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Include the traceback as details, if it's there.
|
" Include the traceback or error data as details, if present.
|
||||||
let l:traceback = get(get(a:response.error, 'data', {}), 'traceback', [])
|
let l:error_data = get(a:response.error, 'data', {})
|
||||||
|
|
||||||
|
if type(l:error_data) is type('')
|
||||||
|
let l:message .= "\n" . l:error_data
|
||||||
|
else
|
||||||
|
let l:traceback = get(l:error_data, 'traceback', [])
|
||||||
|
|
||||||
if type(l:traceback) is type([]) && !empty(l:traceback)
|
if type(l:traceback) is type([]) && !empty(l:traceback)
|
||||||
let l:message .= "\n" . join(l:traceback, "\n")
|
let l:message .= "\n" . join(l:traceback, "\n")
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
return l:message
|
return l:message
|
||||||
endfunction
|
endfunction
|
||||||
|
|||||||
252
autoload/ale/lsp_linter.vim
Normal file
252
autoload/ale/lsp_linter.vim
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: Integration between linters and LSP/tsserver.
|
||||||
|
|
||||||
|
" This code isn't loaded if a user never users LSP features or linters.
|
||||||
|
|
||||||
|
" Associates LSP connection IDs with linter names.
|
||||||
|
if !has_key(s:, 'lsp_linter_map')
|
||||||
|
let s:lsp_linter_map = {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Check if diagnostics for a particular linter should be ignored.
|
||||||
|
function! s:ShouldIgnore(buffer, linter_name) abort
|
||||||
|
let l:config = ale#Var(a:buffer, 'linters_ignore')
|
||||||
|
|
||||||
|
" Don't load code for ignoring diagnostics if there's nothing to ignore.
|
||||||
|
if empty(l:config)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||||
|
let l:ignore_list = ale#engine#ignore#GetList(l:filetype, l:config)
|
||||||
|
|
||||||
|
return index(l:ignore_list, a:linter_name) >= 0
|
||||||
|
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 s:ShouldIgnore(l:buffer, l:linter_name)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
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:linter_name = 'tsserver'
|
||||||
|
let l:buffer = bufnr(a:response.body.file)
|
||||||
|
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||||
|
|
||||||
|
if empty(l:info)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if s:ShouldIgnore(l:buffer, l:linter_name)
|
||||||
|
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(l:linter_name, l:buffer, l:loclist)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:HandleLSPErrorMessage(linter_name, response) abort
|
||||||
|
if !g:ale_history_enabled || !g:ale_history_log_output
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if empty(a:linter_name)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:message = ale#lsp#response#GetErrorMessage(a:response)
|
||||||
|
|
||||||
|
if empty(l:message)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" This global variable is set here so we don't load the debugging.vim file
|
||||||
|
" until someone uses :ALEInfo.
|
||||||
|
let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
|
||||||
|
|
||||||
|
if !has_key(g:ale_lsp_error_messages, a:linter_name)
|
||||||
|
let g:ale_lsp_error_messages[a:linter_name] = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(g:ale_lsp_error_messages[a:linter_name], l:message)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
|
||||||
|
let l:method = get(a:response, 'method', '')
|
||||||
|
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
|
||||||
|
|
||||||
|
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
|
||||||
|
call s:HandleLSPErrorMessage(l:linter_name, a:response)
|
||||||
|
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
|
||||||
|
|
||||||
|
" Given a buffer, an LSP linter, and a callback to register for handling
|
||||||
|
" messages, start up an LSP linter and get ready to receive errors or
|
||||||
|
" completions.
|
||||||
|
function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort
|
||||||
|
let l:command = ''
|
||||||
|
let l:address = ''
|
||||||
|
let l:root = ale#util#GetFunction(a:linter.project_root_callback)(a:buffer)
|
||||||
|
|
||||||
|
if empty(l:root) && a:linter.lsp isnot# 'tsserver'
|
||||||
|
" If there's no project root, then we can't check files with LSP,
|
||||||
|
" unless we are using tsserver, which doesn't use project roots.
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:initialization_options = {}
|
||||||
|
|
||||||
|
if has_key(a:linter, 'initialization_options_callback')
|
||||||
|
let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer)
|
||||||
|
elseif has_key(a:linter, 'initialization_options')
|
||||||
|
let l:initialization_options = a:linter.initialization_options
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:linter.lsp is# 'socket'
|
||||||
|
let l:address = ale#linter#GetAddress(a:buffer, a:linter)
|
||||||
|
let l:conn_id = ale#lsp#ConnectToAddress(
|
||||||
|
\ l:address,
|
||||||
|
\ l:root,
|
||||||
|
\ a:callback,
|
||||||
|
\ l:initialization_options,
|
||||||
|
\)
|
||||||
|
else
|
||||||
|
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||||
|
|
||||||
|
if !executable(l:executable)
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:command = ale#job#PrepareCommand(
|
||||||
|
\ a:buffer,
|
||||||
|
\ ale#linter#GetCommand(a:buffer, a:linter),
|
||||||
|
\)
|
||||||
|
let l:conn_id = ale#lsp#StartProgram(
|
||||||
|
\ l:executable,
|
||||||
|
\ l:command,
|
||||||
|
\ l:root,
|
||||||
|
\ a:callback,
|
||||||
|
\ l:initialization_options,
|
||||||
|
\)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer)
|
||||||
|
|
||||||
|
if empty(l:conn_id)
|
||||||
|
if g:ale_history_enabled && !empty(l:command)
|
||||||
|
call ale#history#Add(a:buffer, 'failed', l:conn_id, l:command)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:details = {
|
||||||
|
\ 'buffer': a:buffer,
|
||||||
|
\ 'connection_id': l:conn_id,
|
||||||
|
\ 'command': l:command,
|
||||||
|
\ 'project_root': l:root,
|
||||||
|
\ 'language_id': l:language_id,
|
||||||
|
\}
|
||||||
|
|
||||||
|
if ale#lsp#OpenDocument(l:details)
|
||||||
|
if g:ale_history_enabled && !empty(l:command)
|
||||||
|
call ale#history#Add(a:buffer, 'started', l:conn_id, l:command)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" The change message needs to be sent for tsserver before doing anything.
|
||||||
|
if a:linter.lsp is# 'tsserver'
|
||||||
|
call ale#lsp#NotifyForChanges(l:details)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:details
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
|
||||||
|
let l:info = g:ale_buffer_info[a:buffer]
|
||||||
|
let l:lsp_details = ale#lsp_linter#StartLSP(
|
||||||
|
\ a:buffer,
|
||||||
|
\ a:linter,
|
||||||
|
\ function('ale#lsp_linter#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
|
||||||
|
|
||||||
|
if a:linter.lsp is# 'tsserver'
|
||||||
|
let l:message = ale#lsp#tsserver_message#Geterr(a:buffer)
|
||||||
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
||||||
|
|
||||||
|
let l:notified = l:request_id != 0
|
||||||
|
else
|
||||||
|
let l:notified = ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" 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)
|
||||||
|
|
||||||
|
let l:notified = l:request_id != 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:notified
|
||||||
|
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:notified
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Clear LSP linter data for the linting engine.
|
||||||
|
function! ale#lsp_linter#ClearLSPData() abort
|
||||||
|
let s:lsp_linter_map = {}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Just for tests.
|
||||||
|
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
|
||||||
|
let s:lsp_linter_map = a:replacement_map
|
||||||
|
endfunction
|
||||||
@@ -84,7 +84,7 @@ function! ale#path#IsAbsolute(filename) abort
|
|||||||
return a:filename[:0] is# '/' || a:filename[1:2] is# ':\'
|
return a:filename[:0] is# '/' || a:filename[1:2] is# ':\'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:temp_dir = ale#path#Simplify(fnamemodify(tempname(), ':h'))
|
let s:temp_dir = ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h'))
|
||||||
|
|
||||||
" Given a filename, return 1 if the file represents some temporary file
|
" Given a filename, return 1 if the file represents some temporary file
|
||||||
" created by Vim.
|
" created by Vim.
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ function! s:CmpPatterns(left_item, right_item) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#pattern_options#SetOptions(buffer) abort
|
function! ale#pattern_options#SetOptions(buffer) abort
|
||||||
if !g:ale_pattern_options_enabled || empty(g:ale_pattern_options)
|
if !get(g:, 'ale_pattern_options_enabled', 0)
|
||||||
|
\|| empty(get(g:, 'ale_pattern_options', 0))
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -2,22 +2,41 @@
|
|||||||
" Description: Preview windows for showing whatever information in.
|
" Description: Preview windows for showing whatever information in.
|
||||||
|
|
||||||
" Open a preview window and show some lines in it.
|
" Open a preview window and show some lines in it.
|
||||||
" An optional second argument can set an alternative filetype for the window.
|
" A second argument can be passed as a Dictionary with options. They are...
|
||||||
|
"
|
||||||
|
" filetype - The filetype to use, defaulting to 'ale-preview'
|
||||||
|
" stay_here - If 1, stay in the window you came from.
|
||||||
function! ale#preview#Show(lines, ...) abort
|
function! ale#preview#Show(lines, ...) abort
|
||||||
let l:filetype = get(a:000, 0, 'ale-preview')
|
let l:options = get(a:000, 0, {})
|
||||||
|
|
||||||
silent pedit ALEPreviewWindow
|
silent pedit ALEPreviewWindow
|
||||||
wincmd P
|
wincmd P
|
||||||
|
|
||||||
setlocal modifiable
|
setlocal modifiable
|
||||||
setlocal noreadonly
|
setlocal noreadonly
|
||||||
setlocal nobuflisted
|
setlocal nobuflisted
|
||||||
let &l:filetype = l:filetype
|
let &l:filetype = get(l:options, 'filetype', 'ale-preview')
|
||||||
setlocal buftype=nofile
|
setlocal buftype=nofile
|
||||||
setlocal bufhidden=wipe
|
setlocal bufhidden=wipe
|
||||||
:%d
|
:%d
|
||||||
call setline(1, a:lines)
|
call setline(1, a:lines)
|
||||||
setlocal nomodifiable
|
setlocal nomodifiable
|
||||||
setlocal readonly
|
setlocal readonly
|
||||||
|
|
||||||
|
if get(l:options, 'stay_here')
|
||||||
|
wincmd p
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Close the preview window if the filetype matches the given one.
|
||||||
|
function! ale#preview#CloseIfTypeMatches(filetype) abort
|
||||||
|
for l:win in getwininfo()
|
||||||
|
let l:wintype = gettabwinvar(l:win.tabnr, l:win.winnr, '&filetype')
|
||||||
|
|
||||||
|
if l:wintype is# a:filetype
|
||||||
|
silent! pclose!
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Show a location selection preview window, given some items.
|
" Show a location selection preview window, given some items.
|
||||||
@@ -35,7 +54,7 @@ function! ale#preview#ShowSelection(item_list) abort
|
|||||||
\)
|
\)
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
call ale#preview#Show(l:lines, 'ale-preview-selection')
|
call ale#preview#Show(l:lines, {'filetype': 'ale-preview-selection'})
|
||||||
let b:ale_preview_item_list = a:item_list
|
let b:ale_preview_item_list = a:item_list
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|||||||
@@ -72,14 +72,13 @@ function! s:FindReferences(linter) abort
|
|||||||
\ ? function('ale#references#HandleTSServerResponse')
|
\ ? function('ale#references#HandleTSServerResponse')
|
||||||
\ : function('ale#references#HandleLSPResponse')
|
\ : function('ale#references#HandleLSPResponse')
|
||||||
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
|
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
if empty(l:lsp_details)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
let l:id = l:lsp_details.connection_id
|
||||||
let l:root = l:lsp_details.project_root
|
|
||||||
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
if a:linter.lsp is# 'tsserver'
|
||||||
let l:message = ale#lsp#tsserver_message#References(
|
let l:message = ale#lsp#tsserver_message#References(
|
||||||
@@ -90,14 +89,14 @@ function! s:FindReferences(linter) abort
|
|||||||
else
|
else
|
||||||
" Send a message saying the buffer has changed first, or the
|
" Send a message saying the buffer has changed first, or the
|
||||||
" references position probably won't make sense.
|
" references position probably won't make sense.
|
||||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
|
call ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
|
||||||
let l:column = min([l:column, len(getline(l:line))])
|
let l:column = min([l:column, len(getline(l:line))])
|
||||||
|
|
||||||
let l:message = ale#lsp#message#References(l:buffer, l:line, l:column)
|
let l:message = ale#lsp#message#References(l:buffer, l:line, l:column)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
|
||||||
|
|
||||||
let s:references_map[l:request_id] = {}
|
let s:references_map[l:request_id] = {}
|
||||||
endfunction
|
endfunction
|
||||||
|
|||||||
@@ -45,14 +45,12 @@ if !hlexists('ALESignColumnWithErrors')
|
|||||||
highlight link ALESignColumnWithErrors error
|
highlight link ALESignColumnWithErrors error
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if !hlexists('ALESignColumnWithoutErrors')
|
function! ale#sign#SetUpDefaultColumnWithoutErrorsHighlight() abort
|
||||||
function! s:SetSignColumnWithoutErrorsHighlight() abort
|
|
||||||
redir => l:output
|
redir => l:output
|
||||||
silent highlight SignColumn
|
0verbose silent highlight SignColumn
|
||||||
redir end
|
redir end
|
||||||
|
|
||||||
let l:highlight_syntax = join(split(l:output)[2:])
|
let l:highlight_syntax = join(split(l:output)[2:])
|
||||||
|
|
||||||
let l:match = matchlist(l:highlight_syntax, '\vlinks to (.+)$')
|
let l:match = matchlist(l:highlight_syntax, '\vlinks to (.+)$')
|
||||||
|
|
||||||
if !empty(l:match)
|
if !empty(l:match)
|
||||||
@@ -60,10 +58,10 @@ if !hlexists('ALESignColumnWithoutErrors')
|
|||||||
elseif l:highlight_syntax isnot# 'cleared'
|
elseif l:highlight_syntax isnot# 'cleared'
|
||||||
execute 'highlight ALESignColumnWithoutErrors ' . l:highlight_syntax
|
execute 'highlight ALESignColumnWithoutErrors ' . l:highlight_syntax
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call s:SetSignColumnWithoutErrorsHighlight()
|
if !hlexists('ALESignColumnWithoutErrors')
|
||||||
delfunction s:SetSignColumnWithoutErrorsHighlight
|
call ale#sign#SetUpDefaultColumnWithoutErrorsHighlight()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Signs show up on the left for error markers.
|
" Signs show up on the left for error markers.
|
||||||
|
|||||||
144
autoload/ale/socket.vim
Normal file
144
autoload/ale/socket.vim
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: APIs for working with asynchronous sockets, with an API
|
||||||
|
" normalised between Vim 8 and NeoVim. Socket connections only work in NeoVim
|
||||||
|
" 0.3+, and silently do nothing in earlier NeoVim versions.
|
||||||
|
"
|
||||||
|
" Important functions are described below. They are:
|
||||||
|
"
|
||||||
|
" ale#socket#Open(address, options) -> channel_id (>= 0 if successful)
|
||||||
|
" ale#socket#IsOpen(channel_id) -> 1 if open, 0 otherwise
|
||||||
|
" ale#socket#Close(channel_id)
|
||||||
|
" ale#socket#Send(channel_id, data)
|
||||||
|
" ale#socket#GetAddress(channel_id) -> Return the address for a job
|
||||||
|
|
||||||
|
let s:channel_map = get(s:, 'channel_map', {})
|
||||||
|
|
||||||
|
function! s:VimOutputCallback(channel, data) abort
|
||||||
|
let l:channel_id = ch_info(a:channel).id
|
||||||
|
|
||||||
|
" Only call the callbacks for jobs which are valid.
|
||||||
|
if l:channel_id >= 0 && has_key(s:channel_map, l:channel_id)
|
||||||
|
call ale#util#GetFunction(s:channel_map[l:channel_id].callback)(l:channel_id, a:data)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:NeoVimOutputCallback(channel_id, data, event) abort
|
||||||
|
let l:info = s:channel_map[a:channel_id]
|
||||||
|
|
||||||
|
if a:event is# 'data'
|
||||||
|
let l:info.last_line = ale#util#JoinNeovimOutput(
|
||||||
|
\ a:channel_id,
|
||||||
|
\ l:info.last_line,
|
||||||
|
\ a:data,
|
||||||
|
\ l:info.mode,
|
||||||
|
\ ale#util#GetFunction(l:info.callback),
|
||||||
|
\)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Open a socket for a given address. The following options are accepted:
|
||||||
|
"
|
||||||
|
" callback - A callback for receiving input. (required)
|
||||||
|
"
|
||||||
|
" A non-negative number representing a channel ID will be returned is the
|
||||||
|
" connection was successful. 0 is a valid channel ID in Vim, so test if the
|
||||||
|
" connection ID is >= 0.
|
||||||
|
function! ale#socket#Open(address, options) abort
|
||||||
|
let l:mode = get(a:options, 'mode', 'raw')
|
||||||
|
let l:Callback = a:options.callback
|
||||||
|
|
||||||
|
let l:channel_info = {
|
||||||
|
\ 'address': a:address,
|
||||||
|
\ 'mode': l:mode,
|
||||||
|
\ 'callback': a:options.callback,
|
||||||
|
\}
|
||||||
|
|
||||||
|
if !has('nvim')
|
||||||
|
" Vim
|
||||||
|
let l:channel_info.channel = ch_open(a:address, {
|
||||||
|
\ 'mode': l:mode,
|
||||||
|
\ 'waittime': 0,
|
||||||
|
\ 'callback': function('s:VimOutputCallback'),
|
||||||
|
\})
|
||||||
|
let l:vim_info = ch_info(l:channel_info.channel)
|
||||||
|
let l:channel_id = !empty(l:vim_info) ? l:vim_info.id : -1
|
||||||
|
elseif exists('*chansend') && exists('*sockconnect')
|
||||||
|
" NeoVim 0.3+
|
||||||
|
try
|
||||||
|
let l:channel_id = sockconnect('tcp', a:address, {
|
||||||
|
\ 'on_data': function('s:NeoVimOutputCallback'),
|
||||||
|
\})
|
||||||
|
let l:channel_info.last_line = ''
|
||||||
|
catch /connection failed/
|
||||||
|
let l:channel_id = -1
|
||||||
|
endtry
|
||||||
|
|
||||||
|
" 0 means the connection failed some times in NeoVim, so make the ID
|
||||||
|
" invalid to match Vim.
|
||||||
|
if l:channel_id is 0
|
||||||
|
let l:channel_id = -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:channel_info.channel = l:channel_id
|
||||||
|
else
|
||||||
|
" Other Vim versions.
|
||||||
|
let l:channel_id = -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:channel_id >= 0
|
||||||
|
let s:channel_map[l:channel_id] = l:channel_info
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:channel_id
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Return 1 is a channel is open, 0 otherwise.
|
||||||
|
function! ale#socket#IsOpen(channel_id) abort
|
||||||
|
if !has_key(s:channel_map, a:channel_id)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
" In NeoVim, we have to check if this channel is in the global list.
|
||||||
|
return index(map(nvim_list_chans(), 'v:val.id'), a:channel_id) >= 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:channel = s:channel_map[a:channel_id].channel
|
||||||
|
return ch_status(l:channel) is# 'open'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Close a socket, if it's still open.
|
||||||
|
function! ale#socket#Close(channel_id) abort
|
||||||
|
" IsRunning isn't called here, so we don't check nvim_list_chans()
|
||||||
|
if !has_key(s:channel_map, a:channel_id)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:channel = remove(s:channel_map, a:channel_id).channel
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
silent! call chanclose(l:channel)
|
||||||
|
elseif ch_status(l:channel) is# 'open'
|
||||||
|
call ch_close(l:channel)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Send some data to a socket.
|
||||||
|
function! ale#socket#Send(channel_id, data) abort
|
||||||
|
if !has_key(s:channel_map, a:channel_id)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:channel = s:channel_map[a:channel_id].channel
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
call chansend(l:channel, a:data)
|
||||||
|
else
|
||||||
|
call ch_sendraw(l:channel, a:data)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Get an address for a channel, or an empty string.
|
||||||
|
function! ale#socket#GetAddress(channel_id) abort
|
||||||
|
return get(get(s:channel_map, a:channel_id, {}), 'address', '')
|
||||||
|
endfunction
|
||||||
@@ -1,14 +1,6 @@
|
|||||||
" Author: KabbAmine <amine.kabb@gmail.com>
|
" Author: KabbAmine <amine.kabb@gmail.com>
|
||||||
" Description: Statusline related function(s)
|
" Description: Statusline related function(s)
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
"
|
|
||||||
" A deprecated setting for ale#statusline#Status()
|
|
||||||
" See :help ale#statusline#Count() for getting status reports.
|
|
||||||
let g:ale_statusline_format = get(g:, 'ale_statusline_format',
|
|
||||||
\ ['%d error(s)', '%d warning(s)', 'OK']
|
|
||||||
\)
|
|
||||||
|
|
||||||
function! s:CreateCountDict() abort
|
function! s:CreateCountDict() abort
|
||||||
" Keys 0 and 1 are for backwards compatibility.
|
" Keys 0 and 1 are for backwards compatibility.
|
||||||
" The count object used to be a List of [error_count, warning_count].
|
" The count object used to be a List of [error_count, warning_count].
|
||||||
@@ -76,47 +68,3 @@ function! ale#statusline#Count(buffer) abort
|
|||||||
" The Dictionary is copied here before exposing it to other plugins.
|
" The Dictionary is copied here before exposing it to other plugins.
|
||||||
return copy(s:GetCounts(a:buffer))
|
return copy(s:GetCounts(a:buffer))
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" This is the historical format setting which could be configured before.
|
|
||||||
function! s:StatusForListFormat() abort
|
|
||||||
let [l:error_format, l:warning_format, l:no_errors] = g:ale_statusline_format
|
|
||||||
let l:counts = s:GetCounts(bufnr(''))
|
|
||||||
|
|
||||||
" Build strings based on user formatting preferences.
|
|
||||||
let l:errors = l:counts[0] ? printf(l:error_format, l:counts[0]) : ''
|
|
||||||
let l:warnings = l:counts[1] ? printf(l:warning_format, l:counts[1]) : ''
|
|
||||||
|
|
||||||
" Different formats based on the combination of errors and warnings.
|
|
||||||
if empty(l:errors) && empty(l:warnings)
|
|
||||||
let l:res = l:no_errors
|
|
||||||
elseif !empty(l:errors) && !empty(l:warnings)
|
|
||||||
let l:res = printf('%s %s', l:errors, l:warnings)
|
|
||||||
else
|
|
||||||
let l:res = empty(l:errors) ? l:warnings : l:errors
|
|
||||||
endif
|
|
||||||
|
|
||||||
return l:res
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
"
|
|
||||||
" Returns a formatted string that can be integrated in the statusline.
|
|
||||||
"
|
|
||||||
" This function is deprecated, and should not be used. Use the airline plugin
|
|
||||||
" instead, or write your own status function with ale#statusline#Count()
|
|
||||||
function! ale#statusline#Status() abort
|
|
||||||
if !get(g:, 'ale_deprecation_ale_statusline_status', 0)
|
|
||||||
execute 'echom ''ale#statusline#Status() is deprecated, use ale#statusline#Count() to write your own function.'''
|
|
||||||
let g:ale_deprecation_ale_statusline_status = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !exists('g:ale_statusline_format')
|
|
||||||
return 'OK'
|
|
||||||
endif
|
|
||||||
|
|
||||||
if type(g:ale_statusline_format) == type([])
|
|
||||||
return s:StatusForListFormat()
|
|
||||||
endif
|
|
||||||
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ function! ale#toggle#Toggle() abort
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#autocmd#InitAuGroups()
|
call ale#events#Init()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#toggle#Enable() abort
|
function! ale#toggle#Enable() abort
|
||||||
|
|||||||
@@ -17,11 +17,18 @@ endfunction
|
|||||||
" but NeoVim does. Small messages can be echoed in Vim 8, and larger messages
|
" but NeoVim does. Small messages can be echoed in Vim 8, and larger messages
|
||||||
" have to be shown in preview windows.
|
" have to be shown in preview windows.
|
||||||
function! ale#util#ShowMessage(string) abort
|
function! ale#util#ShowMessage(string) abort
|
||||||
|
if !has('nvim')
|
||||||
|
call ale#preview#CloseIfTypeMatches('ale-preview.message')
|
||||||
|
endif
|
||||||
|
|
||||||
" We have to assume the user is using a monospace font.
|
" We have to assume the user is using a monospace font.
|
||||||
if has('nvim') || (a:string !~? "\n" && len(a:string) < &columns)
|
if has('nvim') || (a:string !~? "\n" && len(a:string) < &columns)
|
||||||
execute 'echo a:string'
|
execute 'echo a:string'
|
||||||
else
|
else
|
||||||
call ale#preview#Show(split(a:string, "\n"))
|
call ale#preview#Show(split(a:string, "\n"), {
|
||||||
|
\ 'filetype': 'ale-preview.message',
|
||||||
|
\ 'stay_here': 1,
|
||||||
|
\})
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -39,6 +46,33 @@ if !exists('g:ale#util#nul_file')
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Given a job, a buffered line of data, a list of parts of lines, a mode data
|
||||||
|
" is being read in, and a callback, join the lines of output for a NeoVim job
|
||||||
|
" or socket together, and call the callback with the joined output.
|
||||||
|
"
|
||||||
|
" Note that jobs and IDs are the same thing on NeoVim.
|
||||||
|
function! ale#util#JoinNeovimOutput(job, last_line, data, mode, callback) abort
|
||||||
|
if a:mode is# 'raw'
|
||||||
|
call a:callback(a:job, join(a:data, "\n"))
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:lines = a:data[:-2]
|
||||||
|
|
||||||
|
if len(a:data) > 1
|
||||||
|
let l:lines[0] = a:last_line . l:lines[0]
|
||||||
|
let l:new_last_line = a:data[-1]
|
||||||
|
else
|
||||||
|
let l:new_last_line = a:last_line . get(a:data, 0, '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
for l:line in l:lines
|
||||||
|
call a:callback(a:job, l:line)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:new_last_line
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Return the number of lines for a given buffer.
|
" Return the number of lines for a given buffer.
|
||||||
function! ale#util#GetLineCount(buffer) abort
|
function! ale#util#GetLineCount(buffer) abort
|
||||||
return len(getbufline(a:buffer, 1, '$'))
|
return len(getbufline(a:buffer, 1, '$'))
|
||||||
@@ -56,8 +90,11 @@ function! ale#util#Open(filename, line, column, options) abort
|
|||||||
if get(a:options, 'open_in_tab', 0)
|
if get(a:options, 'open_in_tab', 0)
|
||||||
call ale#util#Execute('tabedit ' . fnameescape(a:filename))
|
call ale#util#Execute('tabedit ' . fnameescape(a:filename))
|
||||||
else
|
else
|
||||||
|
" Open another file only if we need to.
|
||||||
|
if bufnr(a:filename) isnot bufnr('')
|
||||||
call ale#util#Execute('edit ' . fnameescape(a:filename))
|
call ale#util#Execute('edit ' . fnameescape(a:filename))
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
call cursor(a:line, a:column)
|
call cursor(a:line, a:column)
|
||||||
endfunction
|
endfunction
|
||||||
@@ -231,9 +268,8 @@ endfunction
|
|||||||
" See :help sandbox
|
" See :help sandbox
|
||||||
function! ale#util#InSandbox() abort
|
function! ale#util#InSandbox() abort
|
||||||
try
|
try
|
||||||
function! s:SandboxCheck() abort
|
let &equalprg=&equalprg
|
||||||
endfunction
|
catch /E48/
|
||||||
catch /^Vim\%((\a\+)\)\=:E48/
|
|
||||||
" E48 is the sandbox error.
|
" E48 is the sandbox error.
|
||||||
return 1
|
return 1
|
||||||
endtry
|
endtry
|
||||||
@@ -241,14 +277,23 @@ function! ale#util#InSandbox() abort
|
|||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Get the number of milliseconds since some vague, but consistent, point in
|
function! ale#util#Tempname() abort
|
||||||
" the past.
|
let l:clear_tempdir = 0
|
||||||
"
|
|
||||||
" This function can be used for timing execution, etc.
|
if exists('$TMPDIR') && empty($TMPDIR)
|
||||||
"
|
let l:clear_tempdir = 1
|
||||||
" The time will be returned as a Number.
|
let $TMPDIR = '/tmp'
|
||||||
function! ale#util#ClockMilliseconds() abort
|
endif
|
||||||
return float2nr(reltimefloat(reltime()) * 1000)
|
|
||||||
|
try
|
||||||
|
let l:name = tempname() " no-custom-checks
|
||||||
|
finally
|
||||||
|
if l:clear_tempdir
|
||||||
|
let $TMPDIR = ''
|
||||||
|
endif
|
||||||
|
endtry
|
||||||
|
|
||||||
|
return l:name
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Given a single line, or a List of lines, and a single pattern, or a List
|
" Given a single line, or a List of lines, and a single pattern, or a List
|
||||||
|
|||||||
14
doc/ale-cloudformation.txt
Normal file
14
doc/ale-cloudformation.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
===============================================================================
|
||||||
|
ALE CloudFormation Integration *ale-cloudformation-options*
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
cfn-python-lint *ale-cloudformation-cfn-python-lint*
|
||||||
|
|
||||||
|
cfn-python-lint is a linter for AWS CloudFormation template file.
|
||||||
|
|
||||||
|
https://github.com/awslabs/cfn-python-lint
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
|
|
||||||
@@ -156,6 +156,26 @@ g:ale_cpp_cpplint_options *g:ale_cpp_cpplint_options*
|
|||||||
This variable can be changed to modify flags given to cpplint.
|
This variable can be changed to modify flags given to cpplint.
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
cquery *ale-cpp-cquery*
|
||||||
|
|
||||||
|
g:ale_cpp_cquery_executable *g:ale_cpp_cquery_executable*
|
||||||
|
*b:ale_cpp_cquery_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'cquery'`
|
||||||
|
|
||||||
|
This variable can be changed to use a different executable for cquery.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_cpp_cquery_cache_directory *g:ale_cpp_cquery_cache_directory*
|
||||||
|
*b:ale_cpp_cquery_cache_directory*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'~/.cache/cquery'`
|
||||||
|
|
||||||
|
This variable can be changed to decide which directory cquery uses for its
|
||||||
|
cache.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
flawfinder *ale-cpp-flawfinder*
|
flawfinder *ale-cpp-flawfinder*
|
||||||
|
|
||||||
|
|||||||
@@ -35,4 +35,37 @@ g:ale_dart_dartanalyzer_executable *g:ale_dart_dartanalyzer_executable*
|
|||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
dartfmt *ale-dart-dartfmt*
|
||||||
|
|
||||||
|
Installation
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Installing Dart should probably ensure that `dartfmt` is in your `$PATH`.
|
||||||
|
|
||||||
|
In case it is not, try to set the executable option to its absolute path. : >
|
||||||
|
" Set the executable path for dartfmt to the absolute path to it.
|
||||||
|
let g:ale_dart_dartfmt_executable = '/usr/lib/dart/bin/dartfmt'
|
||||||
|
>
|
||||||
|
|
||||||
|
Options
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
g:ale_dart_dartfmt_executable *g:ale_dart_dartfmt_executable*
|
||||||
|
*b:ale_dart_dartfmt_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable can be set to specify an absolute path to the
|
||||||
|
dartfmt executable (or to specify an alternate executable).
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_dart_dartfmt_options *g:ale_dart_dartfmt_options*
|
||||||
|
*b:ale_dart_dartfmt_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable can be set to pass additional options to the dartfmt fixer.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
|
|||||||
226
doc/ale-development.txt
Normal file
226
doc/ale-development.txt
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
*ale-development.txt* For Vim version 8.0.
|
||||||
|
*ale-development*
|
||||||
|
|
||||||
|
ALE Development Documentation
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
CONTENTS *ale-development-contents*
|
||||||
|
|
||||||
|
1. Introduction.........................|ale-development-introduction|
|
||||||
|
2. Design Goals.........................|ale-design-goals|
|
||||||
|
3. Coding Standards.....................|ale-coding-standards|
|
||||||
|
4. Testing ALE..........................|ale-development-tests|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
1. Introduction *ale-development-introduction*
|
||||||
|
|
||||||
|
This document contains helpful information for ALE developers, including
|
||||||
|
design goals, information on how to run the tests, coding standards, and so
|
||||||
|
on. You should read this document if you want to get involved with ALE
|
||||||
|
development.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
2. Design Goals *ale-design-goals*
|
||||||
|
|
||||||
|
This section lists design goals for ALE, in no particular order. They are as
|
||||||
|
follows.
|
||||||
|
|
||||||
|
ALE code should be almost 100% VimL. This makes the plugin as portable as
|
||||||
|
possible.
|
||||||
|
|
||||||
|
ALE should run without needing any other plugins to be installed, to make
|
||||||
|
installation simple. ALE can integrate with other plugins for more advanced
|
||||||
|
functionality, non-essential functionality, or improving on basic first party
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
ALE should check files with as many tools as possible by default, except where
|
||||||
|
they cause security issues or make excessive use of resources on modern
|
||||||
|
machines.
|
||||||
|
|
||||||
|
ALE should be free of breaking changes to the public API, which is comprised of
|
||||||
|
documented functions and options, until a major version is planned. Breaking
|
||||||
|
changes should be preceded by a deprecation phase complete with warnings.
|
||||||
|
Changes required for security may be an exception.
|
||||||
|
|
||||||
|
ALE supports Vim 8 and above, and NeoVim 0.2.0 or newer. These are the
|
||||||
|
earliest versions of Vim and NeoVim which support |job|, |timer|, |closure|,
|
||||||
|
and |lambda| features. All ALE code should be written so it is compatible with
|
||||||
|
these versions of Vim, or with version checks so particular features can
|
||||||
|
degrade or fail gracefully.
|
||||||
|
|
||||||
|
Just about everything should be documented and covered with tests.
|
||||||
|
|
||||||
|
By and large, people shouldn't pay for the functionality they don't use. Care
|
||||||
|
should be taken when adding new features, so supporting new features doesn't
|
||||||
|
degrade the general performance of anything ALE does.
|
||||||
|
|
||||||
|
LSP support will become more important as time goes on. ALE should provide
|
||||||
|
better support for LSP features as time goes on.
|
||||||
|
|
||||||
|
When merging pull requests, you should respond with `Cheers! :beers:`, purely
|
||||||
|
for comedy value.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
3. Coding Standards *ale-coding-standards*
|
||||||
|
|
||||||
|
The following general coding standards should be adhered to for Vim code.
|
||||||
|
|
||||||
|
* Check your Vim code with `Vint` and do everything it says. ALE will check
|
||||||
|
your Vim code with Vint automatically. See: https://github.com/Kuniwak/vint
|
||||||
|
Read ALE's `Dockerfile` to see which version of `Vint` it uses.
|
||||||
|
* Try to write descriptive and concise names for variables and functions.
|
||||||
|
Names shouldn't be too short or too long. Think about others reading your
|
||||||
|
code later on.
|
||||||
|
* Use `snake_case` names for variables and arguments, and `PascalCase` names
|
||||||
|
for functions. Prefix every variable name with its scope. (`l:`, `g:`, etc.)
|
||||||
|
* Try to keep lines no longer than 80 characters, but this isn't an absolute
|
||||||
|
requirement.
|
||||||
|
* Use 4 spaces for every level of indentation in Vim code.
|
||||||
|
* Add a blank line before every `function`, `if`, `for`, `while`, or `return`,
|
||||||
|
which doesn't start a new level of indentation. This makes the logic in
|
||||||
|
your code easier to follow.
|
||||||
|
* End every file with a trailing newline character, but not with extra blank
|
||||||
|
lines. Remove trailing whitespace from the ends of lines.
|
||||||
|
* Write the full names of commands instead of abbreviations. For example, write
|
||||||
|
`function` instead of `func`, and `endif` instead of `end`.
|
||||||
|
* Write functions with `!`, so files can be reloaded. Use the |abort| keyword
|
||||||
|
for all functions, so functions exit on the first error.
|
||||||
|
* Make sure to credit yourself in files you have authored with `Author:`
|
||||||
|
and `Description:` comments.
|
||||||
|
|
||||||
|
In addition to the above general guidelines for the style of your code, you
|
||||||
|
should also follow some additional rules designed to prevent mistakes. Some of
|
||||||
|
these are reported with ALE's `custom-linting-rules` script. See
|
||||||
|
|ale-development-tests|.
|
||||||
|
|
||||||
|
* Don't leave stray `:echo` lines in code. Use `execute 'echo' ...` if you must
|
||||||
|
echo something.
|
||||||
|
* For strings use |is#| instead of |==#|, `is?` instead of `==?`, `isnot#`
|
||||||
|
instead of `!=#`, and `isnot?` instead of `!=?`. This is because `'x' ==# 0`
|
||||||
|
returns 1, while `'x' is# 0` returns 0, so you will experience fewer issues
|
||||||
|
when numbers are compared with strings. `is` and `isnot` also do not throw
|
||||||
|
errors when other objects like List or Dictionaries are compared with
|
||||||
|
strings.
|
||||||
|
* Don't use the `getcwd()` function in the ALE codebase. Most of ALE's code
|
||||||
|
runs from asynchronous callback functions, and these functions can execute
|
||||||
|
from essentially random buffers. Therefore, the `getcwd()` output is
|
||||||
|
useless. Use `expand('#' . a:buffer . ':p:h')` instead. Don't use
|
||||||
|
`expand('%...')` for the same reason.
|
||||||
|
* Don't use the `simplify()` function. It doesn't simplify paths enough. Use
|
||||||
|
`ale#path#Simplify()` instead.
|
||||||
|
* Don't use the `shellescape()` function. It doesn't escape arguments properly
|
||||||
|
on Windows. Use `ale#Escape()` instead, which will avoid escaping where it
|
||||||
|
isn't needed, and generally escape arguments better on Windows.
|
||||||
|
* Don't use the `tempname()` function. It doesn't work when `$TMPDIR` isn't
|
||||||
|
set. Use `ale#util#Tempname()` instead, which temporarily sets `$TMPDIR`
|
||||||
|
appropriately where needed.
|
||||||
|
|
||||||
|
Apply the following guidelines when writing Vader test files.
|
||||||
|
|
||||||
|
* Use 2 spaces for Vader test files, instead of the 4 spaces for Vim files.
|
||||||
|
* If you write `Before` and `After` blocks, you should typically write them at
|
||||||
|
the top of the file, so they run for all tests. There may be some tests
|
||||||
|
where it make sense to modify the `Before` and `After` code part of the way
|
||||||
|
through the file.
|
||||||
|
* If you modify any settings or global variables, reset them in `After`
|
||||||
|
blocks. The Vader `Save` and `Restore` commands can be useful for this
|
||||||
|
purpose.
|
||||||
|
* If you load or define linters in tests, write `call ale#linter#Reset()` in
|
||||||
|
an `After` block.
|
||||||
|
* Just write `Execute` blocks for Vader tests, and don't bother writing `Then`
|
||||||
|
blocks. `Then` blocks execute after `After` blocks in older versions, and
|
||||||
|
that can be confusing.
|
||||||
|
|
||||||
|
Apply the following rules when writing Bash scripts.
|
||||||
|
|
||||||
|
* Run `shellcheck`, and do everything it says.
|
||||||
|
See: https://github.com/koalaman/shellcheck
|
||||||
|
* Try to write scripts so they will run on Linux, BSD, or Mac OSX.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
4. Testing ALE *ale-development-tests*
|
||||||
|
|
||||||
|
ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE
|
||||||
|
runs tests with the following versions of Vim in the following environments.
|
||||||
|
|
||||||
|
1. Vim 8.0.0027 on Linux via Travis CI.
|
||||||
|
2. NeoVim 0.2.0 on Linux via Travis CI.
|
||||||
|
3. NeoVim 0.3.0 on Linux via Travis CI.
|
||||||
|
4. Vim 8 (stable builds) on Windows via AppVeyor.
|
||||||
|
|
||||||
|
If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs
|
||||||
|
tests by installing Docker and running the `run-tests` script. Follow the
|
||||||
|
instructions on the Docker site for installing Docker.
|
||||||
|
See: https://docs.docker.com/install/
|
||||||
|
|
||||||
|
NOTE: Don't forget to add your user to the `docker` group on Linux, or Docker
|
||||||
|
just won't work. See: https://docs.docker.com/install/linux/linux-postinstall/
|
||||||
|
|
||||||
|
If you run simply `./run-tests` from the ALE repository root directory, the
|
||||||
|
latest Docker image for tests will be downloaded if needed, and the script
|
||||||
|
will run all of the tests in Vader, Vint checks, and several Bash scripts for
|
||||||
|
finding extra issues. Run `./run-tests --help` to see all of the options the
|
||||||
|
script supports. Note that the script supports selecting particular test files.
|
||||||
|
|
||||||
|
Generally write tests for any changes you make. The following types of tests
|
||||||
|
are recommended for the following types of code.
|
||||||
|
|
||||||
|
* New/edited error handler callbacks -> Write tests in `test/handler`
|
||||||
|
* New/edited command callbacks -> Write tests in `test/command_callback`
|
||||||
|
* New/edited fixer functions -> Write tests in `test/fixers`
|
||||||
|
|
||||||
|
Look at existing tests in the codebase for examples of how to write tests.
|
||||||
|
Refer to the Vader documentation for general information on how to write Vader
|
||||||
|
tests: https://github.com/junegunn/vader.vim
|
||||||
|
|
||||||
|
When you add new linters or fixers, make sure to add them into the table in
|
||||||
|
the README, and also into the |ale-support| list in the main help file. If you
|
||||||
|
forget to keep them both in sync, you should see an error like the following
|
||||||
|
in Travis CI. >
|
||||||
|
|
||||||
|
========================================
|
||||||
|
diff README.md and doc/ale.txt tables
|
||||||
|
========================================
|
||||||
|
Differences follow:
|
||||||
|
|
||||||
|
--- /tmp/readme.qLjNhJdB 2018-07-01 16:29:55.590331972 +0100
|
||||||
|
+++ /tmp/doc.dAi8zfVE 2018-07-01 16:29:55.582331877 +0100
|
||||||
|
@@ -1 +1 @@
|
||||||
|
- ASM: gcc, foobar
|
||||||
|
+ ASM: gcc
|
||||||
|
<
|
||||||
|
Make sure to list documentation entries for linters and fixers in individual
|
||||||
|
help files in the table of contents, and to align help tags to the right
|
||||||
|
margin. For example, if you add a heading for an `aardvark` tool to
|
||||||
|
`ale-python.txt` with a badly aligned doc tag, you will see errors like so. >
|
||||||
|
|
||||||
|
========================================
|
||||||
|
Look for badly aligned doc tags
|
||||||
|
========================================
|
||||||
|
Badly aligned tags follow:
|
||||||
|
|
||||||
|
doc/ale-python.txt:aardvark ...
|
||||||
|
========================================
|
||||||
|
Look for table of contents issues
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Check for bad ToC sorting:
|
||||||
|
|
||||||
|
Check for mismatched ToC and headings:
|
||||||
|
|
||||||
|
--- /tmp/table-of-contents.mwCFOgSI 2018-07-01 16:33:25.068811878 +0100
|
||||||
|
+++ /tmp/headings.L4WU0hsO 2018-07-01 16:33:25.076811973 +0100
|
||||||
|
@@ -168,6 +168,7 @@
|
||||||
|
pyrex (cython), ale-pyrex-options
|
||||||
|
cython, ale-pyrex-cython
|
||||||
|
python, ale-python-options
|
||||||
|
+ aardvark, ale-python-aardvark
|
||||||
|
autopep8, ale-python-autopep8
|
||||||
|
black, ale-python-black
|
||||||
|
flake8, ale-python-flake8
|
||||||
|
<
|
||||||
|
Make sure to make the table of contents match the headings, and to keep the
|
||||||
|
doc tags on the right margin.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
@@ -19,13 +19,15 @@ g:ale_gitcommit_gitlint_options *g:ale_gitcommit_gitlint_options*
|
|||||||
Default: `''`
|
Default: `''`
|
||||||
|
|
||||||
This variable can be changed to add command-line arguments to the gitlint
|
This variable can be changed to add command-line arguments to the gitlint
|
||||||
invocation.
|
invocation. For example, you can specify the path to a configuration file. >
|
||||||
|
|
||||||
For example, to dinamically set the gitlint configuration file path, you
|
|
||||||
may want to set >
|
|
||||||
|
|
||||||
let g:ale_gitcommit_gitlint_options = '-C /home/user/.config/gitlint.ini'
|
let g:ale_gitcommit_gitlint_options = '-C /home/user/.config/gitlint.ini'
|
||||||
<
|
<
|
||||||
|
You can also disable particular error codes using this option. For example,
|
||||||
|
you can ignore errors for git commits with a missing body. >
|
||||||
|
|
||||||
|
let g:ale_gitcommit_gitlint_options = '--ignore B6'
|
||||||
|
<
|
||||||
|
|
||||||
g:ale_gitcommit_gitlint_use_global *g:ale_gitcommit_gitlint_use_global*
|
g:ale_gitcommit_gitlint_use_global *g:ale_gitcommit_gitlint_use_global*
|
||||||
*b:ale_gitcommit_gitlint_use_global*
|
*b:ale_gitcommit_gitlint_use_global*
|
||||||
|
|||||||
@@ -71,6 +71,14 @@ g:ale_html_tidy_options *g:ale_html_tidy_options*
|
|||||||
(mac), sjis (shiftjis), utf-16le, utf-16, utf-8
|
(mac), sjis (shiftjis), utf-16le, utf-16, utf-8
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_html_tidy_use_global *g:html_tidy_use_global*
|
||||||
|
|
||||||
|
Type: |Number|
|
||||||
|
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
write-good *ale-html-write-good*
|
write-good *ale-html-write-good*
|
||||||
|
|
||||||
|
|||||||
25
doc/ale-pyrex.txt
Normal file
25
doc/ale-pyrex.txt
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
===============================================================================
|
||||||
|
ALE Pyrex (Cython) Integration *ale-pyrex-options*
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
cython *ale-pyrex-cython*
|
||||||
|
|
||||||
|
g:ale_pyrex_cython_executable *g:ale_pyrex_cython_executable*
|
||||||
|
*b:ale_pyrex_cython_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'cython'`
|
||||||
|
|
||||||
|
This variable can be changed to use a different executable for cython.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_pyrex_cython_options *g:ale_pyrex_cython_options*
|
||||||
|
*b:ale_pyrex_cython_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'--warning-extra --warning-errors'`
|
||||||
|
|
||||||
|
This variable can be changed to modify flags given to cython.
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
@@ -100,7 +100,8 @@ g:ale_python_flake8_executable *g:ale_python_flake8_executable*
|
|||||||
Type: |String|
|
Type: |String|
|
||||||
Default: `'flake8'`
|
Default: `'flake8'`
|
||||||
|
|
||||||
This variable can be changed to modify the executable used for flake8.
|
This variable can be changed to modify the executable used for flake8. Set
|
||||||
|
this to `'pipenv'` to invoke `'pipenv` `run` `flake8'`.
|
||||||
|
|
||||||
|
|
||||||
g:ale_python_flake8_options *g:ale_python_flake8_options*
|
g:ale_python_flake8_options *g:ale_python_flake8_options*
|
||||||
@@ -169,6 +170,8 @@ g:ale_python_mypy_executable *g:ale_python_mypy_executable*
|
|||||||
|
|
||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
Set this to `'pipenv'` to invoke `'pipenv` `run` `mypy'`.
|
||||||
|
|
||||||
g:ale_python_mypy_ignore_invalid_syntax
|
g:ale_python_mypy_ignore_invalid_syntax
|
||||||
*g:ale_python_mypy_ignore_invalid_syntax*
|
*g:ale_python_mypy_ignore_invalid_syntax*
|
||||||
*b:ale_python_mypy_ignore_invalid_syntax*
|
*b:ale_python_mypy_ignore_invalid_syntax*
|
||||||
@@ -207,6 +210,8 @@ g:ale_python_prospector_executable *g:ale_python_prospector_executable*
|
|||||||
|
|
||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
Set this to `'pipenv'` to invoke `'pipenv` `run` `prospector'`.
|
||||||
|
|
||||||
|
|
||||||
g:ale_python_prospector_options *g:ale_python_prospector_options*
|
g:ale_python_prospector_options *g:ale_python_prospector_options*
|
||||||
*b:ale_python_prospector_options*
|
*b:ale_python_prospector_options*
|
||||||
@@ -248,6 +253,8 @@ g:ale_python_pycodestyle_executable *g:ale_python_pycodestyle_executable*
|
|||||||
|
|
||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pycodestyle'`.
|
||||||
|
|
||||||
|
|
||||||
g:ale_python_pycodestyle_options *g:ale_python_pycodestyle_options*
|
g:ale_python_pycodestyle_options *g:ale_python_pycodestyle_options*
|
||||||
*b:ale_python_pycodestyle_options*
|
*b:ale_python_pycodestyle_options*
|
||||||
@@ -266,6 +273,20 @@ g:ale_python_pycodestyle_use_global *g:ale_python_pycodestyle_use_global*
|
|||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
pyflakes *ale-python-pyflakes*
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_python_pyflakes_executable *g:ale_python_pyflakes_executable*
|
||||||
|
*b:ale_python_pyflakes_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'pyflakes'`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pyflakes'`.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
pylint *ale-python-pylint*
|
pylint *ale-python-pylint*
|
||||||
|
|
||||||
@@ -287,6 +308,8 @@ g:ale_python_pylint_executable *g:ale_python_pylint_executable*
|
|||||||
|
|
||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pylint'`.
|
||||||
|
|
||||||
|
|
||||||
g:ale_python_pylint_options *g:ale_python_pylint_options*
|
g:ale_python_pylint_options *g:ale_python_pylint_options*
|
||||||
*b:ale_python_pylint_options*
|
*b:ale_python_pylint_options*
|
||||||
@@ -329,6 +352,8 @@ g:ale_python_pyls_executable *g:ale_python_pyls_executable*
|
|||||||
|
|
||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pyls'`.
|
||||||
|
|
||||||
|
|
||||||
g:ale_python_pyls_use_global *g:ale_python_pyls_use_global*
|
g:ale_python_pyls_use_global *g:ale_python_pyls_use_global*
|
||||||
*b:ale_python_pyls_use_global*
|
*b:ale_python_pyls_use_global*
|
||||||
@@ -338,6 +363,30 @@ g:ale_python_pyls_use_global *g:ale_python_pyls_use_global*
|
|||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
pyre *ale-python-pyre*
|
||||||
|
|
||||||
|
`pyre` will be run from a detected project root, per |ale-python-root|.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_python_pyre_executable *g:ale_python_pyre_executable*
|
||||||
|
*b:ale_python_pyre_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'pyre'`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pyre'`.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_python_pyre_use_global *g:ale_python_pyre_use_global*
|
||||||
|
*b:ale_python_pyre_use_global*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
yapf *ale-python-yapf*
|
yapf *ale-python-yapf*
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,26 @@ g:ale_rust_cargo_check_all_targets *g:ale_rust_cargo_check_all_targets*
|
|||||||
is used. See |g:ale_rust_cargo_use_check|,
|
is used. See |g:ale_rust_cargo_use_check|,
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_rust_cargo_check_tests *g:ale_rust_cargo_check_tests*
|
||||||
|
*b:ale_rust_cargo_check_tests*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `0`
|
||||||
|
|
||||||
|
When set to `1`, ALE will set the `--tests` option when `cargo check`
|
||||||
|
is used. This allows for linting of tests which are normally excluded.
|
||||||
|
See |g:ale_rust_cargo_use_check|,
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_rust_cargo_check_examples *g:ale_rust_cargo_check_examples*
|
||||||
|
*b:ale_rust_cargo_check_examples*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `0`
|
||||||
|
|
||||||
|
When set to `1`, ALE will set the `--examples` option when `cargo check`
|
||||||
|
is used. This allows for linting of examples which are normally excluded.
|
||||||
|
See |g:ale_rust_cargo_use_check|,
|
||||||
|
|
||||||
|
|
||||||
g:ale_rust_cargo_default_feature_behavior
|
g:ale_rust_cargo_default_feature_behavior
|
||||||
*g:ale_rust_cargo_default_feature_behavior*
|
*g:ale_rust_cargo_default_feature_behavior*
|
||||||
*b:ale_rust_cargo_default_feature_behavior*
|
*b:ale_rust_cargo_default_feature_behavior*
|
||||||
@@ -88,6 +108,15 @@ g:ale_rust_cargo_include_features *g:ale_rust_cargo_include_features*
|
|||||||
When defined, ALE will set the `--features` option when invoking `cargo` to
|
When defined, ALE will set the `--features` option when invoking `cargo` to
|
||||||
perform the lint check. See |g:ale_rust_cargo_default_feature_behavior|.
|
perform the lint check. See |g:ale_rust_cargo_default_feature_behavior|.
|
||||||
|
|
||||||
|
g:ale_rust_cargo_avoid_whole_workspace *g:ale_rust_cargo_avoid_whole_workspace*
|
||||||
|
*b:ale_rust_cargo_avoid_whole_workspace*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `1`
|
||||||
|
|
||||||
|
When set to 1, and ALE is used to edit a crate that is part of a Cargo
|
||||||
|
workspace, avoid building the entire entire workspace by invoking
|
||||||
|
`cargo` directly in the crate's directory. Otherwise, behave as usual.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
rls *ale-rust-rls*
|
rls *ale-rust-rls*
|
||||||
|
|||||||
@@ -2,6 +2,31 @@
|
|||||||
ALE Scala Integration *ale-scala-options*
|
ALE Scala Integration *ale-scala-options*
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
scalafmt *ale-scala-scalafmt*
|
||||||
|
|
||||||
|
If Nailgun is used, override `g:ale_scala_scalafmt_executable` like so: >
|
||||||
|
let g:ale_scala_scalafmt_executable = 'ng'
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_scala_scalafmt_executable *g:ale_scala_scalafmt_executable*
|
||||||
|
*b:ale_scala_scalafmt_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'scalafmt'`
|
||||||
|
|
||||||
|
Override the invoked `scalafmt` binary. This is useful for running `scalafmt`
|
||||||
|
with Nailgun.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_scala_scalafmt_options *g:ale_scala_scalafmt_options*
|
||||||
|
*b:ale_scala_scalafmt_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
A string containing additional options to pass to `'scalafmt'`, or
|
||||||
|
`'ng scalafmt'` if Nailgun is used.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
scalastyle *ale-scala-scalastyle*
|
scalastyle *ale-scala-scalastyle*
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,25 @@
|
|||||||
ALE Shell Integration *ale-sh-options*
|
ALE Shell Integration *ale-sh-options*
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
sh-language-server *ale-sh-language-server*
|
||||||
|
|
||||||
|
g:ale_sh_language_server_executable *g:ale_sh_language_server_executable*
|
||||||
|
*b:ale_sh_language_server_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'bash-language-server'`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_sh_language_server_use_global *g:ale_sh_language_server_use_global*
|
||||||
|
*b:ale_sh_language_server_use_global*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
shell *ale-sh-shell*
|
shell *ale-sh-shell*
|
||||||
|
|
||||||
|
|||||||
123
doc/ale.txt
123
doc/ale.txt
@@ -35,6 +35,8 @@ CONTENTS *ale-contents*
|
|||||||
foodcritic..........................|ale-chef-foodcritic|
|
foodcritic..........................|ale-chef-foodcritic|
|
||||||
clojure...............................|ale-clojure-options|
|
clojure...............................|ale-clojure-options|
|
||||||
joker...............................|ale-clojure-joker|
|
joker...............................|ale-clojure-joker|
|
||||||
|
cloudformation........................|ale-cloudformation-options|
|
||||||
|
cfn-python-lint.....................|ale-cloudformation-cfn-python-lint|
|
||||||
cmake.................................|ale-cmake-options|
|
cmake.................................|ale-cmake-options|
|
||||||
cmakelint...........................|ale-cmake-cmakelint|
|
cmakelint...........................|ale-cmake-cmakelint|
|
||||||
cpp...................................|ale-cpp-options|
|
cpp...................................|ale-cpp-options|
|
||||||
@@ -44,6 +46,7 @@ CONTENTS *ale-contents*
|
|||||||
clangtidy...........................|ale-cpp-clangtidy|
|
clangtidy...........................|ale-cpp-clangtidy|
|
||||||
cppcheck............................|ale-cpp-cppcheck|
|
cppcheck............................|ale-cpp-cppcheck|
|
||||||
cpplint.............................|ale-cpp-cpplint|
|
cpplint.............................|ale-cpp-cpplint|
|
||||||
|
cquery..............................|ale-cpp-cquery|
|
||||||
flawfinder..........................|ale-cpp-flawfinder|
|
flawfinder..........................|ale-cpp-flawfinder|
|
||||||
gcc.................................|ale-cpp-gcc|
|
gcc.................................|ale-cpp-gcc|
|
||||||
c#....................................|ale-cs-options|
|
c#....................................|ale-cs-options|
|
||||||
@@ -56,6 +59,7 @@ CONTENTS *ale-contents*
|
|||||||
nvcc................................|ale-cuda-nvcc|
|
nvcc................................|ale-cuda-nvcc|
|
||||||
dart..................................|ale-dart-options|
|
dart..................................|ale-dart-options|
|
||||||
dartanalyzer........................|ale-dart-dartanalyzer|
|
dartanalyzer........................|ale-dart-dartanalyzer|
|
||||||
|
dartfmt.............................|ale-dart-dartfmt|
|
||||||
dockerfile............................|ale-dockerfile-options|
|
dockerfile............................|ale-dockerfile-options|
|
||||||
hadolint............................|ale-dockerfile-hadolint|
|
hadolint............................|ale-dockerfile-hadolint|
|
||||||
elixir................................|ale-elixir-options|
|
elixir................................|ale-elixir-options|
|
||||||
@@ -182,6 +186,8 @@ CONTENTS *ale-contents*
|
|||||||
puglint.............................|ale-pug-puglint|
|
puglint.............................|ale-pug-puglint|
|
||||||
puppet................................|ale-puppet-options|
|
puppet................................|ale-puppet-options|
|
||||||
puppetlint..........................|ale-puppet-puppetlint|
|
puppetlint..........................|ale-puppet-puppetlint|
|
||||||
|
pyrex (cython)........................|ale-pyrex-options|
|
||||||
|
cython..............................|ale-pyrex-cython|
|
||||||
python................................|ale-python-options|
|
python................................|ale-python-options|
|
||||||
autopep8............................|ale-python-autopep8|
|
autopep8............................|ale-python-autopep8|
|
||||||
black...............................|ale-python-black|
|
black...............................|ale-python-black|
|
||||||
@@ -190,8 +196,10 @@ CONTENTS *ale-contents*
|
|||||||
mypy................................|ale-python-mypy|
|
mypy................................|ale-python-mypy|
|
||||||
prospector..........................|ale-python-prospector|
|
prospector..........................|ale-python-prospector|
|
||||||
pycodestyle.........................|ale-python-pycodestyle|
|
pycodestyle.........................|ale-python-pycodestyle|
|
||||||
|
pyflakes............................|ale-python-pyflakes|
|
||||||
pylint..............................|ale-python-pylint|
|
pylint..............................|ale-python-pylint|
|
||||||
pyls................................|ale-python-pyls|
|
pyls................................|ale-python-pyls|
|
||||||
|
pyre................................|ale-python-pyre|
|
||||||
yapf................................|ale-python-yapf|
|
yapf................................|ale-python-yapf|
|
||||||
qml...................................|ale-qml-options|
|
qml...................................|ale-qml-options|
|
||||||
qmlfmt..............................|ale-qml-qmlfmt|
|
qmlfmt..............................|ale-qml-qmlfmt|
|
||||||
@@ -218,11 +226,13 @@ CONTENTS *ale-contents*
|
|||||||
sass..................................|ale-sass-options|
|
sass..................................|ale-sass-options|
|
||||||
stylelint...........................|ale-sass-stylelint|
|
stylelint...........................|ale-sass-stylelint|
|
||||||
scala.................................|ale-scala-options|
|
scala.................................|ale-scala-options|
|
||||||
|
scalafmt............................|ale-scala-scalafmt|
|
||||||
scalastyle..........................|ale-scala-scalastyle|
|
scalastyle..........................|ale-scala-scalastyle|
|
||||||
scss..................................|ale-scss-options|
|
scss..................................|ale-scss-options|
|
||||||
prettier............................|ale-scss-prettier|
|
prettier............................|ale-scss-prettier|
|
||||||
stylelint...........................|ale-scss-stylelint|
|
stylelint...........................|ale-scss-stylelint|
|
||||||
sh....................................|ale-sh-options|
|
sh....................................|ale-sh-options|
|
||||||
|
sh-language-server..................|ale-sh-language-server|
|
||||||
shell...............................|ale-sh-shell|
|
shell...............................|ale-sh-shell|
|
||||||
shellcheck..........................|ale-sh-shellcheck|
|
shellcheck..........................|ale-sh-shellcheck|
|
||||||
shfmt...............................|ale-sh-shfmt|
|
shfmt...............................|ale-sh-shfmt|
|
||||||
@@ -299,6 +309,9 @@ control functionality used for checking for problems. Try using the
|
|||||||
|ALEFixSuggest| command for browsing tools that can be used to fix problems
|
|ALEFixSuggest| command for browsing tools that can be used to fix problems
|
||||||
for the current buffer.
|
for the current buffer.
|
||||||
|
|
||||||
|
If you are interested in contributing to the development of ALE, read the
|
||||||
|
developer documentation. See |ale-development|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
2. Supported Languages & Tools *ale-support*
|
2. Supported Languages & Tools *ale-support*
|
||||||
|
|
||||||
@@ -314,14 +327,15 @@ Notes:
|
|||||||
* API Blueprint: `drafter`
|
* API Blueprint: `drafter`
|
||||||
* AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good`
|
* AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good`
|
||||||
* Awk: `gawk`
|
* Awk: `gawk`
|
||||||
* Bash: `shell` (-n flag), `shellcheck`, `shfmt`
|
* Bash: `language-server`, `shell` (-n flag), `shellcheck`, `shfmt`
|
||||||
* Bourne Shell: `shell` (-n flag), `shellcheck`, `shfmt`
|
* Bourne Shell: `shell` (-n flag), `shellcheck`, `shfmt`
|
||||||
* C: `cppcheck`, `cpplint`!!, `clang`, `clangtidy`!!, `clang-format`, `flawfinder`, `gcc`
|
* C: `cppcheck`, `cpplint`!!, `clang`, `clangtidy`!!, `clang-format`, `flawfinder`, `gcc`
|
||||||
* C++ (filetype cpp): `clang`, `clangcheck`!!, `clangtidy`!!, `clang-format`, `cppcheck`, `cpplint`!!, `flawfinder`, `gcc`
|
* C++ (filetype cpp): `clang`, `clangcheck`!!, `clangtidy`!!, `clang-format`, `cppcheck`, `cpplint`!!, `cquery`, `flawfinder`, `gcc`
|
||||||
* CUDA: `nvcc`!!
|
* CUDA: `nvcc`!!
|
||||||
* C#: `mcs`, `mcsc`!!
|
* C#: `mcs`, `mcsc`!!
|
||||||
* Chef: `foodcritic`
|
* Chef: `foodcritic`
|
||||||
* Clojure: `joker`
|
* Clojure: `joker`
|
||||||
|
* CloudFormation: `cfn-python-lint`
|
||||||
* CMake: `cmakelint`
|
* CMake: `cmakelint`
|
||||||
* CoffeeScript: `coffee`, `coffeelint`
|
* CoffeeScript: `coffee`, `coffeelint`
|
||||||
* Crystal: `crystal`!!
|
* Crystal: `crystal`!!
|
||||||
@@ -330,9 +344,9 @@ Notes:
|
|||||||
* Cython (pyrex filetype): `cython`
|
* Cython (pyrex filetype): `cython`
|
||||||
* D: `dmd`
|
* D: `dmd`
|
||||||
* Dafny: `dafny`!!
|
* Dafny: `dafny`!!
|
||||||
* Dart: `dartanalyzer`!!, `language_server`
|
* Dart: `dartanalyzer`!!, `language_server`, dartfmt!!
|
||||||
* Dockerfile: `hadolint`
|
* Dockerfile: `hadolint`
|
||||||
* Elixir: `credo`, `dialyxir`, `dogma`!!
|
* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!
|
||||||
* Elm: `elm-format, elm-make`
|
* Elm: `elm-format, elm-make`
|
||||||
* Erb: `erb`, `erubi`, `erubis`
|
* Erb: `erb`, `erubi`, `erubis`
|
||||||
* Erlang: `erlc`, `SyntaxErl`
|
* Erlang: `erlc`, `SyntaxErl`
|
||||||
@@ -377,7 +391,7 @@ Notes:
|
|||||||
* proto: `protoc-gen-lint`
|
* proto: `protoc-gen-lint`
|
||||||
* Pug: `pug-lint`
|
* Pug: `pug-lint`
|
||||||
* Puppet: `puppet`, `puppet-lint`
|
* Puppet: `puppet`, `puppet-lint`
|
||||||
* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pyls`, `pylint`!!, `yapf`
|
* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pyls`, `pyre`, `pylint`!!, `yapf`
|
||||||
* QML: `qmlfmt`, `qmllint`
|
* QML: `qmlfmt`, `qmllint`
|
||||||
* R: `lintr`
|
* R: `lintr`
|
||||||
* ReasonML: `merlin`, `ols`, `refmt`
|
* ReasonML: `merlin`, `ols`, `refmt`
|
||||||
@@ -388,7 +402,7 @@ Notes:
|
|||||||
* Rust: `cargo`!!, `rls`, `rustc` (see |ale-integration-rust|), `rustfmt`
|
* Rust: `cargo`!!, `rls`, `rustc` (see |ale-integration-rust|), `rustfmt`
|
||||||
* SASS: `sass-lint`, `stylelint`
|
* SASS: `sass-lint`, `stylelint`
|
||||||
* SCSS: `prettier`, `sass-lint`, `scss-lint`, `stylelint`
|
* SCSS: `prettier`, `sass-lint`, `scss-lint`, `stylelint`
|
||||||
* Scala: `fsc`, `scalac`, `scalastyle`
|
* Scala: `fsc`, `scalac`, `scalafmt`, `scalastyle`
|
||||||
* Slim: `slim-lint`
|
* Slim: `slim-lint`
|
||||||
* SML: `smlnj`
|
* SML: `smlnj`
|
||||||
* Solidity: `solhint`, `solium`
|
* Solidity: `solhint`, `solium`
|
||||||
@@ -932,6 +946,14 @@ g:ale_fixers *g:ale_fixers*
|
|||||||
`b:ale_fixers` can be set to a |List| of callbacks instead, which can be
|
`b:ale_fixers` can be set to a |List| of callbacks instead, which can be
|
||||||
more convenient.
|
more convenient.
|
||||||
|
|
||||||
|
A special `'*'` key be used as a wildcard filetype for configuring fixers
|
||||||
|
for every other type of file. For example: >
|
||||||
|
|
||||||
|
" Fix Python files with 'bar'.
|
||||||
|
" Don't fix 'html' files.
|
||||||
|
" Fix everything else with 'foo'.
|
||||||
|
let g:ale_fixers = {'python': ['bar'], 'html': [], '*': ['foo']}
|
||||||
|
<
|
||||||
|
|
||||||
g:ale_fix_on_save *g:ale_fix_on_save*
|
g:ale_fix_on_save *g:ale_fix_on_save*
|
||||||
b:ale_fix_on_save *b:ale_fix_on_save*
|
b:ale_fix_on_save *b:ale_fix_on_save*
|
||||||
@@ -1111,6 +1133,7 @@ g:ale_linter_aliases *g:ale_linter_aliases*
|
|||||||
\ 'csh': 'sh',
|
\ 'csh': 'sh',
|
||||||
\ 'plaintex': 'tex',
|
\ 'plaintex': 'tex',
|
||||||
\ 'systemverilog': 'verilog',
|
\ 'systemverilog': 'verilog',
|
||||||
|
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
||||||
\ 'vimwiki': 'markdown',
|
\ 'vimwiki': 'markdown',
|
||||||
\ 'zsh': 'sh',
|
\ 'zsh': 'sh',
|
||||||
\}
|
\}
|
||||||
@@ -1216,6 +1239,32 @@ g:ale_linters_explicit *g:ale_linters_explicit*
|
|||||||
as possible, unless otherwise specified.
|
as possible, unless otherwise specified.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_linters_ignore *g:ale_linters_ignore*
|
||||||
|
*b:ale_linters_ignore*
|
||||||
|
|
||||||
|
Type: |Dictionary| or |List|
|
||||||
|
Default: `{}`
|
||||||
|
|
||||||
|
Linters to ignore. Commands for ignored linters will not be run, and
|
||||||
|
diagnostics for LSP linters will be ignored. (See |ale-lsp|)
|
||||||
|
|
||||||
|
This setting can be set to a |Dictionary| mapping filetypes to linter names,
|
||||||
|
just like |g:ale_linters|, to list linters to ignore. Ignore lists will be
|
||||||
|
applied after everything else. >
|
||||||
|
|
||||||
|
" Select flake8 and pylint, and ignore pylint, so only flake8 is run.
|
||||||
|
let g:ale_linters = {'python': ['flake8', 'pylint']}
|
||||||
|
let g:ale_linters_ignore = {'python': ['pylint']}
|
||||||
|
<
|
||||||
|
This setting can be set to simply a |List| of linter names, which is
|
||||||
|
especially more convenient when using the setting in ftplugin files for
|
||||||
|
particular buffers. >
|
||||||
|
|
||||||
|
" The same as above, in a ftplugin/python.vim.
|
||||||
|
let b:ale_linters = ['flake8', 'pylint']
|
||||||
|
let b:ale_linters_ignore = ['pylint']
|
||||||
|
<
|
||||||
|
|
||||||
g:ale_list_vertical *g:ale_list_vertical*
|
g:ale_list_vertical *g:ale_list_vertical*
|
||||||
*b:ale_list_vertical*
|
*b:ale_list_vertical*
|
||||||
Type: |Number|
|
Type: |Number|
|
||||||
@@ -1352,8 +1401,7 @@ g:ale_set_balloons *g:ale_set_balloons*
|
|||||||
*b:ale_set_balloons*
|
*b:ale_set_balloons*
|
||||||
|
|
||||||
Type: |Number|
|
Type: |Number|
|
||||||
Default: `(has('balloon_eval') && has('gui_running'))`
|
Default: `has('balloon_eval') && has('gui_running')`
|
||||||
`|| (has('balloon_eval_term') && !has('gui_running'))`
|
|
||||||
|
|
||||||
When this option is set to `1`, balloon messages will be displayed for
|
When this option is set to `1`, balloon messages will be displayed for
|
||||||
problems or hover information if available.
|
problems or hover information if available.
|
||||||
@@ -1363,6 +1411,12 @@ g:ale_set_balloons *g:ale_set_balloons*
|
|||||||
supporting "Hover" information, per |ale-hover|, then brief information
|
supporting "Hover" information, per |ale-hover|, then brief information
|
||||||
about the symbol under the cursor will be displayed in a balloon.
|
about the symbol under the cursor will be displayed in a balloon.
|
||||||
|
|
||||||
|
Balloons can be enabled for terminal versions of Vim that support balloons,
|
||||||
|
but some versions of Vim will produce strange mouse behavior when balloons
|
||||||
|
are enabled. To configure balloons for your terminal, you should first
|
||||||
|
configure your |ttymouse| setting, and then consider setting
|
||||||
|
`g:ale_set_balloons` to `1` before ALE is loaded.
|
||||||
|
|
||||||
`b:ale_set_balloons` can be set to `0` to disable balloons for a buffer.
|
`b:ale_set_balloons` can be set to `0` to disable balloons for a buffer.
|
||||||
Balloons cannot be enabled for a specific buffer when not initially enabled
|
Balloons cannot be enabled for a specific buffer when not initially enabled
|
||||||
globally.
|
globally.
|
||||||
@@ -1964,9 +2018,13 @@ ALEDisableBuffer *ALEDisableBuffer*
|
|||||||
*:ALEDetail*
|
*:ALEDetail*
|
||||||
ALEDetail *ALEDetail*
|
ALEDetail *ALEDetail*
|
||||||
|
|
||||||
Show the full linter message for the current line in the preview window.
|
Show the full linter message for the problem nearest to the cursor on the
|
||||||
This will only have an effect on lines that contain a linter message. The
|
given line in the preview window. The preview window can be easily closed
|
||||||
preview window can be easily closed with the `q` key.
|
with the `q` key. If there is no message to show, the window will not be
|
||||||
|
opened.
|
||||||
|
|
||||||
|
If a loclist item has a `detail` key set, the message for that key will be
|
||||||
|
preferred over `text`. See |ale-loclist-format|.
|
||||||
|
|
||||||
A plug mapping `<Plug>(ale_detail)` is defined for this command.
|
A plug mapping `<Plug>(ale_detail)` is defined for this command.
|
||||||
|
|
||||||
@@ -2150,13 +2208,20 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
|
|
||||||
This argument is required, unless the linter is an
|
This argument is required, unless the linter is an
|
||||||
LSP linter. In which case, this argument must not be
|
LSP linter. In which case, this argument must not be
|
||||||
defined, as LSP linters handle diangostics
|
defined, as LSP linters handle diagnostics
|
||||||
automatically. See |ale-lsp-linters|.
|
automatically. See |ale-lsp-linters|.
|
||||||
|
|
||||||
|
If the function named does not exist, including if
|
||||||
|
the function is later deleted, ALE will behave as if
|
||||||
|
the callback returned an empty list.
|
||||||
|
|
||||||
The keys for each item in the List will be handled in
|
The keys for each item in the List will be handled in
|
||||||
the following manner:
|
the following manner:
|
||||||
*ale-loclist-format*
|
*ale-loclist-format*
|
||||||
`text` - This error message is required.
|
`text` - This error message is required.
|
||||||
|
`detail` - An optional, more descriptive message.
|
||||||
|
This message can be displayed with the |ALEDetail|
|
||||||
|
command instead of the message for `text`, if set.
|
||||||
`lnum` - The line number is required. Any strings
|
`lnum` - The line number is required. Any strings
|
||||||
will be automatically converted to numbers by
|
will be automatically converted to numbers by
|
||||||
using `str2nr()`.
|
using `str2nr()`.
|
||||||
@@ -2316,8 +2381,16 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
|
|
||||||
When this argument is set to `'stdio'`, then the
|
When this argument is set to `'stdio'`, then the
|
||||||
linter will be defined as an LSP linter which keeps a
|
linter will be defined as an LSP linter which keeps a
|
||||||
process for a language server runnning, and
|
process for a language server running, and
|
||||||
communicates with it directly via a |channel|.
|
communicates with it directly via a |channel|.
|
||||||
|
`executable` or `executable_callback` must be set,
|
||||||
|
and `command` or `command_callback` must be set.
|
||||||
|
|
||||||
|
When this argument is set to `'socket'`, then the
|
||||||
|
linter will be defined as an LSP linter via a TCP
|
||||||
|
socket connection. `address_callback` must be set
|
||||||
|
with a callback returning an address to connect to.
|
||||||
|
ALE will not start a server automatically.
|
||||||
|
|
||||||
When this argument is not empty, only one of either
|
When this argument is not empty, only one of either
|
||||||
`language` or `language_callback` must be defined,
|
`language` or `language_callback` must be defined,
|
||||||
@@ -2329,6 +2402,17 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
An optional `completion_filter` callback may be
|
An optional `completion_filter` callback may be
|
||||||
defined for filtering completion results.
|
defined for filtering completion results.
|
||||||
|
|
||||||
|
An optional `initialization_options` or
|
||||||
|
`initialization_options_callback` may be defined to
|
||||||
|
pass initialization options to the LSP.
|
||||||
|
|
||||||
|
`address_callback` A |String| or |Funcref| for a callback function
|
||||||
|
accepting a buffer number. A |String| should be
|
||||||
|
returned with an address to connect to.
|
||||||
|
|
||||||
|
This argument must only be set if the `lsp` argument
|
||||||
|
is set to `'socket'`.
|
||||||
|
|
||||||
`project_root_callback` A |String| or |Funcref| for a callback function
|
`project_root_callback` A |String| or |Funcref| for a callback function
|
||||||
accepting a buffer number. A |String| should be
|
accepting a buffer number. A |String| should be
|
||||||
returned representing the path to the project for the
|
returned representing the path to the project for the
|
||||||
@@ -2370,6 +2454,17 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
setting can make it easier to guess the linter name
|
setting can make it easier to guess the linter name
|
||||||
by offering a few alternatives.
|
by offering a few alternatives.
|
||||||
|
|
||||||
|
`initialization_options` A |Dictionary| of initialization options for LSPs.
|
||||||
|
This will be fed (as JSON) to the LSP in the
|
||||||
|
initialize command.
|
||||||
|
|
||||||
|
`initialization_options_callback`
|
||||||
|
A |String| or |Funcref| for a callback function
|
||||||
|
accepting a buffer number. A |Dictionary| should be
|
||||||
|
returned for initialization options to pass the LSP.
|
||||||
|
This can be used in place of `initialization_options`
|
||||||
|
when more complicated processing is needed.
|
||||||
|
|
||||||
Only one of `command`, `command_callback`, or `command_chain` should be
|
Only one of `command`, `command_callback`, or `command_chain` should be
|
||||||
specified. `command_callback` is generally recommended when a command string
|
specified. `command_callback` is generally recommended when a command string
|
||||||
needs to be generated dynamically, or any global options are used.
|
needs to be generated dynamically, or any global options are used.
|
||||||
@@ -2546,5 +2641,5 @@ free to send an email to devw0rp@gmail.com.
|
|||||||
Please drink responsibly, or not at all, which is ironically the preference
|
Please drink responsibly, or not at all, which is ironically the preference
|
||||||
of w0rp, who is teetotal.
|
of w0rp, who is teetotal.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
|
|||||||
@@ -32,21 +32,9 @@ if !s:has_features
|
|||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
if has('nvim') && !has('nvim-0.2.0') && !get(g:, 'ale_use_deprecated_neovim')
|
|
||||||
execute 'echom ''ALE support for NeoVim versions below 0.2.0 is deprecated.'''
|
|
||||||
execute 'echom ''Use `let g:ale_use_deprecated_neovim = 1` to silence this warning for now.'''
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Set this flag so that other plugins can use it, like airline.
|
" Set this flag so that other plugins can use it, like airline.
|
||||||
let g:loaded_ale = 1
|
let g:loaded_ale = 1
|
||||||
|
|
||||||
" Set the TMPDIR environment variable if it is not set automatically.
|
|
||||||
" This can automatically fix some environments.
|
|
||||||
if has('unix') && empty($TMPDIR)
|
|
||||||
let $TMPDIR = '/tmp'
|
|
||||||
endif
|
|
||||||
|
|
||||||
" This global variable is used internally by ALE for tracking information for
|
" This global variable is used internally by ALE for tracking information for
|
||||||
" each buffer which linters are being run against.
|
" each buffer which linters are being run against.
|
||||||
let g:ale_buffer_info = {}
|
let g:ale_buffer_info = {}
|
||||||
@@ -120,10 +108,7 @@ let g:ale_set_highlights = get(g:, 'ale_set_highlights', has('syntax'))
|
|||||||
let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', 1)
|
let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', 1)
|
||||||
|
|
||||||
" This flag can be set to 0 to disable balloon support.
|
" This flag can be set to 0 to disable balloon support.
|
||||||
let g:ale_set_balloons = get(g:, 'ale_set_balloons',
|
let g:ale_set_balloons = get(g:, 'ale_set_balloons', has('balloon_eval') && has('gui_running'))
|
||||||
\ (has('balloon_eval') && has('gui_running'))
|
|
||||||
\ || (has('balloon_eval_term') && !has('gui_running'))
|
|
||||||
\)
|
|
||||||
|
|
||||||
" This flag can be set to 0 to disable warnings for trailing whitespace
|
" This flag can be set to 0 to disable warnings for trailing whitespace
|
||||||
let g:ale_warn_about_trailing_whitespace = get(g:, 'ale_warn_about_trailing_whitespace', 1)
|
let g:ale_warn_about_trailing_whitespace = get(g:, 'ale_warn_about_trailing_whitespace', 1)
|
||||||
@@ -221,35 +206,13 @@ nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return>
|
|||||||
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
|
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
|
||||||
|
|
||||||
" Set up autocmd groups now.
|
" Set up autocmd groups now.
|
||||||
call ale#autocmd#InitAuGroups()
|
call ale#events#Init()
|
||||||
|
|
||||||
" Housekeeping
|
" Housekeeping
|
||||||
|
|
||||||
augroup ALECleanupGroup
|
augroup ALECleanupGroup
|
||||||
autocmd!
|
autocmd!
|
||||||
" Clean up buffers automatically when they are unloaded.
|
" Clean up buffers automatically when they are unloaded.
|
||||||
autocmd BufDelete * call ale#engine#Cleanup(str2nr(expand('<abuf>')))
|
autocmd BufDelete * if exists('*ale#engine#Cleanup') | call ale#engine#Cleanup(str2nr(expand('<abuf>'))) | endif
|
||||||
autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand('<abuf>')))
|
autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand('<abuf>')))
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
" Backwards Compatibility
|
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
function! ALELint(delay) abort
|
|
||||||
if !get(g:, 'ale_deprecation_ale_lint', 0)
|
|
||||||
execute 'echom ''ALELint() is deprecated, use ale#Queue() instead.'''
|
|
||||||
let g:ale_deprecation_ale_lint = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
call ale#Queue(a:delay)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
function! ALEGetStatusLine() abort
|
|
||||||
if !get(g:, 'ale_deprecation_ale_get_status_line', 0)
|
|
||||||
execute 'echom ''ALEGetStatusLine() is deprecated.'''
|
|
||||||
let g:ale_deprecation_ale_get_status_line = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
return ale#statusline#Status()
|
|
||||||
endfunction
|
|
||||||
|
|||||||
95
run-tests
95
run-tests
@@ -5,24 +5,25 @@ set -u
|
|||||||
|
|
||||||
# Author: w0rp <devw0rp@gmail.com>
|
# Author: w0rp <devw0rp@gmail.com>
|
||||||
#
|
#
|
||||||
# This script runs tests for the ALE project. The following options are
|
# This script runs tests for the ALE project. Run `./run-tests --help` for
|
||||||
# accepted:
|
# options, or read the output below.
|
||||||
#
|
#
|
||||||
# -v Enable verbose output
|
|
||||||
# --neovim-only Run tests only for NeoVim
|
|
||||||
# --vim-only Run tests only for Vim
|
|
||||||
|
|
||||||
current_image_id=d5a1b5915b09
|
|
||||||
image=w0rp/ale
|
image=w0rp/ale
|
||||||
|
current_image_id=71553d0ab3e8
|
||||||
|
|
||||||
|
# Used in all test scripts for running the selected Docker image.
|
||||||
|
DOCKER_RUN_IMAGE="$image"
|
||||||
|
export DOCKER_RUN_IMAGE
|
||||||
|
|
||||||
tests='test/*.vader test/*/*.vader test/*/*/*.vader test/*/*/*.vader'
|
tests='test/*.vader test/*/*.vader test/*/*/*.vader test/*/*/*.vader'
|
||||||
# These flags are forwarded to the script for running Vader tests.
|
# These flags are forwarded to the script for running Vader tests.
|
||||||
verbose_flag=''
|
verbose_flag=''
|
||||||
quiet_flag=''
|
quiet_flag=''
|
||||||
run_neovim_tests=1
|
run_neovim_02_tests=1
|
||||||
|
run_neovim_03_tests=1
|
||||||
run_vim_tests=1
|
run_vim_tests=1
|
||||||
run_vint=1
|
run_linters=1
|
||||||
run_custom_checks=1
|
|
||||||
|
|
||||||
while [ $# -ne 0 ]; do
|
while [ $# -ne 0 ]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
@@ -36,35 +37,50 @@ while [ $# -ne 0 ]; do
|
|||||||
;;
|
;;
|
||||||
--neovim-only)
|
--neovim-only)
|
||||||
run_vim_tests=0
|
run_vim_tests=0
|
||||||
run_vint=0
|
run_linters=0
|
||||||
run_custom_checks=0
|
shift
|
||||||
|
;;
|
||||||
|
--neovim-02-only)
|
||||||
|
run_neovim_03_tests=0
|
||||||
|
run_vim_tests=0
|
||||||
|
run_linters=0
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--neovim-03-only)
|
||||||
|
run_neovim_02_tests=0
|
||||||
|
run_vim_tests=0
|
||||||
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--vim-only)
|
--vim-only)
|
||||||
run_neovim_tests=0
|
run_neovim_02_tests=0
|
||||||
run_vint=0
|
run_neovim_03_tests=0
|
||||||
run_custom_checks=0
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--no-vint)
|
--linters-only)
|
||||||
run_vint=0
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--vint-only)
|
|
||||||
run_vim_tests=0
|
run_vim_tests=0
|
||||||
run_neovim_tests=0
|
run_neovim_02_tests=0
|
||||||
run_custom_checks=0
|
run_neovim_03_tests=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--no-custom-checks)
|
--help)
|
||||||
run_custom_checks=0
|
echo 'Usage: ./run-tests [OPTION]... [FILE]...'
|
||||||
shift
|
echo
|
||||||
;;
|
echo 'Filenames can be given as arguments to run a subset of tests.'
|
||||||
--custom-checks-only)
|
echo 'For example: ./run-tests test/test_ale_var.vader'
|
||||||
run_vim_tests=0
|
echo
|
||||||
run_neovim_tests=0
|
echo 'Options:'
|
||||||
run_vint=0
|
echo ' -v Enable verbose output'
|
||||||
shift
|
echo ' -q Hide output for successful tests'
|
||||||
|
echo ' --neovim-only Run tests only for NeoVim 0.2 and 0.3'
|
||||||
|
echo ' --neovim-02-only Run tests only for NeoVim 0.2'
|
||||||
|
echo ' --neovim-03-only Run tests only for NeoVim 0.3'
|
||||||
|
echo ' --vim-only Run tests only for Vim'
|
||||||
|
echo ' --linters-only Run only Vint and custom checks'
|
||||||
|
echo ' --help Show this help text'
|
||||||
|
echo ' -- Stop parsing options after this'
|
||||||
|
exit 0
|
||||||
;;
|
;;
|
||||||
--)
|
--)
|
||||||
shift
|
shift
|
||||||
@@ -85,6 +101,9 @@ if [ $# -ne 0 ]; then
|
|||||||
# This doesn't perfectly handle work splitting, but none of our files
|
# This doesn't perfectly handle work splitting, but none of our files
|
||||||
# have spaces in the names.
|
# have spaces in the names.
|
||||||
tests="$*"
|
tests="$*"
|
||||||
|
|
||||||
|
# Don't run other tools when targeting tests.
|
||||||
|
run_linters=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Delete .swp files in the test directory, which cause Vim 8 to hang.
|
# Delete .swp files in the test directory, which cause Vim 8 to hang.
|
||||||
@@ -100,8 +119,10 @@ trap '{ rm -rf "$output_dir"; }' EXIT
|
|||||||
file_number=0
|
file_number=0
|
||||||
pid_list=''
|
pid_list=''
|
||||||
|
|
||||||
for vim in $(docker run --rm "$image" ls /vim-build/bin | grep '^neovim\|^vim' ); do
|
for vim in $(docker run --rm "$DOCKER_RUN_IMAGE" ls /vim-build/bin | grep '^neovim\|^vim' ); do
|
||||||
if ((run_vim_tests)) || [[ $vim =~ ^neovim ]] && ((run_neovim_tests)); then
|
if ( [[ $vim =~ ^vim ]] && ((run_vim_tests)) ) \
|
||||||
|
|| ( [[ $vim =~ ^neovim-v0.2 ]] && ((run_neovim_02_tests)) ) \
|
||||||
|
|| ( [[ $vim =~ ^neovim-v0.3 ]] && ((run_neovim_03_tests)) ); then
|
||||||
echo "Starting Vim: $vim..."
|
echo "Starting Vim: $vim..."
|
||||||
file_number=$((file_number+1))
|
file_number=$((file_number+1))
|
||||||
test/script/run-vader-tests $quiet_flag $verbose_flag "$vim" "$tests" \
|
test/script/run-vader-tests $quiet_flag $verbose_flag "$vim" "$tests" \
|
||||||
@@ -110,14 +131,12 @@ for vim in $(docker run --rm "$image" ls /vim-build/bin | grep '^neovim\|^vim' )
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if ((run_vint)); then
|
if ((run_linters)); then
|
||||||
echo "Starting Vint..."
|
echo "Starting Vint..."
|
||||||
file_number=$((file_number+1))
|
file_number=$((file_number+1))
|
||||||
test/script/run-vint > "$output_dir/$file_number" 2>&1 &
|
test/script/run-vint > "$output_dir/$file_number" 2>&1 &
|
||||||
pid_list="$pid_list $!"
|
pid_list="$pid_list $!"
|
||||||
fi
|
|
||||||
|
|
||||||
if ((run_custom_checks)); then
|
|
||||||
echo "Starting Custom checks..."
|
echo "Starting Custom checks..."
|
||||||
file_number=$((file_number+1))
|
file_number=$((file_number+1))
|
||||||
test/script/custom-checks &> "$output_dir/$file_number" 2>&1 &
|
test/script/custom-checks &> "$output_dir/$file_number" 2>&1 &
|
||||||
@@ -139,4 +158,10 @@ for pid in $pid_list; do
|
|||||||
cat "$output_dir/$index"
|
cat "$output_dir/$index"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if ((failed)); then
|
||||||
|
echo 'Something went wrong!'
|
||||||
|
else
|
||||||
|
echo 'All tests passed!'
|
||||||
|
fi
|
||||||
|
|
||||||
exit $failed
|
exit $failed
|
||||||
|
|||||||
@@ -10,7 +10,21 @@ REM Use the first argument for selecting tests to run.
|
|||||||
if not "%1"=="" set tests=%1
|
if not "%1"=="" set tests=%1
|
||||||
|
|
||||||
set VADER_OUTPUT_FILE=%~dp0\vader_output
|
set VADER_OUTPUT_FILE=%~dp0\vader_output
|
||||||
|
REM Automatically re-run Windows tests, which can fail some times.
|
||||||
|
set tries=0
|
||||||
|
|
||||||
|
RUN_TESTS:
|
||||||
|
set /a tries=%tries%+1
|
||||||
type nul > "%VADER_OUTPUT_FILE%"
|
type nul > "%VADER_OUTPUT_FILE%"
|
||||||
C:\vim\vim\vim80\vim.exe -u test/vimrc "+Vader! %tests%"
|
C:\vim\vim\vim80\vim.exe -u test/vimrc "+Vader! %tests%"
|
||||||
|
set code=%ERRORLEVEL%
|
||||||
|
|
||||||
|
IF %code% EQU 0 GOTO :SHOW_RESULTS
|
||||||
|
IF %tries% GEQ 2 GOTO :SHOW_RESULTS
|
||||||
|
GOTO :RUN_TESTS
|
||||||
|
|
||||||
|
SHOW_RESULTS:
|
||||||
type "%VADER_OUTPUT_FILE%"
|
type "%VADER_OUTPUT_FILE%"
|
||||||
del "%VADER_OUTPUT_FILE%"
|
del "%VADER_OUTPUT_FILE%"
|
||||||
|
|
||||||
|
exit /B %code%
|
||||||
|
|||||||
1
test/command_callback/mix_paths/wrapped_project/mix.exs
Normal file
1
test/command_callback/mix_paths/wrapped_project/mix.exs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
use Mix.Config
|
||||||
0
test/command_callback/python_paths/with_virtualenv/env/Scripts/pyre.exe
vendored
Executable file
0
test/command_callback/python_paths/with_virtualenv/env/Scripts/pyre.exe
vendored
Executable file
0
test/command_callback/python_paths/with_virtualenv/env/bin/pyre
vendored
Executable file
0
test/command_callback/python_paths/with_virtualenv/env/bin/pyre
vendored
Executable file
0
test/command_callback/scala_paths/dummy.scala
Normal file
0
test/command_callback/scala_paths/dummy.scala
Normal file
@@ -1,13 +1,19 @@
|
|||||||
Before:
|
Before:
|
||||||
Save g:ale_rust_cargo_use_check
|
Save g:ale_rust_cargo_use_check
|
||||||
Save g:ale_rust_cargo_check_all_targets
|
Save g:ale_rust_cargo_check_all_targets
|
||||||
|
Save g:ale_rust_cargo_check_tests
|
||||||
|
Save g:ale_rust_cargo_check_examples
|
||||||
Save g:ale_rust_cargo_default_feature_behavior
|
Save g:ale_rust_cargo_default_feature_behavior
|
||||||
Save g:ale_rust_cargo_include_features
|
Save g:ale_rust_cargo_include_features
|
||||||
|
Save g:ale_rust_cargo_avoid_whole_workspace
|
||||||
|
|
||||||
unlet! g:ale_rust_cargo_use_check
|
unlet! g:ale_rust_cargo_use_check
|
||||||
unlet! g:ale_cargo_check_all_targets
|
unlet! g:ale_rust_cargo_check_all_targets
|
||||||
|
unlet! g:ale_rust_cargo_check_tests
|
||||||
|
unlet! g:ale_rust_cargo_check_examples
|
||||||
unlet! g:ale_rust_cargo_default_feature_behavior
|
unlet! g:ale_rust_cargo_default_feature_behavior
|
||||||
unlet! g:ale_rust_cargo_include_features
|
unlet! g:ale_rust_cargo_include_features
|
||||||
|
unlet! g:ale_rust_cargo_avoid_whole_workspace
|
||||||
|
|
||||||
runtime ale_linters/rust/cargo.vim
|
runtime ale_linters/rust/cargo.vim
|
||||||
call ale#test#SetDirectory('/testplugin/test/command_callback')
|
call ale#test#SetDirectory('/testplugin/test/command_callback')
|
||||||
@@ -119,6 +125,38 @@ Execute(--all-targets should be used when g:ale_rust_cargo_check_all_targets is
|
|||||||
|
|
||||||
AssertEqual '', ale_linters#rust#cargo#VersionCheck(bufnr(''))
|
AssertEqual '', ale_linters#rust#cargo#VersionCheck(bufnr(''))
|
||||||
|
|
||||||
|
Execute(--tests should be used when g:ale_rust_cargo_check_tests is set to 1):
|
||||||
|
let g:ale_rust_cargo_check_tests = 1
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ 'cargo check --tests' . g:suffix,
|
||||||
|
\ ale_linters#rust#cargo#GetCommand(bufnr(''), [
|
||||||
|
\ 'cargo 0.22.0 (3423351a5 2017-10-06)',
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
" We should cache the version check
|
||||||
|
AssertEqual
|
||||||
|
\ 'cargo check --tests' . g:suffix,
|
||||||
|
\ ale_linters#rust#cargo#GetCommand(bufnr(''), [])
|
||||||
|
|
||||||
|
AssertEqual '', ale_linters#rust#cargo#VersionCheck(bufnr(''))
|
||||||
|
|
||||||
|
Execute(--examples should be used when g:ale_rust_cargo_check_examples is set to 1):
|
||||||
|
let g:ale_rust_cargo_check_examples = 1
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ 'cargo check --examples' . g:suffix,
|
||||||
|
\ ale_linters#rust#cargo#GetCommand(bufnr(''), [
|
||||||
|
\ 'cargo 0.22.0 (3423351a5 2017-10-06)',
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
" We should cache the version check
|
||||||
|
AssertEqual
|
||||||
|
\ 'cargo check --examples' . g:suffix,
|
||||||
|
\ ale_linters#rust#cargo#GetCommand(bufnr(''), [])
|
||||||
|
|
||||||
|
AssertEqual '', ale_linters#rust#cargo#VersionCheck(bufnr(''))
|
||||||
|
|
||||||
Execute(--no-default-features should be used when g:ale_rust_cargo_default_feature_behavior is none):
|
Execute(--no-default-features should be used when g:ale_rust_cargo_default_feature_behavior is none):
|
||||||
let g:ale_rust_cargo_default_feature_behavior = 'none'
|
let g:ale_rust_cargo_default_feature_behavior = 'none'
|
||||||
|
|
||||||
@@ -162,3 +200,24 @@ Execute(--all-features should be used when g:ale_rust_cargo_default_feature_beha
|
|||||||
\ ale_linters#rust#cargo#GetCommand(bufnr(''), [
|
\ ale_linters#rust#cargo#GetCommand(bufnr(''), [
|
||||||
\ 'cargo 0.22.0 (3423351a5 2017-10-06)',
|
\ 'cargo 0.22.0 (3423351a5 2017-10-06)',
|
||||||
\ ])
|
\ ])
|
||||||
|
|
||||||
|
Execute(When a crate belongs to a workspace we chdir into the crate.):
|
||||||
|
call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs')
|
||||||
|
|
||||||
|
if ale#Has('win32')
|
||||||
|
let test_cdprefix = "C:\\testplugin\\test\\command_callback\\cargo_workspace_paths\\subpath"
|
||||||
|
else
|
||||||
|
let test_cdprefix = "'/testplugin/test/command_callback/cargo_workspace_paths/subpath'"
|
||||||
|
endif
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ "cd ".test_cdprefix." && cargo build --frozen --message-format=json -q",
|
||||||
|
\ ale_linters#rust#cargo#GetCommand(bufnr(''), [])
|
||||||
|
|
||||||
|
Execute(When a crate belongs to a workspace we chdir into the crate, unless we disabled it):
|
||||||
|
let g:ale_rust_cargo_avoid_whole_workspace = 0
|
||||||
|
call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs')
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ "cargo build --frozen --message-format=json -q",
|
||||||
|
\ ale_linters#rust#cargo#GetCommand(bufnr(''), [])
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
" Author: Ben Falconer <ben@falconers.me.uk>
|
||||||
|
" Description: A language server for C++
|
||||||
|
|
||||||
|
Before:
|
||||||
|
Save g:ale_cpp_cquery_executable
|
||||||
|
Save g:ale_cpp_cquery_cache_directory
|
||||||
|
|
||||||
|
unlet! g:ale_cpp_cquery_executable
|
||||||
|
unlet! b:ale_cpp_cquery_executable
|
||||||
|
unlet! g:ale_cpp_cquery_cache_directory
|
||||||
|
unlet! b:ale_cpp_cquery_cache_directory
|
||||||
|
|
||||||
|
runtime ale_linters/cpp/cquery.vim
|
||||||
|
|
||||||
|
After:
|
||||||
|
Restore
|
||||||
|
unlet! b:ale_cpp_cquery_executable
|
||||||
|
unlet! b:ale_cpp_cquery_cache_directory
|
||||||
|
call ale#linter#Reset()
|
||||||
|
|
||||||
|
Execute(The executable should be configurable):
|
||||||
|
AssertEqual 'cquery', ale_linters#cpp#cquery#GetExecutable(bufnr(''))
|
||||||
|
|
||||||
|
let b:ale_cpp_cquery_executable = 'foobar'
|
||||||
|
|
||||||
|
AssertEqual 'foobar', ale_linters#cpp#cquery#GetExecutable(bufnr(''))
|
||||||
|
|
||||||
|
Execute(The executable should be used in the command):
|
||||||
|
AssertEqual
|
||||||
|
\ ale#Escape('cquery'),
|
||||||
|
\ ale_linters#cpp#cquery#GetCommand(bufnr(''))
|
||||||
|
|
||||||
|
let b:ale_cpp_cquery_executable = 'foobar'
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ ale#Escape('foobar'),
|
||||||
|
\ ale_linters#cpp#cquery#GetCommand(bufnr(''))
|
||||||
|
|
||||||
|
Execute(The cache directory should be configurable):
|
||||||
|
AssertEqual
|
||||||
|
\ {'cacheDirectory': expand('$HOME/.cache/cquery')},
|
||||||
|
\ ale_linters#cpp#cquery#GetInitializationOptions(bufnr(''))
|
||||||
|
|
||||||
|
let b:ale_cpp_cquery_cache_directory = '/foo/bar'
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ {'cacheDirectory': '/foo/bar'},
|
||||||
|
\ ale_linters#cpp#cquery#GetInitializationOptions(bufnr(''))
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
Before:
|
||||||
|
runtime ale_linters/elixir/mix.vim
|
||||||
|
|
||||||
|
call ale#test#SetDirectory('/testplugin/test/command_callback')
|
||||||
|
|
||||||
|
let g:project_root = ale#path#Simplify(g:dir . '/mix_paths/wrapped_project')
|
||||||
|
|
||||||
|
let g:env_prefix = has('win32')
|
||||||
|
\ ? 'set MIX_BUILD_PATH=TEMP && '
|
||||||
|
\ : 'MIX_BUILD_PATH=TEMP '
|
||||||
|
|
||||||
|
|
||||||
|
function! GetCommand(buffer) abort
|
||||||
|
let l:command = ale_linters#elixir#mix#GetCommand(a:buffer)
|
||||||
|
|
||||||
|
return substitute(l:command, 'MIX_BUILD_PATH=[^ ]\+', 'MIX_BUILD_PATH=TEMP', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
After:
|
||||||
|
Restore
|
||||||
|
|
||||||
|
unlet! g:env_prefix
|
||||||
|
unlet! g:project_root
|
||||||
|
|
||||||
|
call ale#linter#Reset()
|
||||||
|
call ale#test#RestoreDirectory()
|
||||||
|
|
||||||
|
delfunction GetCommand
|
||||||
|
|
||||||
|
Execute(The default mix command should be correct):
|
||||||
|
call ale#test#SetFilename('mix_paths/wrapped_project/lib/app.ex')
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ GetCommand(bufnr('')),
|
||||||
|
\ ale#path#CdString(g:project_root)
|
||||||
|
\ . g:env_prefix
|
||||||
|
\ . 'mix compile %s'
|
||||||
@@ -174,3 +174,11 @@ Execute(Using `python -m flake8` should be supported for running flake8):
|
|||||||
\ ale#path#BufferCdString(bufnr(''))
|
\ ale#path#BufferCdString(bufnr(''))
|
||||||
\ . ale#Escape('python') . ' -m flake8 --some-option --format=default -',
|
\ . ale#Escape('python') . ' -m flake8 --some-option --format=default -',
|
||||||
\ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9'])
|
\ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9'])
|
||||||
|
|
||||||
|
Execute(Setting executable to 'pipenv' appends 'run flake8'):
|
||||||
|
let g:ale_python_flake8_executable = 'path/to/pipenv'
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ ale#path#BufferCdString(bufnr(''))
|
||||||
|
\ . ale#Escape('path/to/pipenv') . ' run flake8 --format=default --stdin-display-name %s -',
|
||||||
|
\ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0'])
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ After:
|
|||||||
Execute(The default lintr command should be correct):
|
Execute(The default lintr command should be correct):
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ 'cd ' . ale#Escape(getcwd()) . ' && '
|
\ 'cd ' . ale#Escape(getcwd()) . ' && '
|
||||||
\ . 'Rscript -e '
|
\ . 'Rscript --vanilla -e '
|
||||||
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
||||||
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
|
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
|
||||||
\ . 'with_defaults())')
|
\ . 'with_defaults())')
|
||||||
@@ -28,7 +28,7 @@ Execute(The lintr options should be configurable):
|
|||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ 'cd ' . ale#Escape(getcwd()) . ' && '
|
\ 'cd ' . ale#Escape(getcwd()) . ' && '
|
||||||
\ . 'Rscript -e '
|
\ . 'Rscript --vanilla -e '
|
||||||
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
||||||
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
|
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
|
||||||
\ . 'with_defaults(object_usage_linter = NULL))')
|
\ . 'with_defaults(object_usage_linter = NULL))')
|
||||||
@@ -40,7 +40,7 @@ Execute(If the lint_package flag is set, lintr::lint_package should be called):
|
|||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ 'cd ' . ale#Escape(getcwd()) . ' && '
|
\ 'cd ' . ale#Escape(getcwd()) . ' && '
|
||||||
\ . 'Rscript -e '
|
\ . 'Rscript --vanilla -e '
|
||||||
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
||||||
\ . 'lint_package(cache = FALSE, '
|
\ . 'lint_package(cache = FALSE, '
|
||||||
\ . 'linters = with_defaults())')
|
\ . 'linters = with_defaults())')
|
||||||
|
|||||||
@@ -95,3 +95,12 @@ Execute(You should able able to use the global mypy instead):
|
|||||||
\ . ' --show-column-numbers '
|
\ . ' --show-column-numbers '
|
||||||
\ . '--shadow-file %s %t %s',
|
\ . '--shadow-file %s %t %s',
|
||||||
\ ale_linters#python#mypy#GetCommand(bufnr(''))
|
\ ale_linters#python#mypy#GetCommand(bufnr(''))
|
||||||
|
|
||||||
|
Execute(Setting executable to 'pipenv' appends 'run mypy'):
|
||||||
|
let g:ale_python_mypy_executable = 'path/to/pipenv'
|
||||||
|
|
||||||
|
AssertEqual
|
||||||
|
\ ale#path#BufferCdString(bufnr(''))
|
||||||
|
\ . ale#Escape('path/to/pipenv') . ' run mypy'
|
||||||
|
\ . ' --show-column-numbers --shadow-file %s %t %s',
|
||||||
|
\ ale_linters#python#mypy#GetCommand(bufnr(''))
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user