Compare commits

..

9 Commits

Author SHA1 Message Date
w0rp
d837169f1d Ignore compiled files from newer versions 2019-05-08 09:52:43 +01:00
w0rp
9778a6e5b5 Merge pull request #2134 from oaue/master
javac linter: fix handling of error messages containing ':' character
2019-05-08 09:51:46 +01:00
w0rp
0927634916 Fix #2452 - Strip trailing spaces off sign text automatically 2019-04-23 15:59:05 +01:00
w0rp
711de2c1be Fix #2415 - Mark tsserver and LSP linters inactive again 2019-04-17 18:13:22 +01:00
w0rp
fa18195e34 Fix #2440 - Fix the kotlinc command when Maven and Gradle are missing 2019-04-15 13:36:28 +01:00
w0rp
0059bcd1d0 Merge pull request #2433 from belka-ew/bugfix/remove-otherproject-util-double
Remove otherproject#util#Double from d.vim
2019-04-13 12:30:04 +01:00
w0rp
9d0a55edec Do not complain about generated _callback settings 2019-04-10 19:53:22 +01:00
w0rp
950204b133 Fix #2399 - Do not check buffers used for displaying diffs 2019-04-10 18:43:21 +01:00
w0rp
bbb6e70377 #2417 - Silence errors for shortmess+=T 2019-04-10 15:40:16 +01:00
2011 changed files with 11278 additions and 62558 deletions

View File

@@ -5,25 +5,6 @@ clone_depth: 10
# Use the directory C:\testplugin so test directories will mostly work.
clone_folder: C:\testplugin
branches:
only:
- master
- /v\d+\.\d+\.(x|\d+)/
# Skip running Windows tests if we only change files that can't impact
# Windows tests.
skip_commits:
files:
- '.github/**/*'
- .gitattributes
- Dockerfile
- README.md
- doc/*
- lua/*
- run-tests
- supported-tools.md
- syntax/*
# Cache the vim and vader directories between builds.
cache:
- C:\vim -> .appveyor.yml
@@ -33,9 +14,6 @@ init:
# Stop git from changing newlines
- git config --global core.autocrlf input
# NOTE: If you change the Vim or Vader versions here, please also update the
# instructions for running tests on Windows in ale-development.txt
install:
# Download and unpack Vim
- ps: >-

View File

@@ -12,7 +12,3 @@ insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.vader]
indent_style = space
indent_size = 2

View File

@@ -1,6 +0,0 @@
---
blank_issues_enabled: false
contact_links:
- name: Ask for Help
url: https://github.com/dense-analysis/ale/discussions/new?category=q-a-ask-for-help-with-problems
about: Ask for Help in ALE Discussions

View File

@@ -1,6 +1,5 @@
---
name: Report a bug
labels: bug
about: Report a bug with ALE.
---
@@ -40,9 +39,7 @@ Are you having trouble configuring ALE? Try asking for help on [Stack Exchange](
2. Then this happened.
### :ALEInfo
<details>
<summary>Expand</summary>
<!-- Paste the output of :ALEInfo here. Try :ALEInfo -clipboard -->
<!-- Make sure to run :ALEInfo from the buffer where the bug occurred. -->
<!-- Read the output. You might figure out what went wrong yourself. -->
</details>
<!-- Paste the output of :ALEInfo here. Try :ALEInfoToClipboard -->
<!-- Make sure to run :ALEInfo from the buffer where the bug occurred. -->
<!-- Read the output. You might figure out what went wrong yourself. -->

View File

@@ -1,6 +1,5 @@
---
name: Suggest a new linter or fixer
labels: new tool
about: Suggest a new tool ALE can officially integrate with.
---

View File

@@ -1,6 +1,5 @@
---
name: Suggest an improvement
labels: enhancement
about: Suggest some way to improve ALE, or add a new feature.
---

17
.github/stale.yml vendored
View File

@@ -1,17 +0,0 @@
---
# This configuration closes stale PRs after 56 + 7 days.
# That's 8 weeks until stale bot complains, and a week until it closes a PR.
# Issues in ALE are never, ever stale. They are either resolved or not.
only: pulls
daysUntilStale: 56
daysUntilClose: 7
exemptLabels: []
staleLabel: stale
markComment: >
This pull request has been automatically marked as stale because it has not
been updated recently. Make sure to write tests and document your changes.
See `:help ale-dev` for information on writing tests.
If your pull request is good to merge, bother w0rp or another maintainer
again, and get them to merge it.
closeComment: false

View File

@@ -1,38 +0,0 @@
---
name: CI
on: # yamllint disable-line rule:truthy
push:
branches: [ master ] # yamllint disable-line rule:brackets
tags:
- v[0-9]+.[0-9]+.x
- v[0-9]+.[0-9]+.[0-9]+
pull_request:
branches: [ master ] # yamllint disable-line rule:brackets
jobs:
build_image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build docker run image
shell: bash
env:
DOCKER_HUB_USER: ${{ secrets.DOCKER_HUB_USER }}
DOCKER_HUB_PASS: ${{ secrets.DOCKER_HUB_PASS }}
run: ./run-tests --build-image
test_ale:
needs: build_image
runs-on: ubuntu-latest
strategy:
matrix:
vim-version:
- '--vim-80-only'
- '--vim-90-only'
- '--neovim-07-only'
- '--neovim-08-only'
- '--lua-only'
- '--linters-only'
steps:
- uses: actions/checkout@v4
- name: Run tests
run: ./run-tests -v ${{ matrix.vim-version }}

5
.gitignore vendored
View File

@@ -1,12 +1,11 @@
!.editorconfig
*.obj
*.pyc
# Ignore all hidden files everywhere.
# Use `git add -f` to add hidden files.
.*
__pycache__
*.pyc
/doc/tags
/init.vim
/test/ale-info-test-file
/vader_output
__pycache__
tags

View File

@@ -1,19 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
"diagnostics.globals": [
"vim"
],
"workspace.ignoreDir": [
"test"
],
"workspace.library": [
"/usr/share/nvim/runtime/lua"
],
"runtime.pathStrict": true,
"runtime.path": [
"lua/?.lua",
"lua/?/init.lua"
],
"runtime.version": "LuaJIT",
"hint.enable": false
}

12
.travis.yml Normal file
View File

@@ -0,0 +1,12 @@
---
sudo: required
services:
- docker
language: generic
env:
- OPTIONS=--vim-80-only
- OPTIONS=--vim-81-only
- OPTIONS=--neovim-only
- OPTIONS=--linters-only
script: |
./run-tests -v $OPTIONS

View File

@@ -1,5 +0,0 @@
policies:
# Disable a violation that is thrown randomly for reasons I still
# do not understand.
ProhibitMissingScriptEncoding:
enabled: false

View File

@@ -1,32 +1,20 @@
ARG TESTBED_VIM_VERSION=24
FROM tweekmonster/vim-testbed:latest
FROM testbed/vim:${TESTBED_VIM_VERSION}
RUN install_vim -tag v8.0.0027 -build \
-tag v8.1.0204 -build \
-tag neovim:v0.2.0 -build \
-tag neovim:v0.3.0 -build
ENV PACKAGES="\
lua5.1 \
lua5.1-dev \
lua5.1-busted \
bash \
git \
python2 \
python3 \
py3-pip \
grep \
sed \
python \
py-pip \
"
RUN apk --update add $PACKAGES && \
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
RUN install_vim -tag v8.0.0027 -build \
-tag v9.0.0297 -build \
-tag neovim:v0.7.0 -build \
-tag neovim:v0.8.0 -build
RUN pip install vim-vint==0.3.21
RUN pip install vim-vint==0.3.15
RUN git clone https://github.com/junegunn/vader.vim vader && \
cd vader && git checkout c6243dd81c98350df4dec608fa972df98fa2a3af
ARG GIT_VERSION
LABEL Version=${GIT_VERSION}
LABEL Name=denseanalysis/ale

View File

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

669
README.md
View File

@@ -1,16 +1,15 @@
# Asynchronous Lint Engine
# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) [![Join the chat at https://gitter.im/vim-ale/Lobby](https://badges.gitter.im/vim-ale/Lobby.svg)](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Vim](https://img.shields.io/badge/VIM-%2311AB00.svg?style=for-the-badge&logo=vim&logoColor=white)](https://www.vim.org/) [![Neovim](https://img.shields.io/badge/NeoVim-%2357A143.svg?&style=for-the-badge&logo=neovim&logoColor=white)](https://neovim.io/) [![CI](https://img.shields.io/github/actions/workflow/status/dense-analysis/ale/main.yml?branch=master&label=CI&logo=github&style=for-the-badge)](https://github.com/dense-analysis/ale/actions?query=event%3Apush+workflow%3ACI+branch%3Amaster++) [![AppVeyor Build Status](https://img.shields.io/appveyor/build/dense-analysis/ale?label=Windows&style=for-the-badge)](https://ci.appveyor.com/project/dense-analysis/ale) [![Join the Dense Analysis Discord server](https://img.shields.io/badge/chat-Discord-5865F2?style=for-the-badge&logo=appveyor)](https://discord.gg/5zFD6pQxDk)
![ALE Logo by Mark Grealish - https://www.bhalash.com/](https://user-images.githubusercontent.com/3518142/59195920-2c339500-8b85-11e9-9c22-f6b7f69637b8.jpg)
![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true)
ALE (Asynchronous Lint Engine) is a plugin providing linting (syntax checking
and semantic errors) in Neovim 0.7.0+ and Vim 8.0+ while you edit your text files,
ALE (Asynchronous Lint Engine) is a plugin for providing linting (checking
syntax and semantics) in NeoVim 0.2.0+ and Vim 8 while you edit your text files,
and acts as a Vim [Language Server Protocol](https://langserver.org/) client.
<video autoplay="true" muted="true" loop="true" controls="false" src="https://user-images.githubusercontent.com/3518142/210141215-8f2ff760-6a87-4704-a11e-c109b8e9ec41.mp4" title="An example showing what ALE can do."></video>
<img src="img/example.gif?raw=true" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim.">
ALE makes use of Neovim and Vim 8 job control functions and timers to
ALE makes use of NeoVim and Vim 8 job control functions and timers to
run linters on the contents of text buffers and return errors as
text is changed in Vim. This allows for displaying warnings and
errors in files being edited in Vim before files have been saved
@@ -27,7 +26,7 @@ features, including:
* Diagnostics (via Language Server Protocol linters)
* Go To Definition (`:ALEGoToDefinition`)
* Completion (Built in completion support, or with Deoplete)
* Completion (`let g:ale_completion_enabled = 1` before ALE is loaded)
* Finding references (`:ALEFindReferences`)
* Hover information (`:ALEHover`)
* Symbol search (`:ALESymbolSearch`)
@@ -36,42 +35,61 @@ If you don't care about Language Server Protocol, ALE won't load any of the code
for working with it unless needed. One of ALE's general missions is that you
won't pay for the features that you don't use.
**Help Wanted:** If you would like to help maintain this plugin by managing the
many issues and pull requests that are submitted, please send the author an
email at [dev@w0rp.com](mailto:dev@w0rp.com?subject=Helping%20with%20ALE).
If you enjoy this plugin, feel free to contribute or check out the author's
other content at [w0rp.com](https://w0rp.com).
## Why ALE?
## Table of Contents
ALE has been around for many years, and there are many ways to run asynchronous
linting and fixing of code in Vim. ALE offers the following.
1. [Supported Languages and Tools](#supported-languages)
2. [Usage](#usage)
1. [Linting](#usage-linting)
2. [Fixing](#usage-fixing)
3. [Completion](#usage-completion)
4. [Go To Definition](#usage-go-to-definition)
5. [Find References](#usage-find-references)
6. [Hovering](#usage-hover)
7. [Symbol Search](#usage-symbol-search)
3. [Installation](#installation)
1. [Installation with Vim package management](#standard-installation)
2. [Installation with Pathogen](#installation-with-pathogen)
3. [Installation with Vundle](#installation-with-vundle)
4. [Installation with Vim-Plug](#installation-with-vim-plug)
4. [Contributing](#contributing)
5. [FAQ](#faq)
1. [How do I disable particular linters?](#faq-disable-linters)
2. [How can I keep the sign gutter open?](#faq-keep-signs)
3. [How can I change the signs ALE uses?](#faq-change-signs)
4. [How can I change or disable the highlights ALE uses?](#faq-change-highlights)
5. [How can I show errors or warnings in my statusline?](#faq-statusline)
6. [How can I show errors or warnings in my lightline?](#faq-lightline)
7. [How can I change the format for echo messages?](#faq-echo-format)
8. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd)
9. [How can I navigate between errors quickly?](#faq-navigation)
10. [How can I run linters only when I save files?](#faq-lint-on-save)
11. [How can I use the quickfix list instead of the loclist?](#faq-quickfix)
12. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint)
13. [How can I check Vue files with ESLint?](#faq-vue-eslint)
14. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad)
15. [How can I configure my C or C++ project?](#faq-c-configuration)
16. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration)
17. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height)
18. [How can I see what ALE has configured for the current file?](#faq-get-info)
* No dependencies for ALE itself
* Lightweight plugin architecture (No JavaScript or Python required)
* Low memory footprint
* Runs virtually everywhere, including remote shells, and in `git commit`
* Out of the box support for running particular linters and language servers
* Near-zero configuration with custom code for better defaults
* Highly customizable and well-documented (`:help ale-options`)
* Breaking changes for the plugin are extremely rare
* Integrates with Neovim's LSP client (0.8+) and diagnostics (0.7+)
* Support for older Vim and Neovim versions
* Windows support
* Well-integrated with other plugins
<a name="supported-languages"></a>
## Supported Languages and Tools
## 1. Supported Languages and Tools
ALE supports a wide variety of languages and tools. See the
[full list](supported-tools.md) in the
[Supported Languages and Tools](supported-tools.md) page.
## Usage
<a name="usage"></a>
## 2. Usage
<a name="usage-linting"></a>
### Linting
### 2.i Linting
Once this plugin is installed, while editing your files in supported
languages and tools which have been correctly installed,
@@ -80,14 +98,14 @@ programs for checking the syntax and semantics of your programs. By default,
linters will be re-run in the background to check your syntax when you open
new buffers or as you make edits to your files.
The behavior of linting can be configured with a variety of options,
The behaviour of linting can be configured with a variety of options,
documented in [the Vim help file](doc/ale.txt). For more information on the
options ALE offers, consult `:help ale-options` for global options and `:help
ale-integration-options` for options specified to particular linters.
<a name="usage-fixing"></a>
### Fixing
### 2.ii Fixing
ALE can fix files with the `ALEFix` command. Functions need to be configured
either in each buffer with a `b:ale_fixers`, or globally with `g:ale_fixers`.
@@ -135,72 +153,33 @@ See `:help ale-fix` for complete information on how to fix files with ALE.
<a name="usage-completion"></a>
### Completion
### 2.iii Completion
ALE offers some support for completion via hijacking of omnicompletion while you
type. All of ALE's completion information must come from Language Server
Protocol linters, or from `tsserver` for TypeScript.
When running ALE in Neovim 0.8+, ALE will integrate with Neovim's LSP client by
default, and any auto-completion plugin that uses the native LSP client will
work when ALE runs language servers.
[nvim-cmp](https://github.com/hrsh7th/nvim-cmp) is recommended as a
completion plugin worth trying in Neovim.
ALE integrates with [Deoplete](https://github.com/Shougo/deoplete.nvim) as a
completion source, named `'ale'`. You can configure Deoplete to only use ALE as
the source of completion information, or mix it with other sources.
```vim
" Use ALE and also some plugin 'foobar' as completion sources for all code.
call deoplete#custom#option('sources', {
\ '_': ['ale', 'foobar'],
\})
```
ALE also offers its own automatic completion support, which does not require any
other plugins, and can be enabled by changing a setting before ALE is loaded.
```vim
" Enable completion where available.
" This setting must be set before ALE is loaded.
"
" You should not turn this setting on if you wish to use ALE as a completion
" source for other completion plugins, like Deoplete.
let g:ale_completion_enabled = 1
```
ALE provides an omni-completion function you can use for triggering
completion manually with `<C-x><C-o>`.
```vim
set omnifunc=ale#completion#OmniFunc
```
ALE supports automatic imports from external modules. This behavior is enabled
by default and can be disabled by setting:
```vim
let g:ale_completion_autoimport = 0
```
Note that disabling auto import can result in missing completion items from some
LSP servers (e.g. eclipselsp). See `:help ale-completion` for more information.
See `:help ale-completion` for more information.
<a name="usage-go-to-definition"></a>
### Go To Definition
### 2.iv Go To Definition
ALE supports jumping to the definition of words under your cursor with the
`:ALEGoToDefinition` command using any enabled Language Server Protocol linters
and `tsserver`. In Neovim 0.8+, you can also use Neovim's built in `gd` keybind
and more.
and `tsserver`.
See `:help ale-go-to-definition` for more information.
<a name="usage-find-references"></a>
### Find References
### 2.v Find References
ALE supports finding references for words under your cursor with the
`:ALEFindReferences` command using any enabled Language Server Protocol linters
@@ -210,15 +189,12 @@ See `:help ale-find-references` for more information.
<a name="usage-hover"></a>
### Hovering
### 2.vi Hovering
ALE supports "hover" information for printing brief information about symbols at
the cursor taken from Language Server Protocol linters and `tsserver` with the
`ALEHover` command.
Truncated information will be displayed when the cursor rests on a symbol by
default, as long as there are no problems on the same line.
The information can be displayed in a `balloon` tooltip in Vim or GVim by
hovering your mouse over symbols. Mouse hovering is enabled by default in GVim,
and needs to be configured for Vim 8.1+ in terminals.
@@ -227,7 +203,7 @@ See `:help ale-hover` for more information.
<a name="usage-symbol-search"></a>
### Symbol Search
### 2.vii Symbol Search
ALE supports searching for workspace symbols via Language Server Protocol
linters with the `ALESymbolSearch` command.
@@ -237,108 +213,125 @@ similar to a given query string.
See `:help ale-symbol-search` for more information.
<a name="usage-refactoring"></a>
<a name="installation"></a>
### Refactoring: Rename, Actions
## 3. Installation
ALE supports renaming symbols in code such as variables or class
names with the `ALERename` command.
To install this plugin, you should use one of the following methods.
For Windows users, replace usage of the Unix `~/.vim` directory with
`%USERPROFILE%\vimfiles`, or another directory if you have configured
Vim differently. On Windows, your `~/.vimrc` file will be similarly
stored in `%USERPROFILE%\_vimrc`.
`ALEFileRename` will rename file and fix import paths (tsserver
only).
<a name="standard-installation"></a>
`ALECodeAction` will execute actions on the cursor or applied to a visual
range selection, such as automatically fixing errors.
### 3.i. Installation with Vim package management
See `:help ale-refactor` for more information.
In Vim 8 and NeoVim, you can install plugins easily without needing to use
any other tools. Simply clone the plugin into your `pack` directory.
## Installation
Add ALE to your runtime path in the usual ways.
If you have trouble reading `:help ale`, try the following.
```vim
packloadall | silent! helptags ALL
```
#### Vim `packload`:
#### Vim 8 on Unix
```bash
mkdir -p ~/.vim/pack/git-plugins/start
git clone --depth 1 https://github.com/dense-analysis/ale.git ~/.vim/pack/git-plugins/start/ale
git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale
```
#### Neovim `packload`:
#### NeoVim on Unix
```bash
mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start
git clone --depth 1 https://github.com/dense-analysis/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
```
#### Windows `packload`:
#### Vim 8 on Windows
```bash
# Run these commands in the "Git for Windows" Bash terminal
mkdir -p ~/vimfiles/pack/git-plugins/start
git clone --depth 1 https://github.com/dense-analysis/ale.git ~/vimfiles/pack/git-plugins/start/ale
git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale
```
#### [vim-plug](https://github.com/junegunn/vim-plug)
#### Generating Vim help files
You can add the following line to your vimrc files to generate documentation
tags automatically, if you don't have something similar already, so you can use
the `:help` command to consult ALE's online documentation:
```vim
Plug 'dense-analysis/ale'
" Put these lines at the very end of your vimrc file.
" Load all plugins now.
" Plugins need to be added to runtimepath before helptags can be generated.
packloadall
" Load all of the helptags now, after plugins have been loaded.
" All messages and errors will be ignored.
silent! helptags ALL
```
#### [Vundle](https://github.com/VundleVim/Vundle.vim)
<a name="installation-with-pathogen"></a>
### 3.ii. Installation with Pathogen
To install this module with [Pathogen](https://github.com/tpope/vim-pathogen),
you should clone this repository to your bundle directory, and ensure
you have the line `execute pathogen#infect()` in your `~/.vimrc` file.
You can run the following commands in your terminal to do so:
```bash
cd ~/.vim/bundle
git clone https://github.com/w0rp/ale.git
```
<a name="installation-with-vundle"></a>
### 3.iii. Installation with Vundle
You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.vim)
by using the path on GitHub for this repository.
```vim
Plugin 'dense-analysis/ale'
Plugin 'w0rp/ale'
```
#### [Pathogen](https://github.com/tpope/vim-pathogen)
See the Vundle documentation for more information.
<a name="installation-with-vim-plug"></a>
### 3.iiii. Installation with Vim-Plug
You can install this plugin using [Vim-Plug](https://github.com/junegunn/vim-plug)
by adding the GitHub path for this repository to your `~/.vimrc`
and running `:PlugInstall`.
```vim
git clone https://github.com/dense-analysis/ale ~/.vim/bundle/ale
Plug 'w0rp/ale'
```
#### [lazy.nvim](https://github.com/folke/lazy.nvim)
```lua
{
'dense-analysis/ale',
config = function()
-- Configuration goes here.
local g = vim.g
<a name="contributing"></a>
g.ale_ruby_rubocop_auto_correct_all = 1
g.ale_linters = {
ruby = {'rubocop', 'ruby'},
lua = {'lua_language_server'}
}
end
}
```
## Contributing
## 4. Contributing
If you would like to see support for more languages and tools, please
[create an issue](https://github.com/dense-analysis/ale/issues)
or [create a pull request](https://github.com/dense-analysis/ale/pulls).
[create an issue](https://github.com/w0rp/ale/issues)
or [create a pull request](https://github.com/w0rp/ale/pulls).
If your tool can read from stdin or you have code to suggest which is good,
support can be happily added for it.
If you are interested in the general direction of the project, check out the
[wiki home page](https://github.com/dense-analysis/ale/wiki). The wiki includes
a Roadmap for the future, and more.
[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a
Roadmap for the future, and more.
If you'd liked to discuss ALE and more check out the Dense Analysis Discord
server here: https://discord.gg/5zFD6pQxDk
If you'd liked to discuss the project more directly, check out the `#vim-ale` channel
on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels=vim-ale).
## FAQ
<a name="faq"></a>
## 5. FAQ
<a name="faq-disable-linters"></a>
### How do I disable particular linters?
### 5.i. How do I disable particular linters?
By default, all available tools for all supported languages will be run. If you
want to only select a subset of the tools, you can define `b:ale_linters` for a
@@ -384,51 +377,20 @@ This plugin will look for linters in the [`ale_linters`](ale_linters) directory.
Each directory within corresponds to a particular filetype in Vim, and each file
in each directory corresponds to the name of a particular linter.
### How do I disable a particular warning or error?
Warnings and errors should be configured in project configuration files for the
relevant tools. ALE supports disabling only warnings relating to trailing
whitespace, which Vim users often fix automatically.
```vim
" Disable whitespace warnings
let g:ale_warn_about_trailing_whitespace = 0
```
Users generally should not ignore warnings or errors in projects by changing
settings in their own editor. Instead, configure tools appropriately so any
other user of the same project will see the same problems.
<a name="faq-get-info"></a>
### How can I see what ALE has configured for the current file?
Run the following to see what is currently configured:
```vim
:ALEInfo
```
### How can I disable virtual text appearing at ends of lines?
By default, ALE displays errors and warnings with virtual text. The problems ALE
shows appear with comment-like syntax after every problem found. You can set ALE
to only show problems where the cursor currently lies like so.
```vim
let g:ale_virtualtext_cursor = 'current'
```
If you want to disable virtual text completely, apply the following.
```vim
let g:ale_virtualtext_cursor = 'disabled'
```
<a name="faq-keep-signs"></a>
### 5.ii. How can I keep the sign gutter open?
You can keep the sign gutter open at all times by setting the
`g:ale_sign_column_always` to 1
```vim
let g:ale_sign_column_always = 1
```
<a name="faq-change-signs"></a>
### How can I customise signs?
### 5.iii. How can I change the signs ALE uses?
Use these options to specify what text should be used for signs:
@@ -446,15 +408,9 @@ highlight clear ALEErrorSign
highlight clear ALEWarningSign
```
You can configure the sign gutter open at all times, if you wish.
```vim
let g:ale_sign_column_always = 1
```
<a name="faq-change-highlights"></a>
### How can I change or disable the highlights ALE uses?
### 5.iv. How can I change or disable the highlights ALE uses?
ALE's highlights problems with highlight groups which link to `SpellBad`,
`SpellCap`, `error`, and `todo` groups by default. The characters that are
@@ -478,51 +434,9 @@ highlight ALEWarning ctermbg=DarkMagenta
See `:help ale-highlights` for more information.
<a name="faq-echo-format"></a>
### How can I change the format for echo messages?
There are 3 global options that allow customizing the echoed message.
- `g:ale_echo_msg_format` where:
* `%s` is the error message itself
* `%...code...%` is an optional error code, and most characters can be
written between the `%` characters.
* `%linter%` is the linter name
* `%severity%` is the severity type
- `g:ale_echo_msg_error_str` is the string used for error severity.
- `g:ale_echo_msg_warning_str` is the string used for warning severity.
So for example this:
```vim
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
```
Will give you:
![Echoed message](https://user-images.githubusercontent.com/3518142/59195927-348bd000-8b85-11e9-88b6-508a094f1548.png)
See `:help g:ale_echo_msg_format` for more information.
<a name="faq-statusline"></a>
<a name="faq-lightline"></a>
### How can I customise the statusline?
#### lightline
[lightline](https://github.com/itchyny/lightline.vim) does not have built-in
support for ALE, nevertheless there is a plugin that adds this functionality:
[maximbaz/lightline-ale](https://github.com/maximbaz/lightline-ale).
For more information, check out the sources of that plugin,
`:help ale#statusline#Count()` and
[lightline documentation](https://github.com/itchyny/lightline.vim#advanced-configuration).
#### vim-airline
### 5.v. How can I show errors or warnings in my statusline?
[vim-airline](https://github.com/vim-airline/vim-airline) integrates with ALE
for displaying error information in the status bar. If you want to see the
@@ -534,10 +448,9 @@ The airline extension can be enabled by adding the following to your vimrc:
let g:airline#extensions#ale#enabled = 1
```
#### Custom statusline
You can implement your own statusline function without adding any other plugins.
ALE provides some functions to assist in this endeavour, including:
If you don't want to use vim-airline, you can implement your own statusline
function without adding any other plugins. ALE provides some functions to
assist in this endeavour, including:
* `ale#statusline#Count`: Which returns the number of problems found by ALE
for a specified buffer.
@@ -570,136 +483,47 @@ set statusline=%{LinterStatus()}
See `:help ale#statusline#Count()` or `:help ale#statusline#FirstProblem()`
for more information.
<a name="faq-window-borders"></a>
<a name="faq-lightline"></a>
### How can I change the borders for floating preview windows?
### 5.vi. How can I show errors or warnings in my lightline?
Borders for floating preview windows are enabled by default. You can use the
`g:ale_floating_window_border` setting to configure them.
[lightline](https://github.com/itchyny/lightline.vim) does not have built-in
support for ALE, nevertheless there is a plugin that adds this functionality: [maximbaz/lightline-ale](https://github.com/maximbaz/lightline-ale).
You could disable the border with an empty list.
For more information, check out the sources of that plugin, `:help ale#statusline#Count()` and [lightline documentation](https://github.com/itchyny/lightline.vim#advanced-configuration).
<a name="faq-echo-format"></a>
### 5.vii. How can I change the format for echo messages?
There are 3 global options that allow customizing the echoed message.
- `g:ale_echo_msg_format` where:
* `%s` is the error message itself
* `%...code...%` is an optional error code, and most characters can be
written between the `%` characters.
* `%linter%` is the linter name
* `%severity%` is the severity type
- `g:ale_echo_msg_error_str` is the string used for error severity.
- `g:ale_echo_msg_warning_str` is the string used for warning severity.
So for example this:
```vim
let g:ale_floating_window_border = []
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
```
If the terminal supports Unicode, you might try setting the value like below, to
make it look nicer.
Will give you:
```vim
let g:ale_floating_window_border = ['│', '─', '╭', '╮', '╯', '╰', '│', '─']
```
![Echoed message](img/echo.png)
Since vim's default uses nice Unicode characters when possible, you can trick
ale into using that default with
```vim
let g:ale_floating_window_border = repeat([''], 8)
```
<a name="faq-my-battery-is-sad"></a>
### Will this plugin eat all of my laptop battery power?
ALE takes advantage of the power of various tools to check your code. This of
course means that CPU time will be used to continuously check your code. If you
are concerned about the CPU time ALE will spend, which will of course imply
some cost to battery life, you can adjust your settings to make your CPU do
less work.
First, consider increasing the delay before which ALE will run any linters
while you type. ALE uses a timeout which is cancelled and reset every time you
type, and this delay can be increased so linters are run less often. See
`:help g:ale_lint_delay` for more information.
If you don't wish to run linters while you type, you can disable that behavior.
Set `g:ale_lint_on_text_changed` to `never`. You won't get as frequent error
checking, but ALE shouldn't block your ability to edit a document after you save
a file, so the asynchronous nature of the plugin will still be an advantage.
If you are still concerned, you can turn the automatic linting off altogether,
including the option `g:ale_lint_on_enter`, and you can run ALE manually with
`:ALELint`.
<a name="faq-coc-nvim"></a>
<a name="faq-vim-lsp"></a>
### How can I use ALE with other LSP clients?
ALE offers an API for letting any other plugin integrate with ALE. If you are
interested in writing an integration, see `:help ale-lint-other-sources`.
If you're running ALE in Neovim with
[nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) for configuring
particular language servers, ALE will automatically disable its LSP
functionality for any language servers configured with nvim-lspconfig by
default. The following setting is applied by default:
```vim
let g:ale_disable_lsp = 'auto'
```
If you are running ALE in combination with another LSP client, you may wish to
disable ALE's LSP functionality entirely. You can change the setting to `1` to
always disable all LSP functionality.
```vim
let g:ale_disable_lsp = 1
```
You can also use `b:ale_disable_lsp` in your ftplugin files to enable or disable
LSP features in ALE for different filetypes.
#### Neovim Diagnostics
If you are running Neovim 0.7 or later, you can make ALE display errors and
warnings via the Neovim diagnostics API.
```vim
let g:ale_use_neovim_diagnostics_api = 1
```
<!-- We could expand this section to say a little more. -->
#### coc.nvim
[coc.nvim](https://github.com/neoclide/coc.nvim) is a popular Vim plugin written
in TypeScript and dependent on the [npm](https://www.npmjs.com/) ecosystem for
providing full IDE features to Vim. Both ALE and coc.nvim implement
[Language Server Protocol](https://microsoft.github.io/language-server-protocol/)
(LSP) clients for supporting diagnostics (linting with a live server), and other
features like auto-completion, and others listed above.
ALE is primarily focused on integrating with external programs through virtually
any means, provided the plugin remains almost entirely written in Vim script.
coc.nvim is primarily focused on bringing IDE features to Vim. If you want to
run external programs on your files to check for errors, and also use the most
advanced IDE features, you might want to use both plugins at the same time.
The easiest way to get both plugins to work together is to configure coc.nvim to
send diagnostics to ALE, so ALE controls how all problems are presented to you,
and to disable all LSP features in ALE, so ALE doesn't try to provide LSP
features already provided by coc.nvim, such as auto-completion.
Open your coc.nvim configuration file with `:CocConfig` and add
`"diagnostic.displayByAle": true` to your settings.
#### vim-lsp
[vim-lsp](https://github.com/prabirshrestha/vim-lsp) is a popular plugin as
implementation of Language Server Protocol (LSP) client for Vim. It provides
all the LSP features including auto completion, diagnostics, go to definitions,
etc.
[vim-lsp-ale](https://github.com/rhysd/vim-lsp-ale) is a bridge plugin to solve
the problem when using both ALE and vim-lsp. With the plugin, diagnostics are
provided by vim-lsp and ALE can handle all the errors. Please read
[vim-lsp-ale's documentation](https://github.com/rhysd/vim-lsp-ale/blob/master/doc/vim-lsp-ale.txt)
for more details.
See `:help g:ale_echo_msg_format` for more information.
<a name="faq-autocmd"></a>
### How can I execute some code when ALE starts or stops linting?
### 5.viii. How can I execute some code when ALE starts or stops linting?
ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html)
events when a lint or fix cycle are started and stopped. There is also an event
@@ -722,7 +546,7 @@ augroup END
<a name="faq-navigation"></a>
### How can I navigate between errors quickly?
### 5.ix. How can I navigate between errors quickly?
ALE offers some commands with `<Plug>` keybinds for moving between warnings and
errors quickly. You can map the keys Ctrl+j and Ctrl+k to moving between errors
@@ -738,31 +562,31 @@ For more information, consult the online documentation with
<a name="faq-lint-on-save"></a>
### How can I run linters only when I save files?
### 5.x. How can I run linters only when I save files?
ALE offers an option `g:ale_lint_on_save` for enabling running the linters when
files are saved. This option is enabled by default. If you only wish to run
linters when files are saved, you can turn the other options off.
ALE offers an option `g:ale_lint_on_save` for enabling running the linters
when files are saved. This option is enabled by default. If you only
wish to run linters when files are saved, you can turn the other
options off.
```vim
" Write this in your vimrc file
let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_insert_leave = 0
" You can disable this option too
" if you don't want linters to run on opening a file
let g:ale_lint_on_enter = 0
```
If for whatever reason you don't wish to run linters again when you save files,
you can set `g:ale_lint_on_save` to `0`.
If for whatever reason you don't wish to run linters again when you save
files, you can set `g:ale_lint_on_save` to `0`.
<a name="faq-quickfix"></a>
### How can I use the quickfix list instead of the loclist?
### 5.xi. How can I use the quickfix list instead of the loclist?
The quickfix list can be enabled by turning the `g:ale_set_quickfix` option on.
If you wish to also disable the loclist, you can disable the `g:ale_set_loclist`
option.
The quickfix list can be enabled by turning the `g:ale_set_quickfix`
option on. If you wish to also disable the loclist, you can disable
the `g:ale_set_loclist` option.
```vim
" Write this in your vimrc file
@@ -770,10 +594,10 @@ let g:ale_set_loclist = 0
let g:ale_set_quickfix = 1
```
If you wish to show Vim windows for the loclist or quickfix items when a file
contains warnings or errors, `g:ale_open_list` can be set to `1`.
`g:ale_keep_list_window_open` can be set to `1` if you wish to keep the window
open even after errors disappear.
If you wish to show Vim windows for the loclist or quickfix items
when a file contains warnings or errors, `g:ale_open_list` can be
set to `1`. `g:ale_keep_list_window_open` can be set to `1`
if you wish to keep the window open even after errors disappear.
```vim
let g:ale_open_list = 1
@@ -786,11 +610,12 @@ let g:ale_keep_list_window_open = 1
You can also set `let g:ale_list_vertical = 1` to open the windows vertically
instead of the default horizontally.
### Why isn't ALE checking my filetype?
<a name="faq-jsx-stylelint-eslint"></a>
#### stylelint for JSX
### 5.xii. How can I check JSX files with both stylelint and eslint?
If you configure ALE options correctly in your vimrc file, and install
the right tools, you can check JSX files with stylelint and eslint.
First, install eslint and install stylelint with
[stylelint-processor-styled-components](https://github.com/styled-components/stylelint-processor-styled-components).
@@ -829,7 +654,7 @@ no linter will be run twice for the same file.
<a name="faq-vue-eslint"></a>
#### Checking Vue with ESLint
### 5.xiii. How can I check Vue files with ESLint?
To check Vue files with ESLint, your ESLint project configuration file must be
configured to use the [Vue plugin](https://github.com/vuejs/eslint-plugin-vue).
@@ -858,9 +683,34 @@ let g:ale_linter_aliases = {'vue': ['vue', 'javascript']}
let g:ale_linters = {'vue': ['eslint', 'vls']}
```
<a name="faq-my-battery-is-sad"></a>
### 5.xiv. Will this plugin eat all of my laptop battery power?
ALE takes advantage of the power of various tools to check your code. This of
course means that CPU time will be used to continuously check your code. If you
are concerned about the CPU time ALE will spend, which will of course imply
some cost to battery life, you can adjust your settings to make your CPU do
less work.
First, consider increasing the delay before which ALE will run any linters
while you type. ALE uses a timeout which is cancelled and reset every time you
type, and this delay can be increased so linters are run less often. See
`:help g:ale_lint_delay` for more information.
If you don't wish to run linters while you type, you can disable that
behaviour. Set `g:ale_lint_on_text_changed` to `never` or `normal`. You won't
get as frequent error checking, but ALE shouldn't block your ability to edit a
document after you save a file, so the asynchronous nature of the plugin will
still be an advantage.
If you are still concerned, you can turn the automatic linting off altogether,
including the option `g:ale_lint_on_enter`, and you can run ALE manually with
`:ALELint`.
<a name="faq-c-configuration"></a>
### How can I configure my C or C++ project?
### 5.xv. How can I configure my C or C++ project?
The structure of C and C++ projects varies wildly from project to project, with
many different build tools being used for building them, and many different
@@ -880,24 +730,63 @@ setting. Consult the documentation for that setting for more information.
`b:ale_linters` can be used to select which tools you want to run, say if you
want to use only `gcc` for one project, and only `clang` for another.
ALE will attempt to parse `compile_commands.json` files to discover compiler
flags to use when linting code. See `:help g:ale_c_parse_compile_commands` for
more information. See Clang's documentation for
[compile_commands.json files](https://clang.llvm.org/docs/JSONCompilationDatabase.html).
You should strongly consider generating them in your builds, which is easy to do
with CMake.
You may also configure buffer-local settings for linters with project-specific
vimrc files. [local_vimrc](https://github.com/LucHermitte/local_vimrc) can be
used for executing local vimrc files which can be shared in your project.
You can also configure ALE to automatically run `make -n` to run dry runs on
`Makefile`s to discover compiler flags. This can execute arbitrary code, so the
option is disabled by default. See `:help g:ale_c_parse_makefile`.
<a name="faq-buffer-configuration"></a>
<a name="faq-vm"></a>
### 5.xvi. How can I configure ALE differently for different buffers?
### How can I run linters or fixers via Docker or a VM?
ALE offers various ways to configure which linters or fixers are run, and
other settings. For the majority of ALE's settings, they can either be
configured globally with a `g:` variable prefix, or for a specific buffer
with a `b:` variable prefix. For example, you can configure a Python ftplugin
file like so.
ALE supports running linters or fixers via Docker, virtual machines, or in
combination with any remote machine with a different file system, so long as the
tools are well-integrated with ALE, and ALE is properly configured to run the
correct commands and map filename paths between different file systems. See
`:help ale-lint-other-machines` for the full documentation on how to configure
ALE to support this.
```vim
" In ~/.vim/ftplugin/python.vim
" Check Python files with flake8 and pylint.
let b:ale_linters = ['flake8', 'pylint']
" Fix Python files with autopep8 and yapf.
let b:ale_fixers = ['autopep8', 'yapf']
" Disable warnings about trailing whitespace for Python files.
let b:ale_warn_about_trailing_whitespace = 0
```
For configuring files based on regular expression patterns matched against the
absolute path to a file, you can use `g:ale_pattern_options`.
```vim
" Do not lint or fix minified files.
let g:ale_pattern_options = {
\ '\.min\.js$': {'ale_linters': [], 'ale_fixers': []},
\ '\.min\.css$': {'ale_linters': [], 'ale_fixers': []},
\}
" If you configure g:ale_pattern_options outside of vimrc, you need this.
let g:ale_pattern_options_enabled = 1
```
Buffer-local variables for settings always override the global settings.
<a name="faq-list-window-height"></a>
### 5.xvii. How can I configure the height of the list in which ALE displays errors?
To set a default height for the error list, use the `g:ale_list_window_size` variable.
```vim
" Show 5 lines of errors (default: 10)
let g:ale_list_window_size = 5
```
<a name="faq-get-info"></a>
### 5.xviii. How can I see what ALE has configured for the current file?
Run the following to see what is currently configured:
```vim
:ALEInfo
```

View File

@@ -1,26 +0,0 @@
" Author: Bartek Jasicki http://github.com/thindil
" Description: Support for Ada Language Server
call ale#Set('ada_adals_executable', 'ada_language_server')
call ale#Set('ada_adals_project', 'default.gpr')
call ale#Set('ada_adals_encoding', 'utf-8')
function! ale_linters#ada#adals#GetAdaLSConfig(buffer) abort
return {
\ 'ada.projectFile': ale#Var(a:buffer, 'ada_adals_project'),
\ 'ada.defaultCharset': ale#Var(a:buffer, 'ada_adals_encoding')
\}
endfunction
function! ale_linters#ada#adals#GetRootDirectory(buffer) abort
return fnamemodify(bufname(a:buffer), ':p:h')
endfunction
call ale#linter#Define('ada', {
\ 'name': 'adals',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'ada_adals_executable')},
\ 'command': '%e',
\ 'project_root': function('ale_linters#ada#adals#GetRootDirectory'),
\ 'lsp_config': function('ale_linters#ada#adals#GetAdaLSConfig')
\})

View File

@@ -1,5 +0,0 @@
scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: cspell support for Ada files.
call ale#handlers#cspell#DefineLinter('ada')

View File

@@ -18,7 +18,7 @@ function! ale_linters#ada#gcc#GetCommand(buffer) abort
" -gnatc: Check syntax and semantics only (no code generation attempted)
return '%e -x ada -c -gnatc'
\ . ' -o ' . ale#Escape(l:out_file)
\ . ' -I %s:h'
\ . ' -I ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(ale#Var(a:buffer, 'ada_gcc_options'))
\ . ' %t'
endfunction

View File

@@ -1,4 +1,4 @@
" Authors: Bjorn Neergaard <bjorn@neersighted.com>, Vytautas Macionis <vytautas.macionis@manomail.de>
" Author: Bjorn Neergaard <bjorn@neersighted.com>
" Description: ansible-lint for ansible-yaml files
call ale#Set('ansible_ansible_lint_executable', 'ansible-lint')
@@ -7,7 +7,7 @@ function! ale_linters#ansible#ansible_lint#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'ansible_ansible_lint_executable')
endfunction
function! ale_linters#ansible#ansible_lint#Handle(buffer, version, lines) abort
function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort
for l:line in a:lines[:10]
if match(l:line, '^Traceback') >= 0
return [{
@@ -18,121 +18,39 @@ function! ale_linters#ansible#ansible_lint#Handle(buffer, version, lines) abort
endif
endfor
let l:version_group = ale#semver#GTE(a:version, [6, 0, 0]) ? '>=6.0.0' :
\ ale#semver#GTE(a:version, [5, 0, 0]) ? '>=5.0.0' :
\ '<5.0.0'
" Matches patterns line the following:
"
" test.yml:35: [EANSIBLE0002] Trailing whitespace
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: \[?([[:alnum:]]+)\]? (.*)$'
let l:output = []
if '>=6.0.0' is# l:version_group
let l:error_codes = { 'blocker': 'E', 'critical': 'E', 'major': 'W', 'minor': 'W', 'info': 'I' }
let l:linter_issues = ale#util#FuzzyJSONDecode(a:lines, [])
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:code = l:match[4]
for l:issue in l:linter_issues
if ale#path#IsBufferPath(a:buffer, l:issue.location.path)
if exists('l:issue.location.positions')
let l:coord_keyname = 'positions'
else
let l:coord_keyname = 'lines'
endif
if l:code is# 'EANSIBLE0002'
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
" Skip warnings for trailing whitespace if the option is off.
continue
endif
let l:column_member = printf(
\ 'l:issue.location.%s.begin.column', l:coord_keyname
\)
call add(l:output, {
\ 'lnum': exists(l:column_member) ? l:issue.location[l:coord_keyname].begin.line :
\ l:issue.location[l:coord_keyname].begin,
\ 'col': exists(l:column_member) ? l:issue.location[l:coord_keyname].begin.column : 0,
\ 'text': l:issue.check_name,
\ 'detail': l:issue.description,
\ 'code': l:issue.severity,
\ 'type': l:error_codes[l:issue.severity],
\})
endif
endfor
endif
if '>=5.0.0' is# l:version_group
" Matches patterns line the following:
" test.yml:3:148: syntax-check 'var' is not a valid attribute for a Play
" roles/test/tasks/test.yml:8: [package-latest] [VERY_LOW] Package installs should not use latest
" D:\test\tasks\test.yml:8: [package-latest] [VERY_LOW] package installs should not use latest
let l:pattern = '\v^(%([a-zA-Z]:)?[^:]+):(\d+):%((\d+):)? %(\[([-[:alnum:]]+)\]) %(\[([_[:alnum:]]+)\]) (.*)$'
let l:error_codes = { 'VERY_HIGH': 'E', 'HIGH': 'E', 'MEDIUM': 'W', 'LOW': 'W', 'VERY_LOW': 'W', 'INFO': 'I' }
for l:match in ale#util#GetMatches(a:lines, l:pattern)
if ale#path#IsBufferPath(a:buffer, l:match[1])
call add(l:output, {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[6],
\ 'code': l:match[4],
\ 'type': l:error_codes[l:match[5]],
\})
endif
endfor
endif
if '<5.0.0' is# l:version_group
" Matches patterns line the following:
" test.yml:35: [EANSIBLE0002] Trailing whitespace
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: \[?([[:alnum:]]+)\]? (.*)$'
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:code = l:match[4]
if l:code is# 'EANSIBLE0002'
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
" Skip warnings for trailing whitespace if the option is off.
continue
endif
if ale#path#IsBufferPath(a:buffer, l:match[1])
call add(l:output, {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[5],
\ 'code': l:code,
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
\})
endif
endfor
endif
if ale#path#IsBufferPath(a:buffer, l:match[1])
call add(l:output, {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[5],
\ 'code': l:code,
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
\})
endif
endfor
return l:output
endfunction
function! ale_linters#ansible#ansible_lint#GetCommand(buffer, version) abort
let l:commands = {
\ '>=6.0.0': '%e --nocolor -f json -x yaml %s',
\ '>=5.0.0': '%e --nocolor --parseable-severity -x yaml %s',
\ '<5.0.0': '%e --nocolor -p %t'
\}
let l:command = ale#semver#GTE(a:version, [6, 0]) ? l:commands['>=6.0.0'] :
\ ale#semver#GTE(a:version, [5, 0]) ? l:commands['>=5.0.0'] :
\ l:commands['<5.0.0']
return l:command
endfunction
call ale#linter#Define('ansible', {
\ 'name': 'ansible_lint',
\ 'aliases': ['ansible', 'ansible-lint'],
\ 'executable': function('ale_linters#ansible#ansible_lint#GetExecutable'),
\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ buffer,
\ ale_linters#ansible#ansible_lint#GetExecutable(buffer),
\ '%e --version',
\ function('ale_linters#ansible#ansible_lint#GetCommand'),
\ )},
\ 'lint_file': 1,
\ 'callback': {buffer, lines -> ale#semver#RunWithVersionCheck(
\ buffer,
\ ale_linters#ansible#ansible_lint#GetExecutable(buffer),
\ '%e --version',
\ {buffer, version -> ale_linters#ansible#ansible_lint#Handle(
\ buffer,
\ l:version,
\ lines)},
\ )},
\ 'command': '%e -p %t',
\ 'callback': 'ale_linters#ansible#ansible_lint#Handle',
\})

View File

@@ -1,47 +0,0 @@
" Author: Horacio Sanson <https://github.com/hsanson>
" Description: Support ansible language server https://github.com/ansible/ansible-language-server/
call ale#Set('ansible_language_server_executable', 'ansible-language-server')
call ale#Set('ansible_language_server_config', {})
function! ale_linters#ansible#language_server#Executable(buffer) abort
return ale#Var(a:buffer, 'ansible_language_server_executable')
endfunction
function! ale_linters#ansible#language_server#GetCommand(buffer) abort
let l:executable = ale_linters#ansible#language_server#Executable(a:buffer)
return ale#Escape(l:executable) . ' --stdio'
endfunction
function! ale_linters#ansible#language_server#FindProjectRoot(buffer) abort
let l:dir = fnamemodify(
\ ale#path#FindNearestFile(a:buffer, 'ansible.cfg'),
\ ':h'
\)
if l:dir isnot# '.' && isdirectory(l:dir)
return l:dir
endif
let l:dir = fnamemodify(
\ ale#path#FindNearestDirectory(a:buffer, '.git'),
\ ':h:h'
\)
if l:dir isnot# '.' && isdirectory(l:dir)
return l:dir
endif
return ''
endfunction
call ale#linter#Define('ansible', {
\ 'name': 'language_server',
\ 'aliases': ['ansible_language_server', 'ansible-language-server'],
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#ansible#language_server#Executable'),
\ 'command': function('ale_linters#ansible#language_server#GetCommand'),
\ 'project_root': function('ale_linters#ansible#language_server#FindProjectRoot'),
\ 'lsp_config': {b -> ale#Var(b, 'ansible_language_server_config')}
\})

View File

@@ -1,12 +0,0 @@
" Author: Leo <thinkabit.ukim@gmail.com>
" Description: apkbuild-lint from atools linter for APKBUILDs
call ale#Set('apkbuild_apkbuild_lint_executable', 'apkbuild-lint')
call ale#linter#Define('apkbuild', {
\ 'name': 'apkbuild_lint',
\ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'apkbuild_apkbuild_lint_executable')},
\ 'command': '%e %t',
\ 'callback': 'ale#handlers#atools#Handle',
\})

View File

@@ -1,12 +0,0 @@
" Author: Leo <thinkabit.ukim@gmail.com>
" Description: secfixes-check from atools linter for APKBUILDs
call ale#Set('apkbuild_secfixes_check_executable', 'secfixes-check')
call ale#linter#Define('apkbuild', {
\ 'name': 'secfixes_check',
\ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'apkbuild_secfixes_check_executable')},
\ 'command': '%e %t',
\ 'callback': 'ale#handlers#atools#Handle',
\})

View File

@@ -1,5 +0,0 @@
scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: cspell support for ASCIIDoc files.
call ale#handlers#cspell#DefineLinter('asciidoc')

View File

@@ -1,5 +0,0 @@
" Author: Horacio Sanson (hsanson [ät] gmail.com)
" Description: languagetool for asciidoc files, copied from markdown.
call ale#handlers#languagetool#DefineLinter('asciidoc')

View File

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

View File

@@ -1,37 +0,0 @@
" Author: uidops <uidops@protonmail.com>
" Description: llvm-mc linter for asm files
call ale#Set('asm_llvm_mc_executable', 'llvm-mc')
call ale#Set('asm_llvm_mc_options', '')
function! ale_linters#asm#llvm_mc#GetCommand(buffer) abort
return '%e --assemble'
\ . ' --filetype=asm'
\ . ' -o ' . g:ale#util#nul_file
\ . ' ' . ale#Var(a:buffer, 'asm_llvm_mc_options')
endfunction
function! ale_linters#asm#llvm_mc#Handle(buffer, lines) abort
let l:pattern = '^.\+:\(\d\+\):\(\d\+\): \([^:]\+\): \(.\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'type': l:match[3] =~? 'error' ? 'E' : 'W',
\ 'text': l:match[4],
\})
endfor
return l:output
endfunction
call ale#linter#Define('asm', {
\ 'name': 'llvm_mc',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'asm_llvm_mc_executable')},
\ 'command': function('ale_linters#asm#llvm_mc#GetCommand'),
\ 'callback': 'ale_linters#asm#llvm_mc#Handle',
\})

View File

@@ -1,11 +0,0 @@
" Author: Hyuksang Kwon <gwonhyuksang@gmail.com>
" Description: eslint for astro files
call ale#linter#Define('astro', {
\ 'name': 'eslint',
\ 'output_stream': 'both',
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'cwd': function('ale#handlers#eslint#GetCwd'),
\ 'command': function('ale#handlers#eslint#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON',
\})

View File

@@ -1,36 +0,0 @@
" Author: Utkarsh Verma <utkarshverma@protonmail.com>
" Description: AVRA linter for avra syntax.
call ale#Set('avra_avra_executable', 'avra')
call ale#Set('avra_avra_options', '')
function! ale_linters#avra#avra#GetCommand(buffer) abort
return '%e'
\ . ' %t'
\ . ale#Pad(ale#Var(a:buffer, 'avra_avra_options'))
\ . ' -o ' . g:ale#util#nul_file
endfunction
function! ale_linters#avra#avra#Handle(buffer, lines) abort
" Note that we treat 'fatal' as errors.
let l:pattern = '^\S\+(\(\d\+\))\s\+:\s\+\(\S\+\)\s\+:\s\+\(.\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'type': l:match[2] =~? 'Error' ? 'E' : 'W',
\ 'text': l:match[3],
\})
endfor
return l:output
endfunction
call ale#linter#Define('avra', {
\ 'name': 'avra',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'avra_avra_executable')},
\ 'command': function('ale_linters#avra#avra#GetCommand'),
\ 'callback': 'ale_linters#avra#avra#Handle',
\})

View File

@@ -1,5 +1,5 @@
" Author: kmarc <korondi.mark@gmail.com>
" Description: This file adds support for using GNU awk with scripts.
" Description: This file adds support for using GNU awk with sripts.
call ale#Set('awk_gawk_executable', 'gawk')
call ale#Set('awk_gawk_options', '')
@@ -9,9 +9,8 @@ function! ale_linters#awk#gawk#GetCommand(buffer) abort
" gawk from attempting to execute the body of the script
" it is linting.
return '%e --source ' . ale#Escape('BEGIN { exit } END { exit 1 }')
\ . ' --lint'
\ . ale#Pad(ale#Var(a:buffer, 'awk_gawk_options'))
\ . ' -f %t /dev/null'
\ . ' -f %t --lint /dev/null'
endfunction
call ale#linter#Define('awk', {

View File

@@ -1,4 +0,0 @@
" Author: Ian2020 <https://github.com/Ian2020>
" Description: shellcheck linter for bats scripts.
call ale#handlers#shellcheck#DefineLinter('bats')

View File

@@ -18,12 +18,7 @@ function! ale_linters#bib#bibclean#get_type(str) abort
endfunction
function! ale_linters#bib#bibclean#match_msg(line) abort
" Legacy message pattern works for bibclean <= v2.11.4. If empty, try
" the new message pattern for bibtex > v2.11.4
let l:matches_legacy = matchlist(a:line, '^\(.*\) "stdin", line \(\d\+\): \(.*\)$')
return ! empty(l:matches_legacy) ? l:matches_legacy
\ : matchlist(a:line, '^\(.*\) stdin:\(\d\+\):\(.*\)$')
return matchlist(a:line, '^\(.*\) "stdin", line \(.*\): \(.*\)$')
endfunction
function! ale_linters#bib#bibclean#match_entry(line) abort

View File

@@ -1,69 +0,0 @@
" Author: Carl Smedstad <carl.smedstad at protonmail dot com>
" Description: az_bicep for bicep files
let g:ale_bicep_az_bicep_executable =
\ get(g:, 'ale_bicep_az_bicep_executable', 'az')
let g:ale_bicep_az_bicep_options =
\ get(g:, 'ale_bicep_az_bicep_options', '')
function! ale_linters#bicep#az_bicep#Executable(buffer) abort
return ale#Var(a:buffer, 'bicep_az_bicep_executable')
endfunction
function! ale_linters#bicep#az_bicep#Command(buffer) abort
let l:executable = ale_linters#bicep#az_bicep#Executable(a:buffer)
let l:options = ale#Var(a:buffer, 'bicep_az_bicep_options')
if has('win32')
let l:nullfile = 'NUL'
else
let l:nullfile = '/dev/null'
endif
return ale#Escape(l:executable)
\ . ' bicep build --outfile '
\ . l:nullfile
\ . ' --file '
\ . '%s '
\ . l:options
endfunction
function! ale_linters#bicep#az_bicep#Handle(buffer, lines) abort
let l:pattern = '\v^([A-Z]+)?(:\s)?(.*)\((\d+),(\d+)\)\s:\s([a-zA-Z]*)\s([-a-zA-Z0-9]*):\s(.*)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
if l:match[1] is# 'ERROR'
let l:type = 'E'
elseif l:match[1] is# 'WARNING'
let l:type = 'W'
elseif l:match[6] is# 'Error'
let l:type = 'E'
elseif l:match[6] is# 'Warning'
let l:type = 'W'
else
let l:type = 'I'
endif
call add(l:output, {
\ 'filename': l:match[3],
\ 'lnum': l:match[4] + 0,
\ 'col': l:match[5] + 0,
\ 'type': l:type,
\ 'code': l:match[7],
\ 'text': l:match[8],
\})
endfor
return l:output
endfunction
call ale#linter#Define('bicep', {
\ 'name': 'az_bicep',
\ 'executable': function('ale_linters#bicep#az_bicep#Executable'),
\ 'command': function('ale_linters#bicep#az_bicep#Command'),
\ 'callback': 'ale_linters#bicep#az_bicep#Handle',
\ 'output_stream': 'stderr',
\ 'lint_file': 1,
\})

View File

@@ -1,65 +0,0 @@
" Author: Carl Smedstad <carl.smedstad at protonmail dot com>
" Description: bicep for bicep files
let g:ale_bicep_bicep_executable =
\ get(g:, 'ale_bicep_bicep_executable', 'bicep')
let g:ale_bicep_bicep_options =
\ get(g:, 'ale_bicep_bicep_options', '')
function! ale_linters#bicep#bicep#Executable(buffer) abort
return ale#Var(a:buffer, 'bicep_bicep_executable')
endfunction
function! ale_linters#bicep#bicep#Command(buffer) abort
let l:executable = ale_linters#bicep#bicep#Executable(a:buffer)
let l:options = ale#Var(a:buffer, 'bicep_bicep_options')
if has('win32')
let l:nullfile = 'NUL'
else
let l:nullfile = '/dev/null'
endif
return ale#Escape(l:executable)
\ . ' build --outfile '
\ . l:nullfile
\ . ' '
\ . l:options
\ . ' %s'
endfunction
function! ale_linters#bicep#bicep#Handle(buffer, lines) abort
let l:pattern = '\v^(.*)\((\d+),(\d+)\)\s:\s([a-zA-Z]*)\s([-a-zA-Z0-9]*):\s(.*)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
if l:match[4] is# 'Error'
let l:type = 'E'
elseif l:match[4] is# 'Warning'
let l:type = 'W'
else
let l:type = 'I'
endif
call add(l:output, {
\ 'filename': l:match[1],
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'type': l:type,
\ 'code': l:match[5],
\ 'text': l:match[6],
\})
endfor
return l:output
endfunction
call ale#linter#Define('bicep', {
\ 'name': 'bicep',
\ 'executable': function('ale_linters#bicep#bicep#Executable'),
\ 'command': function('ale_linters#bicep#bicep#Command'),
\ 'callback': 'ale_linters#bicep#bicep#Handle',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})

View File

@@ -1,47 +0,0 @@
" Author: offa
" Description: oelint-adv for BitBake files
call ale#Set('bitbake_oelint_adv_executable', 'oelint-adv')
call ale#Set('bitbake_oelint_adv_options', '')
call ale#Set('bitbake_oelint_adv_config', '.oelint.cfg')
function! ale_linters#bitbake#oelint_adv#Command(buffer) abort
let l:config_file = ale#path#FindNearestFile(a:buffer,
\ ale#Var(a:buffer, 'bitbake_oelint_adv_config'))
return ((!empty(l:config_file))
\ ? 'OELINT_CONFIG=' . ale#Escape(l:config_file) . ' '
\ : '')
\ . '%e --quiet '
\ . ale#Pad(ale#Var(a:buffer, 'bitbake_oelint_adv_options')) . '%s'
endfunction
function! ale_linters#bitbake#oelint_adv#Handle(buffer, lines) abort
let l:pattern = '\v^(.+):(.+):(.+):(.+):(.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': str2nr(l:match[2]),
\ 'type': l:match[3] is# 'error'
\ ? 'E' : (l:match[3] is# 'warning' ? 'W' : 'I'),
\ 'text': StripAnsiCodes(l:match[5]),
\ 'code': l:match[4]
\ })
endfor
return l:output
endfunction
function! StripAnsiCodes(line) abort
return substitute(a:line, '\e\[[0-9;]\+[mK]', '', 'g')
endfunction
call ale#linter#Define('bitbake', {
\ 'name': 'oelint_adv',
\ 'output_stream': 'both',
\ 'executable': {b -> ale#Var(b, 'bitbake_oelint_adv_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#bitbake#oelint_adv#Command'),
\ 'callback': 'ale_linters#bitbake#oelint_adv#Handle',
\ })

View File

@@ -1,40 +0,0 @@
" Author: Chuck Grindel <chuck.grindel@gmail.com>
" Description: Bazel Starlark lint support using buildifier.
function! ale_linters#bzl#buildifier#GetCommand(buffer) abort
let l:executable = ale#Escape(ale#fixers#buildifier#GetExecutable(a:buffer))
let l:options = ale#Var(a:buffer, 'bazel_buildifier_options')
let l:filename = ale#Escape(bufname(a:buffer))
let l:command = l:executable . ' -mode check -lint warn -path %s'
if l:options isnot# ''
let l:command .= ' ' . l:options
endif
return l:command
endfunction
function! ale_linters#bzl#buildifier#Handle(buffer, lines) abort
let l:pattern = '\v^[^:]+:(\d+):(\d+)?:?\s+(syntax error near)?(.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3] . l:match[4],
\ 'type': l:match[3] is# 'syntax error near' ? 'E' : 'W',
\})
endfor
return l:output
endfunction
call ale#linter#Define('bzl', {
\ 'name': 'buildifier',
\ 'output_stream': 'both',
\ 'executable': function('ale#fixers#buildifier#GetExecutable'),
\ 'command': function('ale_linters#bzl#buildifier#GetCommand'),
\ 'callback': function('ale_linters#bzl#buildifier#Handle'),
\})

View File

@@ -1,67 +0,0 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: A C compiler linter for C files with gcc/clang, etc.
call ale#Set('c_cc_executable', '<auto>')
call ale#Set('c_cc_options', '-std=c11 -Wall')
call ale#Set('c_cc_use_header_lang_flag', -1)
call ale#Set('c_cc_header_exts', ['h'])
function! ale_linters#c#cc#GetExecutable(buffer) abort
let l:executable = ale#Var(a:buffer, 'c_cc_executable')
" Default to either clang or gcc.
if l:executable is# '<auto>'
if ale#engine#IsExecutable(a:buffer, 'clang')
let l:executable = 'clang'
else
let l:executable = 'gcc'
endif
endif
return l:executable
endfunction
function! ale_linters#c#cc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:ale_flags = ale#Var(a:buffer, 'c_cc_options')
if l:cflags =~# '-std='
let l:ale_flags = substitute(
\ l:ale_flags,
\ '-std=\(c\|gnu\)[0-9]\{2\}',
\ '',
\ 'g')
endif
" Select the correct language flag depending on the executable, options
" and file extension
let l:executable = ale_linters#c#cc#GetExecutable(a:buffer)
let l:use_header_lang_flag = ale#Var(a:buffer, 'c_cc_use_header_lang_flag')
let l:header_exts = ale#Var(a:buffer, 'c_cc_header_exts')
let l:lang_flag = ale#c#GetLanguageFlag(
\ a:buffer,
\ l:executable,
\ l:use_header_lang_flag,
\ l:header_exts,
\ 'c')
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
"
" `-o /dev/null` or `-o null` is needed to catch all errors,
" -fsyntax-only doesn't catch everything.
return '%e -S -x ' . l:lang_flag
\ . ' -o ' . g:ale#util#nul_file
\ . ' -iquote %s:h'
\ . ale#Pad(l:cflags)
\ . ale#Pad(l:ale_flags) . ' -'
endfunction
call ale#linter#Define('c', {
\ 'name': 'cc',
\ 'aliases': ['gcc', 'clang'],
\ 'output_stream': 'stderr',
\ 'executable': function('ale_linters#c#cc#GetExecutable'),
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#cc#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})

View File

@@ -3,7 +3,6 @@
call ale#Set('c_ccls_executable', 'ccls')
call ale#Set('c_ccls_init_options', {})
call ale#Set('c_build_dir', '')
call ale#linter#Define('c', {
\ 'name': 'ccls',
@@ -11,5 +10,5 @@ call ale#linter#Define('c', {
\ 'executable': {b -> ale#Var(b, 'c_ccls_executable')},
\ 'command': '%e',
\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'),
\ 'initialization_options': {b -> ale#handlers#ccls#GetInitOpts(b, 'c_ccls_init_options')},
\ 'initialization_options': {b -> ale#Var(b, 'c_ccls_init_options')},
\})

24
ale_linters/c/clang.vim Normal file
View File

@@ -0,0 +1,24 @@
" Author: Masahiro H https://github.com/mshr-h
" Description: clang linter for c files
call ale#Set('c_clang_executable', 'clang')
call ale#Set('c_clang_options', '-std=c11 -Wall')
function! ale_linters#c#clang#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return '%e -S -x c -fsyntax-only'
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(l:cflags)
\ . ale#Pad(ale#Var(a:buffer, 'c_clang_options')) . ' -'
endfunction
call ale#linter#Define('c', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_clang_executable')},
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clang#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})

View File

@@ -1,38 +0,0 @@
" Author: gagbo <gagbobada@gmail.com>
" : luibo <ng.akhoa98@gmail.com>
" : Jorengarenar <jorengarenar@outlook.com>
" Description: clang-check linter for C files
" modified from cpp/clangcheck.vim to match for C
call ale#Set('c_clangcheck_executable', 'clang-check')
call ale#Set('c_clangcheck_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#c#clangcheck#GetCommand(buffer) abort
let l:user_options = ale#Var(a:buffer, 'c_clangcheck_options')
" Try to find compilation database to link automatically
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
if empty(l:build_dir)
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
let l:build_dir = ale#path#Dirname(l:json_file)
endif
" The extra arguments in the command are used to prevent .plist files from
" being generated. These are only added if no build directory can be
" detected.
return '%e -analyze %s'
\ . (empty(l:build_dir) ? ' --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics': '')
\ . ale#Pad(l:user_options)
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
endfunction
call ale#linter#Define('c', {
\ 'name': 'clangcheck',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_clangcheck_executable')},
\ 'command': function('ale_linters#c#clangcheck#GetCommand'),
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

View File

@@ -3,14 +3,15 @@
call ale#Set('c_clangd_executable', 'clangd')
call ale#Set('c_clangd_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#c#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#c#clangd#GetCommand(buffer) abort
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
return '%e'
\ . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
\ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '')
return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
endfunction
call ale#linter#Define('c', {
@@ -18,5 +19,5 @@ call ale#linter#Define('c', {
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'c_clangd_executable')},
\ 'command': function('ale_linters#c#clangd#GetCommand'),
\ 'project_root': function('ale#c#FindProjectRoot'),
\ 'project_root': function('ale_linters#c#clangd#GetProjectRoot'),
\})

View File

@@ -11,32 +11,22 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy')
" http://clang.llvm.org/extra/clang-tidy/checks/list.html
call ale#Set('c_clangtidy_checks', [])
" Set this option to manually set some options for clang-tidy to use as compile
" flags.
" Set this option to manually set some options for clang-tidy.
" This will disable compile_commands.json detection.
call ale#Set('c_clangtidy_options', '')
" Set this option to manually set options for clang-tidy directly.
call ale#Set('c_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#c#clangtidy#GetCommand(buffer, output) abort
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',')
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = ''
" Get the extra options if we couldn't find a build directory.
if empty(l:build_dir)
let l:options = ale#Var(a:buffer, 'c_clangtidy_options')
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
endif
" Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
let l:options = empty(l:build_dir)
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
\ : ''
return '%e'
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
\ . ' %s'
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . (!empty(l:options) ? ' -- ' . l:options : '')
@@ -46,7 +36,7 @@ call ale#linter#Define('c', {
\ 'name': 'clangtidy',
\ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')},
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clangtidy#GetCommand'))},
\ 'command': function('ale_linters#c#clangtidy#GetCommand'),
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

View File

@@ -5,17 +5,23 @@ call ale#Set('c_cppcheck_executable', 'cppcheck')
call ale#Set('c_cppcheck_options', '--enable=style')
function! ale_linters#c#cppcheck#GetCommand(buffer) abort
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
let l:buffer_path_include = empty(l:compile_commands_option)
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : ''
let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
" Search upwards from the file for compile_commands.json.
"
" If we find it, we'll `cd` to where the compile_commands.json file is,
" then use the file to set up import paths, etc.
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return '%e -q --language=c'
\ . l:template
\ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options'))
\ . l:buffer_path_include
let l:cd_command = !empty(l:compile_commmands_path)
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
\ : ''
let l:compile_commands_option = !empty(l:compile_commmands_path)
\ ? '--project=compile_commands.json '
\ : ''
return l:cd_command
\ . '%e -q --language=c '
\ . l:compile_commands_option
\ . ale#Var(a:buffer, 'c_cppcheck_options')
\ . ' %t'
endfunction
@@ -23,7 +29,6 @@ call ale#linter#Define('c', {
\ 'name': 'cppcheck',
\ 'output_stream': 'both',
\ 'executable': {b -> ale#Var(b, 'c_cppcheck_executable')},
\ 'cwd': function('ale#handlers#cppcheck#GetCwd'),
\ 'command': function('ale_linters#c#cppcheck#GetCommand'),
\ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat',
\})

View File

@@ -1,20 +0,0 @@
" Author: Justin Huang <justin.y.huang@live.com>
" Description: cpplint for c files
call ale#Set('c_cpplint_executable', 'cpplint')
call ale#Set('c_cpplint_options', '')
function! ale_linters#c#cpplint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'c_cpplint_options')
return '%e' . ale#Pad(l:options) . ' %s'
endfunction
call ale#linter#Define('c', {
\ 'name': 'cpplint',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_cpplint_executable')},
\ 'command': function('ale_linters#c#cpplint#GetCommand'),
\ 'callback': 'ale#handlers#cpplint#HandleCppLintFormat',
\ 'lint_file': 1,
\})

View File

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

View File

@@ -1,5 +0,0 @@
scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: cspell support for C files.
call ale#handlers#cspell#DefineLinter('c')

24
ale_linters/c/gcc.vim Normal file
View File

@@ -0,0 +1,24 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: gcc linter for c files
call ale#Set('c_gcc_executable', 'gcc')
call ale#Set('c_gcc_options', '-std=c11 -Wall')
function! ale_linters#c#gcc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return '%e -S -x c -fsyntax-only'
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(l:cflags)
\ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -'
endfunction
call ale#linter#Define('c', {
\ 'name': 'gcc',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_gcc_executable')},
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#gcc#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})

View File

@@ -1,22 +0,0 @@
" Author: Koni Marti <koni.marti@gmail.com>
" Description: A Language Server implementation for C3
call ale#Set('c3_c3lsp_executable', 'c3lsp')
call ale#Set('c3_c3lsp_options', '')
call ale#Set('c3_c3lsp_init_options', {})
function! ale_linters#c3#c3lsp#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'c3_c3lsp_executable')
return ale#Escape(l:executable) . ale#Pad(ale#Var(a:buffer, 'c3_c3lsp_options'))
endfunction
call ale#linter#Define('c3', {
\ 'name': 'c3lsp',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'c3_c3lsp_executable')},
\ 'command': function('ale_linters#c3#c3lsp#GetCommand'),
\ 'project_root': function('ale#handlers#c3lsp#GetProjectRoot'),
\ 'lsp_config': {b -> ale#handlers#c3lsp#GetInitOpts(b, 'c3_c3lsp_init_options')},
\})

View File

@@ -1,31 +0,0 @@
" Author: 0xhyoga <0xhyoga@gmx.com>,
" Description: scarb for cairo files
function! ale_linters#cairo#scarb#GetScarbExecutable(bufnr) abort
if ale#path#FindNearestFile(a:bufnr, 'Scarb.toml') isnot# ''
return 'scarb'
else
" if there is no Scarb.toml file, we don't use scarb even if it exists,
" so we return '', because executable('') apparently always fails
return ''
endif
endfunction
function! ale_linters#cairo#scarb#GetCommand(buffer, version) abort
return 'scarb build'
endfunction
call ale#linter#Define('cairo', {
\ 'name': 'scarb',
\ 'executable': function('ale_linters#cairo#scarb#GetScarbExecutable'),
\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ buffer,
\ ale_linters#cairo#scarb#GetScarbExecutable(buffer),
\ '%e --version',
\ function('ale_linters#cairo#scarb#GetCommand'),
\ )},
\ 'callback': 'ale#handlers#cairo#HandleCairoErrors',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})

View File

@@ -1,54 +0,0 @@
" Author: 0xHyoga <0xHyoga@gmx.com>
" Description: Report Starknet compile to sierra errors in cairo 1.0 code
call ale#Set('cairo_sierra_executable', 'starknet-compile')
call ale#Set('cairo_sierra_options', '')
function! ale_linters#cairo#sierra#Handle(buffer, lines) abort
" Matches patterns like the following:
" Error: Expected ';' but got '('
" --> /path/to/file/file.cairo:1:10:)
let l:pattern = '\v(error|warning): (.*)$'
let l:line_and_column_pattern = '\v\.cairo:(\d+):(\d+)'
let l:output = []
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
let l:match = matchlist(l:line, l:line_and_column_pattern)
if len(l:match) > 0
let l:index = len(l:output) - 1
let l:output[l:index]['lnum'] = l:match[1] + 0
let l:output[l:index]['col'] = l:match[2] + 0
endif
else
let l:isError = l:match[1] is? 'Error'
call add(l:output, {
\ 'lnum': 0,
\ 'col': 0,
\ 'text': l:match[2],
\ 'type': l:isError ? 'E' : 'W',
\})
endif
endfor
return l:output
endfunction
function! ale_linters#cairo#sierra#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'cairo_sierra_executable')
return l:executable . ale#Pad(ale#Var(a:buffer, 'cairo_sierra_options')) . ' %s'
endfunction
call ale#linter#Define('cairo', {
\ 'name': 'sierra',
\ 'executable': {b -> ale#Var(b, 'cairo_sierra_executable')},
\ 'command': function('ale_linters#cairo#sierra#GetCommand'),
\ 'callback': 'ale_linters#cairo#sierra#Handle',
\ 'output_stream': 'stderr',
\})

View File

@@ -1,39 +0,0 @@
" Author: 0xHyoga <0xHyoga@gmx.com>
" Description: Report starknet-compile errors in cairo code (pre-starknet
" 1.0). This is deprecated but kept for backwards compatability.
call ale#Set('cairo_starknet_executable', 'starknet-compile')
call ale#Set('cairo_starknet_options', '')
function! ale_linters#cairo#starknet#Handle(buffer, lines) abort
" Error always on the first line
" e.g ex01.cairo:20:6: Could not find module 'contracts.utils.ex00_base'. Searched in the following paths:
let l:pattern = '\v\.cairo:(\d+):(\d+):+ (.*)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': str2nr(l:match[1]),
\ 'col': str2nr(l:match[2]),
\ 'type': 'E',
\ 'text': l:match[3],
\})
endfor
return l:output
endfunction
function! ale_linters#cairo#starknet#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'cairo_starknet_executable')
return l:executable . ale#Pad(ale#Var(a:buffer, 'cairo_starknet_options')) . ' %s'
endfunction
call ale#linter#Define('cairo', {
\ 'name': 'starknet',
\ 'executable': {b -> ale#Var(b, 'cairo_starknet_executable')},
\ 'command': function('ale_linters#cairo#starknet#GetCommand'),
\ 'callback': 'ale_linters#cairo#starknet#Handle',
\ 'output_stream': 'stderr',
\})

View File

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

View File

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

View File

@@ -29,7 +29,6 @@ endfunction
call ale#linter#Define('cloudformation', {
\ 'name': 'cloudformation',
\ 'aliases': ['cfn-lint'],
\ 'executable': 'cfn-lint',
\ 'command': 'cfn-lint --template %t --format parseable',
\ 'callback': 'ale_linters#cloudformation#cfn_python_lint#Handle',

View File

@@ -1,43 +0,0 @@
" Author: Carl Smedstad <carl.smedstad at protonmail dot com>
" Description: cmake-lint for cmake files
let g:ale_cmake_cmake_lint_executable =
\ get(g:, 'ale_cmake_cmake_lint_executable', 'cmake-lint')
let g:ale_cmake_cmake_lint_options =
\ get(g:, 'ale_cmake_cmake_lint_options', '')
function! ale_linters#cmake#cmake_lint#Executable(buffer) abort
return ale#Var(a:buffer, 'cmake_cmake_lint_executable')
endfunction
function! ale_linters#cmake#cmake_lint#Command(buffer) abort
let l:executable = ale_linters#cmake#cmake_lint#Executable(a:buffer)
let l:options = ale#Var(a:buffer, 'cmake_cmake_lint_options')
return ale#Escape(l:executable) . ' ' . l:options . ' %s'
endfunction
function! ale_linters#cmake#cmake_lint#Handle(buffer, lines) abort
let l:pattern = '\v^[^:]+:(\d+),?(\d+)?:\s\[([A-Z]\d+)\]\s(.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'type': 'W',
\ 'code': l:match[3],
\ 'text': l:match[4],
\})
endfor
return l:output
endfunction
call ale#linter#Define('cmake', {
\ 'name': 'cmake_lint',
\ 'executable': function('ale_linters#cmake#cmake_lint#Executable'),
\ 'command': function('ale_linters#cmake#cmake_lint#Command'),
\ 'callback': 'ale_linters#cmake#cmake_lint#Handle',
\})

View File

@@ -1,67 +0,0 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: A C++ compiler linter for C++ files with gcc/clang, etc.
call ale#Set('cpp_cc_executable', '<auto>')
call ale#Set('cpp_cc_options', '-std=c++14 -Wall')
call ale#Set('cpp_cc_use_header_lang_flag', -1)
call ale#Set('cpp_cc_header_exts', ['h', 'hpp'])
function! ale_linters#cpp#cc#GetExecutable(buffer) abort
let l:executable = ale#Var(a:buffer, 'cpp_cc_executable')
" Default to either clang++ or gcc.
if l:executable is# '<auto>'
if ale#engine#IsExecutable(a:buffer, 'clang++')
let l:executable = 'clang++'
else
let l:executable = 'gcc'
endif
endif
return l:executable
endfunction
function! ale_linters#cpp#cc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:ale_flags = ale#Var(a:buffer, 'cpp_cc_options')
if l:cflags =~# '-std='
let l:ale_flags = substitute(
\ l:ale_flags,
\ '-std=\(c\|gnu\)++[0-9]\{2\}',
\ '',
\ 'g')
endif
" Select the correct language flag depending on the executable, options
" and file extension
let l:executable = ale_linters#cpp#cc#GetExecutable(a:buffer)
let l:use_header_lang_flag = ale#Var(a:buffer, 'cpp_cc_use_header_lang_flag')
let l:header_exts = ale#Var(a:buffer, 'cpp_cc_header_exts')
let l:lang_flag = ale#c#GetLanguageFlag(
\ a:buffer,
\ l:executable,
\ l:use_header_lang_flag,
\ l:header_exts,
\ 'c++')
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
"
" `-o /dev/null` or `-o null` is needed to catch all errors,
" -fsyntax-only doesn't catch everything.
return '%e -S -x ' . l:lang_flag
\ . ' -o ' . g:ale#util#nul_file
\ . ' -iquote %s:h'
\ . ale#Pad(l:cflags)
\ . ale#Pad(l:ale_flags) . ' -'
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'cc',
\ 'aliases': ['gcc', 'clang', 'g++', 'clang++'],
\ 'output_stream': 'stderr',
\ 'executable': function('ale_linters#cpp#cc#GetExecutable'),
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#cc#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})

View File

@@ -3,7 +3,6 @@
call ale#Set('cpp_ccls_executable', 'ccls')
call ale#Set('cpp_ccls_init_options', {})
call ale#Set('c_build_dir', '')
call ale#linter#Define('cpp', {
\ 'name': 'ccls',
@@ -11,5 +10,5 @@ call ale#linter#Define('cpp', {
\ 'executable': {b -> ale#Var(b, 'cpp_ccls_executable')},
\ 'command': '%e',
\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'),
\ 'initialization_options': {b -> ale#handlers#ccls#GetInitOpts(b, 'cpp_ccls_init_options')},
\ 'initialization_options': {b -> ale#Var(b, 'cpp_ccls_init_options')},
\})

24
ale_linters/cpp/clang.vim Normal file
View File

@@ -0,0 +1,24 @@
" Author: Tomota Nakamura <https://github.com/tomotanakamura>
" Description: clang linter for cpp files
call ale#Set('cpp_clang_executable', 'clang++')
call ale#Set('cpp_clang_options', '-std=c++14 -Wall')
function! ale_linters#cpp#clang#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return '%e -S -x c++ -fsyntax-only'
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(l:cflags)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_clang_options')) . ' -'
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'cpp_clang_executable')},
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clang#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})

View File

@@ -12,15 +12,14 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
if empty(l:build_dir)
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
let l:build_dir = ale#path#Dirname(l:json_file)
let l:build_dir = ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
endif
" The extra arguments in the command are used to prevent .plist files from
" being generated. These are only added if no build directory can be
" detected.
return '%e -analyze %s'
\ . (empty(l:build_dir) ? ' --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics': '')
\ . (empty(l:build_dir) ? ' -extra-arg -Xclang -extra-arg -analyzer-output=text' : '')
\ . ale#Pad(l:user_options)
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
endfunction

View File

@@ -3,14 +3,15 @@
call ale#Set('cpp_clangd_executable', 'clangd')
call ale#Set('cpp_clangd_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#cpp#clangd#GetCommand(buffer) abort
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
return '%e'
\ . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
\ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '')
return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
endfunction
call ale#linter#Define('cpp', {
@@ -18,5 +19,5 @@ call ale#linter#Define('cpp', {
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')},
\ 'command': function('ale_linters#cpp#clangd#GetCommand'),
\ 'project_root': function('ale#c#FindProjectRoot'),
\ 'project_root': function('ale_linters#cpp#clangd#GetProjectRoot'),
\})

View File

@@ -5,39 +5,22 @@
call ale#Set('cpp_clangtidy_executable', 'clang-tidy')
" Set this option to check the checks clang-tidy will apply.
call ale#Set('cpp_clangtidy_checks', [])
" Set this option to manually set some options for clang-tidy to use as compile
" flags.
" Set this option to manually set some options for clang-tidy.
" This will disable compile_commands.json detection.
call ale#Set('cpp_clangtidy_options', '')
" Set this option to manually set options for clang-tidy directly.
call ale#Set('cpp_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',')
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = ''
" Get the extra options if we couldn't find a build directory.
if empty(l:build_dir)
let l:options = ale#Var(a:buffer, 'cpp_clangtidy_options')
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
" Tell clang-tidy a .h header with a C++ filetype in Vim is a C++ file
" only when compile-commands.json file is not there. Adding these
" flags makes clang-tidy completely ignore compile commands.
if expand('#' . a:buffer) =~# '\.h$'
let l:options .= !empty(l:options) ? ' -x c++' : '-x c++'
endif
endif
" Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
let l:options = empty(l:build_dir)
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
\ : ''
return '%e'
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
\ . ' %s'
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . (!empty(l:options) ? ' -- ' . l:options : '')
@@ -47,7 +30,7 @@ call ale#linter#Define('cpp', {
\ 'name': 'clangtidy',
\ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')},
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clangtidy#GetCommand'))},
\ 'command': function('ale_linters#cpp#clangtidy#GetCommand'),
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

View File

@@ -5,17 +5,23 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck')
call ale#Set('cpp_cppcheck_options', '--enable=style')
function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
let l:buffer_path_include = empty(l:compile_commands_option)
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : ''
let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
" Search upwards from the file for compile_commands.json.
"
" If we find it, we'll `cd` to where the compile_commands.json file is,
" then use the file to set up import paths, etc.
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return '%e -q --language=c++'
\ . l:template
\ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options'))
\ . l:buffer_path_include
let l:cd_command = !empty(l:compile_commmands_path)
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
\ : ''
let l:compile_commands_option = !empty(l:compile_commmands_path)
\ ? '--project=compile_commands.json '
\ : ''
return l:cd_command
\ . '%e -q --language=c++ '
\ . l:compile_commands_option
\ . ale#Var(a:buffer, 'cpp_cppcheck_options')
\ . ' %t'
endfunction
@@ -23,7 +29,6 @@ call ale#linter#Define('cpp', {
\ 'name': 'cppcheck',
\ 'output_stream': 'both',
\ 'executable': {b -> ale#Var(b, 'cpp_cppcheck_executable')},
\ 'cwd': function('ale#handlers#cppcheck#GetCwd'),
\ 'command': function('ale_linters#cpp#cppcheck#GetCommand'),
\ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat',
\})

View File

@@ -5,15 +5,13 @@ 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
" Try to find cquery configuration files first.
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
if !empty(l:config)
return fnamemodify(l:config, ':h')
if empty(l:project_root)
let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
endif
" Fall back on default project root detection.
return ale#c#FindProjectRoot(a:buffer)
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort

View File

@@ -1,5 +0,0 @@
scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: cspell support for C++ files.
call ale#handlers#cspell#DefineLinter('cpp')

25
ale_linters/cpp/gcc.vim Normal file
View File

@@ -0,0 +1,25 @@
" Author: geam <mdelage@student.42.fr>
" Description: gcc linter for cpp files
"
call ale#Set('cpp_gcc_executable', 'gcc')
call ale#Set('cpp_gcc_options', '-std=c++14 -Wall')
function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return '%e -S -x c++ -fsyntax-only'
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(l:cflags)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -'
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'gcc',
\ 'aliases': ['g++'],
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'cpp_gcc_executable')},
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#gcc#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\})

View File

@@ -5,10 +5,6 @@ function! ale_linters#crystal#crystal#Handle(buffer, lines) abort
let l:output = []
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
if !has_key(l:error, 'file')
continue
endif
call add(l:output, {
\ 'lnum': l:error.line + 0,
\ 'col': l:error.column + 0,

View File

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

View File

@@ -1,5 +0,0 @@
scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: cspell support for C# files.
call ale#handlers#cspell#DefineLinter('cs')

View File

@@ -3,10 +3,14 @@ call ale#Set('cs_mcsc_source', '')
call ale#Set('cs_mcsc_assembly_path', [])
call ale#Set('cs_mcsc_assemblies', [])
function! ale_linters#cs#mcsc#GetCwd(buffer) abort
let l:cwd = ale#Var(a:buffer, 'cs_mcsc_source')
function! s:GetWorkingDirectory(buffer) abort
let l:working_directory = ale#Var(a:buffer, 'cs_mcsc_source')
return !empty(l:cwd) ? l:cwd : expand('#' . a:buffer . ':p:h')
if !empty(l:working_directory)
return l:working_directory
endif
return expand('#' . a:buffer . ':p:h')
endfunction
function! ale_linters#cs#mcsc#GetCommand(buffer) abort
@@ -30,7 +34,8 @@ function! ale_linters#cs#mcsc#GetCommand(buffer) abort
" The code is compiled as a module and the output is redirected to a
" temporary file.
return 'mcs -unsafe'
return ale#path#CdString(s:GetWorkingDirectory(a:buffer))
\ . 'mcs -unsafe'
\ . ale#Pad(ale#Var(a:buffer, 'cs_mcsc_options'))
\ . ale#Pad(l:lib_option)
\ . ale#Pad(l:r_option)
@@ -47,34 +52,20 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
" NOTE: pattern also captures file name as linter compiles all
" files within the source tree rooted at the specified source
" path and not just the file loaded in the buffer
let l:patterns = [
\ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
\ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
\]
let l:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$'
let l:output = []
let l:dir = ale_linters#cs#mcsc#GetCwd(a:buffer)
let l:dir = s:GetWorkingDirectory(a:buffer)
for l:match in ale#util#GetMatches(a:lines, l:patterns)
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'type': l:match[4] is# 'error' ? 'E' : 'W',
\ 'code': l:match[5],
\ 'text': l:match[6] ,
\})
elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
call add(l:output, {
\ 'filename':'<mcs>',
\ 'lnum': -1,
\ 'col': -1,
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
\ 'code': l:match[2],
\ 'text': l:match[3],
\})
endif
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'type': l:match[4] is# 'error' ? 'E' : 'W',
\ 'code': l:match[5],
\ 'text': l:match[6],
\})
endfor
return l:output
@@ -84,7 +75,6 @@ call ale#linter#Define('cs',{
\ 'name': 'mcsc',
\ 'output_stream': 'stderr',
\ 'executable': 'mcs',
\ 'cwd': function('ale_linters#cs#mcsc#GetCwd'),
\ 'command': function('ale_linters#cs#mcsc#GetCommand'),
\ 'callback': 'ale_linters#cs#mcsc#Handle',
\ 'lint_file': 1

View File

@@ -1,5 +0,0 @@
scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: cspell support for CSS files.
call ale#handlers#cspell#DefineLinter('css')

View File

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

View File

@@ -11,8 +11,7 @@ endfunction
call ale#linter#Define('css', {
\ 'name': 'stylelint',
\ 'output_stream': 'both',
\ 'executable': {b -> ale#path#FindExecutable(b, 'css_stylelint', [
\ 'executable': {b -> ale#node#FindExecutable(b, 'css_stylelint', [
\ 'node_modules/.bin/stylelint',
\ ])},
\ 'command': function('ale_linters#css#stylelint#GetCommand'),

View File

@@ -1,16 +0,0 @@
" Author: Dalius Dobravolskas <dalius.dobravolskas@gmail.com>
" Description: VSCode css language server
function! ale_linters#css#vscodecss#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('css', {
\ 'name': 'vscodecss',
\ 'lsp': 'stdio',
\ 'executable': 'vscode-css-language-server',
\ 'command': '%e --stdio',
\ 'project_root': function('ale_linters#css#vscodecss#GetProjectRoot'),
\})

View File

@@ -1,23 +0,0 @@
" Author: Tommy Chiang <ty1208chiang@gmail.com>
" Description: Clangd language server for CUDA (modified from Andrey
" Melentyev's implementation for C++)
call ale#Set('cuda_clangd_executable', 'clangd')
call ale#Set('cuda_clangd_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#cuda#clangd#GetCommand(buffer) abort
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
return '%e'
\ . ale#Pad(ale#Var(a:buffer, 'cuda_clangd_options'))
\ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '')
endfunction
call ale#linter#Define('cuda', {
\ 'name': 'clangd',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'cuda_clangd_executable')},
\ 'command': function('ale_linters#cuda#clangd#GetCommand'),
\ 'project_root': function('ale#c#FindProjectRoot'),
\})

View File

@@ -5,6 +5,9 @@ call ale#Set('cuda_nvcc_executable', 'nvcc')
call ale#Set('cuda_nvcc_options', '-std=c++11')
function! ale_linters#cuda#nvcc#GetCommand(buffer) abort
" Unused: use ale#util#nul_file
" let l:output_file = ale#util#Tempname() . '.ii'
" call ale#command#ManageFile(a:buffer, l:output_file)
return '%e -cuda'
\ . ale#Pad(ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer)))
\ . ale#Pad(ale#Var(a:buffer, 'cuda_nvcc_options'))

View File

@@ -1,106 +1,64 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: "dmd for D files"
function! s:GetDUBCommand(buffer) abort
function! ale_linters#d#dmd#GetDUBCommand(buffer) abort
" If we can't run dub, then skip this command.
if executable('dub')
if !executable('dub')
" Returning an empty string skips to the DMD command.
let l:config = ale#d#FindDUBConfig(a:buffer)
" To support older dub versions, we just change the directory to the
" directory where we found the dub config, and then run `dub describe`
" from that directory.
if !empty(l:config)
return [fnamemodify(l:config, ':h'), 'dub describe --data-list
\ --data=import-paths
\ --data=string-import-paths
\ --data=versions
\ --data=debug-versions
\']
endif
return ''
endif
return ['', '']
let l:dub_file = ale#d#FindDUBConfig(a:buffer)
if empty(l:dub_file)
return ''
endif
" To support older dub versions, we just change the directory to
" the directory where we found the dub config, and then run `dub describe`
" from that directory.
return 'cd ' . ale#Escape(fnamemodify(l:dub_file, ':h'))
\ . ' && dub describe --import-paths'
endfunction
function! ale_linters#d#dmd#RunDUBCommand(buffer) abort
let [l:cwd, l:command] = s:GetDUBCommand(a:buffer)
let l:command = ale_linters#d#dmd#GetDUBCommand(a:buffer)
if empty(l:command)
" If we can't run DUB, just run DMD.
return ale_linters#d#dmd#DMDCommand(a:buffer, [], {})
endif
return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#d#dmd#DMDCommand'),
\ {'cwd': l:cwd},
\)
return ale#command#Run(a:buffer, l:command, function('ale_linters#d#dmd#DMDCommand'))
endfunction
function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) abort
let l:import_list = []
let l:str_import_list = []
let l:versions_list = []
let l:deb_versions_list = []
let l:list_ind = 1
let l:seen_line = 0
" Build a list of options generated from DUB, if available.
" DUB output each path or version on a single line.
" Each list is separated by a blank line.
" Empty list are represented by a blank line (followed and/or
" preceded by a separation blank line)
" Build a list of import paths generated from DUB, if available.
for l:line in a:dub_output
" line still has end of line char on windows
let l:line = substitute(l:line, '[\r\n]*$', '', '')
if !empty(l:line)
if l:list_ind == 1
call add(l:import_list, '-I' . ale#Escape(l:line))
elseif l:list_ind == 2
call add(l:str_import_list, '-J' . ale#Escape(l:line))
elseif l:list_ind == 3
call add(l:versions_list, '-version=' . ale#Escape(l:line))
elseif l:list_ind == 4
call add(l:deb_versions_list, '-debug=' . ale#Escape(l:line))
endif
let l:seen_line = 1
elseif !l:seen_line
" if list is empty must skip one empty line
let l:seen_line = 1
else
let l:seen_line = 0
let l:list_ind += 1
" The arguments must be '-Ifilename', not '-I filename'
call add(l:import_list, '-I' . ale#Escape(l:line))
endif
endfor
return 'dmd ' . join(l:import_list) . ' ' .
\ join(l:str_import_list) . ' ' .
\ join(l:versions_list) . ' ' .
\ join(l:deb_versions_list) . ' -o- -wi -vcolumns -c %t'
return 'dmd '. join(l:import_list) . ' -o- -wi -vcolumns -c %t'
endfunction
function! ale_linters#d#dmd#Handle(buffer, lines) abort
" Matches patterns lines like the following:
" /tmp/tmp.qclsa7qLP7/file.d(1): Error: function declaration without return type. (Note that constructors are always named 'this')
" /tmp/tmp.G1L5xIizvB.d(8,8): Error: module weak_reference is in file 'dstruct/weak_reference.d' which cannot be read
let l:pattern = '\v^(\f+)\((\d+)(,(\d+))?\): (\w+): (.+)$'
let l:pattern = '^[^(]\+(\([0-9]\+\)\,\?\([0-9]*\)): \([^:]\+\): \(.\+\)'
let l:output = []
let l:dir = expand('#' . a:buffer . ':p:h')
for l:match in ale#util#GetMatches(a:lines, l:pattern)
" If dmd was invoked with relative path, match[1] is relative, otherwise it is absolute.
" As we invoke dmd with the buffer path (in /tmp), this will generally be absolute already
let l:fname = ale#path#GetAbsPath(l:dir, l:match[1])
call add(l:output, {
\ 'filename': l:fname,
\ 'lnum': l:match[2],
\ 'col': l:match[4],
\ 'type': l:match[5] is# 'Warning' || l:match[5] is# 'Deprecation' ? 'W' : 'E',
\ 'text': l:match[6],
\ 'lnum': l:match[1],
\ 'col': l:match[2],
\ 'type': l:match[3] is# 'Warning' ? 'W' : 'E',
\ 'text': l:match[4],
\})
endfor

View File

@@ -1,5 +1,4 @@
" Author: Taylor Blau <me@ttaylorr.com>
call ale#Set('dafny_dafny_timelimit', 10)
function! ale_linters#dafny#dafny#Handle(buffer, lines) abort
let l:pattern = '\v(.*)\((\d+),(\d+)\): (.*): (.*)'
@@ -7,7 +6,7 @@ function! ale_linters#dafny#dafny#Handle(buffer, lines) abort
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'filename': l:match[1],
\ 'bufnr': a:buffer,
\ 'col': l:match[3] + 0,
\ 'lnum': l:match[2] + 0,
\ 'text': l:match[5],
@@ -15,27 +14,13 @@ function! ale_linters#dafny#dafny#Handle(buffer, lines) abort
\ })
endfor
for l:match in ale#util#GetMatches(a:lines, '\v(.*)\((\d+),(\d+)\): (Verification of .{-} timed out after \d+ seconds)')
call add(l:output, {
\ 'filename': l:match[1],
\ 'col': l:match[3] + 0,
\ 'lnum': l:match[2] + 0,
\ 'text': l:match[4],
\ 'type': 'E',
\ })
endfor
return l:output
endfunction
function! ale_linters#dafny#dafny#GetCommand(buffer) abort
return printf('dafny %%s /compile:0 /timeLimit:%d', ale#Var(a:buffer, 'dafny_dafny_timelimit'))
endfunction
call ale#linter#Define('dafny', {
\ 'name': 'dafny',
\ 'executable': 'dafny',
\ 'command': function('ale_linters#dafny#dafny#GetCommand'),
\ 'command': 'dafny %s /compile:0',
\ 'callback': 'ale_linters#dafny#dafny#Handle',
\ 'lint_file': 1,
\ })

View File

@@ -1,37 +0,0 @@
" Author: Nelson Yeung <nelsyeung@gmail.com>
" Description: Check Dart files with dart analysis server LSP
call ale#Set('dart_analysis_server_enable_language_server', 1)
call ale#Set('dart_analysis_server_executable', 'dart')
function! ale_linters#dart#analysis_server#GetProjectRoot(buffer) abort
" Note: pub only looks for pubspec.yaml, there's no point in adding
" support for pubspec.yml
let l:pubspec = ale#path#FindNearestFile(a:buffer, 'pubspec.yaml')
return !empty(l:pubspec) ? fnamemodify(l:pubspec, ':h:h') : '.'
endfunction
function! ale_linters#dart#analysis_server#GetCommand(buffer) abort
let l:language_server = ale#Var(a:buffer, 'dart_analysis_server_enable_language_server')
let l:executable = ale#Var(a:buffer, 'dart_analysis_server_executable')
let l:dart = resolve(exepath(l:executable))
let l:output = '%e '
\ . fnamemodify(l:dart, ':h') . '/snapshots/analysis_server.dart.snapshot'
\ . ' --lsp'
" Enable new language-server command
if l:language_server == 1
let l:output = '%e language-server --protocol=lsp'
endif
return l:output
endfunction
call ale#linter#Define('dart', {
\ 'name': 'analysis_server',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'dart_analysis_server_executable')},
\ 'command': function('ale_linters#dart#analysis_server#GetCommand'),
\ 'project_root': function('ale_linters#dart#analysis_server#GetProjectRoot'),
\})

View File

@@ -1,29 +0,0 @@
" Author: ghsang <gwonhyuksang@gmail.com>
" Description: Check Dart files with dart analyze
call ale#Set('dart_analyze_executable', 'dart')
function! ale_linters#dart#dart_analyze#Handle(buffer, lines) abort
let l:pattern = '\v([a-z]+) - (.+):(\d+):(\d+) - (.+) - (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let [l:type, l:filename, l:lnum, l:col, l:message, l:code] = l:match[1:6]
call add(l:output, {
\ 'type': l:type is# 'error' ? 'E' : l:type is# 'info' ? 'I' : 'W',
\ 'text': l:code . ': ' . l:message,
\ 'lnum': str2nr(l:lnum),
\ 'col': str2nr(l:col),
\})
endfor
return l:output
endfunction
call ale#linter#Define('dart', {
\ 'name': 'dart_analyze',
\ 'executable': {b -> ale#Var(b, 'dart_analyze_executable')},
\ 'command': '%e analyze --fatal-infos %s',
\ 'callback': 'ale_linters#dart#dart_analyze#Handle',
\ 'lint_file': 1,
\})

View File

@@ -0,0 +1,36 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Check Dart files with dartanalyzer
call ale#Set('dart_dartanalyzer_executable', 'dartanalyzer')
function! ale_linters#dart#dartanalyzer#GetCommand(buffer) abort
let l:path = ale#path#FindNearestFile(a:buffer, '.packages')
return '%e'
\ . (!empty(l:path) ? ' --packages ' . ale#Escape(l:path) : '')
\ . ' %s'
endfunction
function! ale_linters#dart#dartanalyzer#Handle(buffer, lines) abort
let l:pattern = '\v^ ([a-z]+) . (.+) at (.+):(\d+):(\d+) . (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
\ 'text': l:match[6] . ': ' . l:match[2],
\ 'lnum': str2nr(l:match[4]),
\ 'col': str2nr(l:match[5]),
\})
endfor
return l:output
endfunction
call ale#linter#Define('dart', {
\ 'name': 'dartanalyzer',
\ 'executable': {b -> ale#Var(b, 'dart_dartanalyzer_executable')},
\ 'command': function('ale_linters#dart#dartanalyzer#GetCommand'),
\ 'callback': 'ale_linters#dart#dartanalyzer#Handle',
\ 'lint_file': 1,
\})

View File

@@ -1,31 +0,0 @@
call ale#Set('desktop_desktop_file_validate_options', '')
" Example matches for pattern:
"
" foo.desktop: warning: key "TerminalOptions" in group ...
" foo.desktop: error: action "new-private-window" is defined, ...
let s:pattern = '\v^(.+): ([a-z]+): (.+)$'
function! ale_linters#desktop#desktop_file_validate#Handle(buffer, lines) abort
" The error format doesn't specify lines, so we can just put all of the
" errors on line 1.
return ale#util#MapMatches(a:lines, s:pattern, {match -> {
\ 'lnum': 1,
\ 'col': 1,
\ 'type': match[2] is? 'error' ? 'E' : 'W',
\ 'text': match[3],
\}})
endfunction
call ale#linter#Define('desktop', {
\ 'name': 'desktop_file_validate',
\ 'aliases': ['desktop-file-validate'],
\ 'executable': 'desktop-file-validate',
\ 'command': {b ->
\ '%e'
\ . ale#Pad(ale#Var(b, 'desktop_desktop_file_validate_options'))
\ . ' %t'
\ },
\ 'callback': 'ale_linters#desktop#desktop_file_validate#Handle',
\ 'output_stream': 'both',
\})

View File

@@ -32,29 +32,14 @@ function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort
let l:line = get(l:object, 'line', -1)
let l:message = l:object['message']
let l:link = get(l:object, 'reference_url', '')
if type(l:link) == v:t_list
" Somehow, reference_url is returned as two-part list.
" Anchor markers in that list are sometimes duplicated.
" See https://github.com/projectatomic/dockerfile_lint/issues/134
let l:link = join(l:link, '')
let l:link = substitute(l:link, '##', '#', '')
endif
let l:detail = l:message
if get(l:object, 'description', 'None') isnot# 'None'
let l:detail .= "\n\n" . l:object['description']
let l:message = l:message . '. ' . l:object['description']
endif
let l:detail .= "\n\n" . l:link
call add(l:messages, {
\ 'lnum': l:line,
\ 'text': l:message,
\ 'type': ale_linters#dockerfile#dockerfile_lint#GetType(l:type),
\ 'detail': l:detail,
\})
endfor
endfor

View File

@@ -1,69 +0,0 @@
" Author: Shad
" Description: dockerlinter linter for dockerfile
call ale#Set('dockerfile_dockerlinter_executable', 'dockerlinter')
call ale#Set('dockerfile_dockerlinter_options', '')
function! ale_linters#dockerfile#dockerlinter#GetType(type) abort
if a:type is? 'error'
return 'E'
elseif a:type is? 'warning'
return 'W'
endif
return 'I'
endfunction
function! ale_linters#dockerfile#dockerlinter#Handle(buffer, lines) abort
try
let l:data = json_decode(join(a:lines, ''))
catch
return []
endtry
if empty(l:data)
" Should never happen, but it's better to be on the safe side
return []
endif
let l:messages = []
for l:object in l:data
let l:line = get(l:object, 'lineNumber', -1)
let l:message = l:object['message']
let l:type = l:object['level']
let l:detail = l:message
let l:code = l:object['code']
if l:code =~# '^SC'
let l:link = 'https://www.shellcheck.net/wiki/' . l:code
else
let l:link = 'https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md#' . l:code
endif
let l:detail = l:message . "\n\n" . l:link
call add(l:messages, {
\ 'lnum': l:line,
\ 'code': l:code,
\ 'text': l:message,
\ 'type': ale_linters#dockerfile#dockerlinter#GetType(l:type),
\ 'detail': l:detail,
\})
endfor
return l:messages
endfunction
function! ale_linters#dockerfile#dockerlinter#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'dockerfile_dockerlinter_options'))
\ . ' -j -f'
\ . ' %t'
endfunction
call ale#linter#Define('dockerfile', {
\ 'name': 'dockerlinter',
\ 'executable': {b -> ale#Var(b, 'dockerfile_dockerlinter_executable')},
\ 'command': function('ale_linters#dockerfile#dockerlinter#GetCommand'),
\ 'callback': 'ale_linters#dockerfile#dockerlinter#Handle',
\})

View File

@@ -3,14 +3,13 @@
" always, yes, never
call ale#Set('dockerfile_hadolint_use_docker', 'never')
call ale#Set('dockerfile_hadolint_docker_image', 'hadolint/hadolint')
call ale#Set('dockerfile_hadolint_options', '')
function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" -:19 DL3001 warning: Pipe chain should start with a raw value.
" /dev/stdin:19 DL3001 Pipe chain should start with a raw value.
" /dev/stdin:19:3 unexpected thing
let l:pattern = '\v^%(/dev/stdin|-):(\d+):?(\d+)? ((DL|SC)(\d+) )?((.+)?: )?(.+)$'
let l:pattern = '\v^/dev/stdin:(\d+):?(\d+)? ((DL|SC)(\d+) )?(.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
@@ -25,22 +24,10 @@ function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
let l:colnum = l:match[2] + 0
endif
" Shellcheck knows a 'style' severity - pin it to info level as well.
if l:match[7] is# 'style'
let l:type = 'I'
elseif l:match[7] is# 'info'
let l:type = 'I'
elseif l:match[7] is# 'warning'
let l:type = 'W'
else
let l:type = 'E'
endif
let l:text = l:match[8]
let l:detail = l:match[8]
let l:type = 'W'
let l:text = l:match[6]
let l:detail = l:match[6]
let l:domain = 'https://github.com/hadolint/hadolint/wiki/'
let l:code = ''
let l:link = ''
if l:match[4] is# 'SC'
let l:domain = 'https://github.com/koalaman/shellcheck/wiki/'
@@ -49,26 +36,18 @@ function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
if l:match[5] isnot# ''
let l:code = l:match[4] . l:match[5]
let l:link = ' ( ' . l:domain . l:code . ' )'
let l:text = l:code . ': ' . l:detail
let l:detail = l:code . l:link . "\n\n" . l:detail
else
let l:type = 'E'
let l:detail = 'hadolint could not parse the file because of a syntax error.'
endif
let l:line_output = {
call add(l:output, {
\ 'lnum': l:lnum,
\ 'col': l:colnum,
\ 'type': l:type,
\ 'text': l:text,
\ 'detail': l:detail
\}
if l:code isnot# ''
let l:line_output['code'] = l:code
endif
call add(l:output, l:line_output)
\})
endfor
return l:output
@@ -103,15 +82,12 @@ endfunction
function! ale_linters#dockerfile#hadolint#GetCommand(buffer) abort
let l:command = ale_linters#dockerfile#hadolint#GetExecutable(a:buffer)
let l:opts = ale#Var(a:buffer, 'dockerfile_hadolint_options') . ' --no-color -'
if l:command is# 'docker'
return printf('docker run --rm -i %s hadolint %s',
\ ale#Var(a:buffer, 'dockerfile_hadolint_docker_image'),
\ l:opts)
return 'docker run --rm -i ' . ale#Var(a:buffer, 'dockerfile_hadolint_docker_image')
endif
return 'hadolint ' . l:opts
return 'hadolint -'
endfunction

View File

@@ -45,27 +45,19 @@ function! ale_linters#elixir#credo#GetMode() abort
endif
endfunction
function! ale_linters#elixir#credo#GetConfigFile() abort
let l:config_file = get(g:, 'ale_elixir_credo_config_file', '')
if empty(l:config_file)
return ''
endif
return ' --config-file ' . l:config_file
endfunction
function! ale_linters#elixir#credo#GetCommand(buffer) abort
return 'mix help credo && '
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
let l:mode = ale_linters#elixir#credo#GetMode()
return ale#path#CdString(l:project_root)
\ . 'mix help credo && '
\ . 'mix credo ' . ale_linters#elixir#credo#GetMode()
\ . ale_linters#elixir#credo#GetConfigFile()
\ . ' --format=flycheck --read-from-stdin %s'
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'credo',
\ 'executable': 'mix',
\ 'cwd': function('ale#handlers#elixir#FindMixUmbrellaRoot'),
\ 'command': function('ale_linters#elixir#credo#GetCommand'),
\ 'callback': 'ale_linters#elixir#credo#Handle',
\})

View File

@@ -1,5 +0,0 @@
scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: cspell support for Elixir files.
call ale#handlers#cspell#DefineLinter('elixir')

View File

@@ -25,10 +25,17 @@ function! ale_linters#elixir#dialyxir#Handle(buffer, lines) abort
return l:output
endfunction
function! ale_linters#elixir#dialyxir#GetCommand(buffer) abort
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
return ale#path#CdString(l:project_root)
\ . ' mix help dialyzer && mix dialyzer'
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'dialyxir',
\ 'executable': 'mix',
\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'),
\ 'command': 'mix help dialyzer && mix dialyzer',
\ 'command': function('ale_linters#elixir#dialyxir#GetCommand'),
\ 'callback': 'ale_linters#elixir#dialyxir#Handle',
\})

View File

@@ -29,11 +29,17 @@ function! ale_linters#elixir#dogma#Handle(buffer, lines) abort
return l:output
endfunction
function! ale_linters#elixir#dogma#GetCommand(buffer) abort
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
return ale#path#CdString(l:project_root)
\ . ' mix help dogma && mix dogma %s --format=flycheck'
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'dogma',
\ 'executable': 'mix',
\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'),
\ 'command': 'mix help dogma && mix dogma %s --format=flycheck',
\ 'command': function('ale_linters#elixir#dogma#GetCommand'),
\ 'lint_file': 1,
\ 'callback': 'ale_linters#elixir#dogma#Handle',
\})

View File

@@ -1,5 +1,5 @@
" Author: Jon Parise <jon@indelible.org>
" Description: ElixirLS integration (https://github.com/elixir-lsp/elixir-ls)
" Description: ElixirLS integration (https://github.com/JakeBecker/elixir-ls)
call ale#Set('elixir_elixir_ls_release', 'elixir-ls')
call ale#Set('elixir_elixir_ls_config', {})
@@ -12,8 +12,7 @@ function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'elixir_ls',
\ 'aliases': ['elixir-ls', 'elixirls'],
\ 'name': 'elixir-ls',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#elixir#elixir_ls#GetExecutable'),
\ 'command': function('ale_linters#elixir#elixir_ls#GetExecutable'),

View File

@@ -1,19 +0,0 @@
" Author: Axel Clark <axelclark@pm.me>
" Description: Lexical integration (https://github.com/lexical-lsp/lexical)
call ale#Set('elixir_lexical_release', 'lexical')
function! ale_linters#elixir#lexical#GetExecutable(buffer) abort
let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_lexical_release'))
let l:cmd = has('win32') ? '\start_lexical.bat' : '/start_lexical.sh'
return l:dir . l:cmd
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'lexical',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#elixir#lexical#GetExecutable'),
\ 'command': function('ale_linters#elixir#lexical#GetExecutable'),
\ 'project_root': function('ale#handlers#elixir#FindMixUmbrellaRoot'),
\})

View File

@@ -30,15 +30,22 @@ function! ale_linters#elixir#mix#Handle(buffer, lines) abort
endfunction
function! ale_linters#elixir#mix#GetCommand(buffer) abort
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
let l:temp_dir = ale#command#CreateDirectory(a:buffer)
return ale#Env('MIX_BUILD_PATH', l:temp_dir) . 'mix compile %s'
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',
\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'),
\ 'command': function('ale_linters#elixir#mix#GetCommand'),
\ 'callback': 'ale_linters#elixir#mix#Handle',
\ 'lint_file': 1,

View File

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

View File

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

View File

@@ -186,23 +186,24 @@ function! ale_linters#elm#make#IsTest(buffer) abort
endif
endfunction
function! ale_linters#elm#make#GetCwd(buffer) abort
let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer)
return !empty(l:root_dir) ? l:root_dir : ''
endfunction
" Return the command to execute the linter in the projects directory.
" If it doesn't, then this will fail when imports are needed.
function! ale_linters#elm#make#GetCommand(buffer) abort
let l:executable = ale_linters#elm#make#GetExecutable(a:buffer)
let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer)
let l:is_v19 = ale_linters#elm#make#IsVersionGte19(a:buffer)
let l:is_using_elm_test = l:executable =~# 'elm-test$'
if empty(l:root_dir)
let l:dir_set_cmd = ''
else
let l:dir_set_cmd = 'cd ' . ale#Escape(l:root_dir) . ' && '
endif
" elm-test needs to know the path of elm-make if elm isn't installed globally.
" https://github.com/rtfeldman/node-test-runner/blob/57728f10668f2d2ab3179e7e3208bcfa9a1f19aa/README.md#--compiler
if l:is_v19 && l:is_using_elm_test
let l:elm_make_executable = ale#path#FindExecutable(a:buffer, 'elm_make', ['node_modules/.bin/elm'])
let l:elm_make_executable = ale#node#FindExecutable(a:buffer, 'elm_make', ['node_modules/.bin/elm'])
let l:elm_test_compiler_flag = ' --compiler ' . l:elm_make_executable . ' '
else
let l:elm_test_compiler_flag = ' '
@@ -212,9 +213,7 @@ function! ale_linters#elm#make#GetCommand(buffer) abort
" a sort of flag to tell the compiler not to generate an output file,
" which is why this is hard coded here.
" Source: https://github.com/elm-lang/elm-compiler/blob/19d5a769b30ec0b2fc4475985abb4cd94cd1d6c3/builder/src/Generate/Output.hs#L253
return '%e make --report=json --output=/dev/null'
\ . l:elm_test_compiler_flag
\ . '%t'
return l:dir_set_cmd . '%e make --report=json --output=/dev/null' . l:elm_test_compiler_flag . '%t'
endfunction
function! ale_linters#elm#make#GetExecutable(buffer) abort
@@ -222,13 +221,13 @@ function! ale_linters#elm#make#GetExecutable(buffer) abort
let l:is_v19 = ale_linters#elm#make#IsVersionGte19(a:buffer)
if l:is_test && l:is_v19
return ale#path#FindExecutable(
return ale#node#FindExecutable(
\ a:buffer,
\ 'elm_make',
\ ['node_modules/.bin/elm-test', 'node_modules/.bin/elm']
\)
else
return ale#path#FindExecutable(a:buffer, 'elm_make', ['node_modules/.bin/elm'])
return ale#node#FindExecutable(a:buffer, 'elm_make', ['node_modules/.bin/elm'])
endif
endfunction
@@ -236,7 +235,6 @@ call ale#linter#Define('elm', {
\ 'name': 'make',
\ 'executable': function('ale_linters#elm#make#GetExecutable'),
\ 'output_stream': 'both',
\ 'cwd': function('ale_linters#elm#make#GetCwd'),
\ 'command': function('ale_linters#elm#make#GetCommand'),
\ 'callback': 'ale_linters#elm#make#Handle'
\})

View File

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

View File

@@ -1,59 +0,0 @@
" Author: Dmitri Vereshchagin <dmitri.vereshchagin@gmail.com>
" Description: Elvis linter for Erlang files
call ale#Set('erlang_elvis_executable', 'elvis')
function! ale_linters#erlang#elvis#Handle(buffer, lines) abort
let l:pattern = '\v:(\d+):[^:]+:(.+)'
let l:loclist = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:loclist, {
\ 'lnum': str2nr(l:match[1]),
\ 'text': s:AbbreviateMessage(l:match[2]),
\ 'type': 'W',
\ 'sub_type': 'style',
\})
endfor
return l:loclist
endfunction
function! s:AbbreviateMessage(text) abort
let l:pattern = '\v\c^(line \d+ is too long):.*$'
return substitute(a:text, l:pattern, '\1.', '')
endfunction
function! s:GetCommand(buffer) abort
let l:cwd = s:GetCwd(a:buffer)
let l:file = !empty(l:cwd)
\ ? expand('#' . a:buffer . ':p')[len(l:cwd) + 1:]
\ : expand('#' . a:buffer . ':.')
return '%e rock --output-format=parsable ' . ale#Escape(l:file)
endfunction
function! s:GetCwd(buffer) abort
let l:markers = ['elvis.config', 'rebar.lock', 'erlang.mk']
for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
for l:marker in l:markers
if filereadable(l:path . '/' . l:marker)
return l:path
endif
endfor
endfor
return ''
endfunction
call ale#linter#Define('erlang', {
\ 'name': 'elvis',
\ 'callback': 'ale_linters#erlang#elvis#Handle',
\ 'executable': {b -> ale#Var(b, 'erlang_elvis_executable')},
\ 'command': function('s:GetCommand'),
\ 'cwd': function('s:GetCwd'),
\ 'lint_file': 1,
\})

View File

@@ -1,57 +0,0 @@
" Author: Dmitri Vereshchagin <dmitri.vereshchagin@gmail.com>
" Description: LSP linter for Erlang files
call ale#Set('erlang_erlang_ls_executable', 'erlang_ls')
call ale#Set('erlang_erlang_ls_log_dir', '')
call ale#Set('erlang_erlang_ls_log_level', 'info')
function! s:GetCommand(buffer) abort
let l:log_dir = ale#Var(a:buffer, 'erlang_erlang_ls_log_dir')
let l:log_level = ale#Var(a:buffer, 'erlang_erlang_ls_log_level')
let l:command = '%e'
if !empty(l:log_dir)
let l:command .= ' --log-dir=' . ale#Escape(l:log_dir)
endif
let l:command .= ' --log-level=' . ale#Escape(l:log_level)
return l:command
endfunction
function! s:FindProjectRoot(buffer) abort
let l:markers = [
\ '_checkouts/',
\ '_build/',
\ 'deps/',
\ 'erlang_ls.config',
\ 'rebar.lock',
\ 'erlang.mk',
\]
" This is a way to find Erlang/OTP root (the one that is managed
" by kerl or asdf). Useful if :ALEGoToDefinition takes us there.
let l:markers += ['.kerl_config']
for l:marker in l:markers
let l:path = l:marker[-1:] is# '/'
\ ? ale#path#FindNearestDirectory(a:buffer, l:marker)
\ : ale#path#FindNearestFile(a:buffer, l:marker)
if !empty(l:path)
return ale#path#Dirname(l:path)
endif
endfor
return ''
endfunction
call ale#linter#Define('erlang', {
\ 'name': 'erlang_ls',
\ 'executable': {b -> ale#Var(b, 'erlang_erlang_ls_executable')},
\ 'command': function('s:GetCommand'),
\ 'lsp': 'stdio',
\ 'project_root': function('s:FindProjectRoot'),
\ 'aliases': ['erlang-ls'],
\})

View File

@@ -1,22 +1,14 @@
" Author: Magnus Ottenklinger - https://github.com/evnu
let g:ale_erlang_erlc_executable = get(g:, 'ale_erlang_erlc_executable', 'erlc')
let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '')
function! ale_linters#erlang#erlc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'erlang_erlc_executable')
endfunction
function! ale_linters#erlang#erlc#GetCommand(buffer) abort
let l:output_file = ale#util#Tempname()
call ale#command#ManageFile(a:buffer, l:output_file)
let l:command = ale#Escape(ale_linters#erlang#erlc#GetExecutable(a:buffer))
\ . ' -o ' . ale#Escape(l:output_file)
\ . ' ' . ale#Var(a:buffer, 'erlang_erlc_options')
\ . ' %t'
return l:command
return 'erlc -o ' . ale#Escape(l:output_file)
\ . ' ' . ale#Var(a:buffer, 'erlang_erlc_options')
\ . ' %t'
endfunction
function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
@@ -25,7 +17,7 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
" error.erl:4: variable 'B' is unbound
" error.erl:3: Warning: function main/0 is unused
" error.erl:4: Warning: variable 'A' is unused
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+:)? (Warning: )?(.+)$'
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+): (Warning: )?(.+)$'
" parse_transforms are a special case. The error message does not indicate a location:
" error.erl: undefined parse transform 'some_parse_transform'
@@ -65,8 +57,8 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
endif
let l:line = l:match[2]
let l:warning_or_text = l:match[4]
let l:text = l:match[5]
let l:warning_or_text = l:match[3]
let l:text = l:match[4]
" If this file is a header .hrl, ignore the following expected messages:
" - 'no module definition'
@@ -98,7 +90,7 @@ endfunction
call ale#linter#Define('erlang', {
\ 'name': 'erlc',
\ 'executable': function('ale_linters#erlang#erlc#GetExecutable'),
\ 'executable': 'erlc',
\ 'command': function('ale_linters#erlang#erlc#GetCommand'),
\ 'callback': 'ale_linters#erlang#erlc#Handle',
\})

View File

@@ -3,13 +3,29 @@
call ale#Set('erlang_syntaxerl_executable', 'syntaxerl')
function! ale_linters#erlang#syntaxerl#RunHelpCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'erlang_syntaxerl_executable')
return ale#command#Run(
\ a:buffer,
\ ale#Escape(l:executable) . ' -h',
\ function('ale_linters#erlang#syntaxerl#GetCommand'),
\)
endfunction
function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output, meta) abort
let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1
return '%e' . (l:use_b_option ? ' -b %s %t' : ' %t')
endfunction
function! ale_linters#erlang#syntaxerl#Handle(buffer, lines) abort
let l:pattern = '\v\C:(\d+):( warning:)? (.+)'
let l:loclist = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:loclist, {
\ 'lnum': str2nr(l:match[1]),
\ 'lnum': l:match[1] + 0,
\ 'text': l:match[3],
\ 'type': empty(l:match[2]) ? 'E' : 'W',
\})
@@ -18,27 +34,9 @@ function! ale_linters#erlang#syntaxerl#Handle(buffer, lines) abort
return l:loclist
endfunction
function! s:GetExecutable(buffer) abort
return ale#Var(a:buffer, 'erlang_syntaxerl_executable')
endfunction
function! s:GetCommand(buffer) abort
let l:Callback = function('s:GetCommandFromHelpOutput')
return ale#command#Run(a:buffer, '%e -h', l:Callback, {
\ 'executable': s:GetExecutable(a:buffer),
\})
endfunction
function! s:GetCommandFromHelpOutput(buffer, output, metadata) abort
let l:has_b_option = match(a:output, '\V\C-b, --base\>') > -1
return l:has_b_option ? '%e -b %s %t' : '%e %t'
endfunction
call ale#linter#Define('erlang', {
\ 'name': 'syntaxerl',
\ 'executable': {b -> ale#Var(b, 'erlang_syntaxerl_executable')},
\ 'command': {b -> ale_linters#erlang#syntaxerl#RunHelpCommand(b)},
\ 'callback': 'ale_linters#erlang#syntaxerl#Handle',
\ 'executable': function('s:GetExecutable'),
\ 'command': function('s:GetCommand'),
\})

View File

@@ -11,7 +11,7 @@ function! ale_linters#eruby#erb#GetCommand(buffer) abort
" Rails-flavored eRuby does not comply with the standard as understood by
" ERB, so we'll have to do some substitution. This does not reduce the
" effectiveness of the linter—the translated code is still evaluated.
return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), trim_mode: %{-}).src') . '< %t | ruby -c'
return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c'
endfunction
call ale#linter#Define('eruby', {

View File

@@ -1,51 +0,0 @@
" Author: Roeland Moors - https://github.com/roelandmoors
" based on the ale ruumba and robocop linters
" Description: ERB Lint, support for https://github.com/Shopify/erb-lint
call ale#Set('eruby_erblint_executable', 'erblint')
call ale#Set('eruby_erblint_options', '')
function! ale_linters#eruby#erblint#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'eruby_erblint_executable')
return ale#ruby#EscapeExecutable(l:executable, 'erblint')
\ . ' --format json '
\ . ale#Var(a:buffer, 'eruby_erblint_options')
\ . ' --stdin %s'
endfunction
function! ale_linters#eruby#erblint#Handle(buffer, lines) abort
if empty(a:lines)
return []
endif
let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], [])
if !has_key(l:errors, 'summary')
\|| l:errors['summary']['offenses'] == 0
\|| empty(l:errors['files'])
return []
endif
let l:output = []
for l:error in l:errors['files'][0]['offenses']
call add(l:output, {
\ 'lnum': l:error['location']['start_line'] + 0,
\ 'col': l:error['location']['start_column'] + 0,
\ 'end_col': l:error['location']['last_column'] + 0,
\ 'code': l:error['linter'],
\ 'text': l:error['message'],
\ 'type': 'W',
\})
endfor
return l:output
endfunction
call ale#linter#Define('eruby', {
\ 'name': 'erblint',
\ 'executable': {b -> ale#Var(b, 'eruby_erblint_executable')},
\ 'command': function('ale_linters#eruby#erblint#GetCommand'),
\ 'callback': 'ale_linters#eruby#erblint#Handle',
\})

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