Compare commits

..

4 Commits

Author SHA1 Message Date
w0rp
97b410bbba Merge pull request #342 from Exteris/bugfix/gfortran-6.3.1
Update line marker pattern for new gfortran
2017-02-21 20:38:57 +00:00
Chris Paul
78b05d30a5 escape dot in maker regex (#357)
* escape dot in maker regex

* Create test_typecheck_handler

* Rename test_typecheck_handler to test_typecheck_handler.vader
2017-02-21 20:33:16 +00:00
w0rp
6f6c156995 Fix Pug linting 2017-02-11 20:47:11 +00:00
w0rp
62a45f8ae4 Don't export the custom-checks script in archives 2017-02-09 19:34:31 +00:00
1038 changed files with 4428 additions and 51978 deletions

View File

@@ -1,40 +0,0 @@
---
# Disabling building for AppVeyor. We are just testing things.
build: false
clone_depth: 10
# Use the directory C:\testplugin so test directories will mostly work.
clone_folder: C:\testplugin
# Cache the vim and vader directories between builds.
cache:
- C:\vim -> .appveyor.yml
- C:\vader -> .appveyor.yml
init:
# Stop git from changing newlines
- git config --global core.autocrlf input
install:
# Download and unpack Vim
- ps: >-
if (!(Test-Path -Path C:\vim)){
Add-Type -A System.IO.Compression.FileSystem
Invoke-WebRequest ftp://ftp.vim.org/pub/vim/pc/vim80-586w32.zip `
-OutFile C:\vim.zip
[IO.Compression.ZipFile]::ExtractToDirectory('C:\vim.zip', 'C:\vim')
Invoke-WebRequest ftp://ftp.vim.org/pub/vim/pc/vim80-586rt.zip `
-OutFile C:\rt.zip
[IO.Compression.ZipFile]::ExtractToDirectory('C:\rt.zip', 'C:\vim')
}
# Clone Vader and check out the commit we want
- ps: >-
if (!(Test-Path -Path C:\vader)){
git clone https://github.com/junegunn/vader.vim C:\vader 2> $null
cd C:\vader
git checkout -qf c6243dd81c98350df4dec608fa972df98fa2a3af 2> $null
}
test_script:
- cd C:\testplugin
- 'C:\vim\vim\vim80\vim.exe -u test\vimrc "+Vader!
test/*.vader test/*/*.vader test/*/*/*.vader test/*/*/*.vader"'

View File

@@ -1,14 +0,0 @@
# EditorConfig is awesome: http://EditorConfig.org
# Top-most EditorConfig file
root = true
# Match and apply these rules for all file
# types you open in your code editor
[*]
# Unix-style newlines
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

11
.eslintrc.js Normal file
View File

@@ -0,0 +1,11 @@
module.exports = {
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
},
rules: {
semi: 'error',
'space-infix-ops': 'warn',
radix: 'error',
}
}

7
.gitattributes vendored
View File

@@ -1,13 +1,8 @@
.* export-ignore
/CODE_OF_CONDUCT.md export-ignore
/CONTRIBUTING.md export-ignore
/Dockerfile export-ignore
/ISSUE_TEMPLATE export-ignore
/ISSUE_TEMPLATE.md export-ignore
/Makefile export-ignore
/PULL_REQUEST_TEMPLATE.md export-ignore
/README.md export-ignore
/img export-ignore
/run-tests export-ignore
/run-tests.bat export-ignore
/test export-ignore
/custom-checks export-ignore

View File

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

View File

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

View File

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

9
.gitignore vendored
View File

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

View File

@@ -2,6 +2,9 @@
sudo: required
services:
- docker
language: generic
branches:
only:
- master
language: python
script: |
./run-tests -v
make test

View File

@@ -1,3 +0,0 @@
Codes of conduct are totally unnecessary and dumb.
Just don't be a jerk and have fun.

View File

@@ -1,11 +1,26 @@
## Guidelines
# Contributing to ALE
1. [Guidelines](#guidelines)
2. [Creating Issues](#issues)
3. [Creating Pull Requests](#pull-requests)
1. [Adding a New Linter](#adding-a-new-linter)
2. [Adding New Options](#adding-new-options)
<a name="guidelines"></a>
# 1. Guidelines
Have fun, and work on whatever floats your boat. Take It Easy :tm:.
For help with contributing to ALE, see `:help ale-development` in Vim, or view
the help file online [here](/w0rp/ale/blob/master/doc/ale-development.txt).
When writing code, follow the [Google Vimscript Style
Guide](https://google.github.io/styleguide/vimscriptguide.xml), and run `vint
-s` on your files to check for most of what the guide mentions and more. If you
install this plugin (ALE) and install [Vint](https://github.com/Kuniwak/vint), it
will check your code while you type.
## Creating Issues
<a name="issues"></a>
# 2. Creating Issues
Before creating any issues, please look through the current list of issues and
pull requests, and ensure that the issue hasn't already been reported. If an
@@ -23,3 +38,55 @@ operating system, or any other information you think might be helpful.
Please describe your issue in clear, grammatically correct, and easy to
understand English. You are more likely to see an issue resolved if others
can understand you.
<a name="pull-requests"></a>
# 3. Creating Pull Requests
For code you write, make sure to credit yourself at the top of files you add,
and probably those you modify. You can write some comments at the top of your
VIM files.
```vim
" Author: John Smith <john.smith@gmail.com>
" Description: This file adds support for awesomelinter for the best language ever.
```
If you want to credit multiple authors, you can comma separate them.
```vim
" Author: John Smith <john.smith@gmail.com>, Jane Doe <https://jane-doe.info>
```
<a name="adding-a-new-linter"></a>
# 3.i. Adding a New Linter
If you add a new linter, look for existing handlers first in the
[handlers.vim](autoload/ale/handlers.vim) file. One of the handlers there may
already be able to handle your lines of output. If you find that your new
linter replicates an existing error handler, consider pulling it up into the
[handlers.vim](autoload/ale/handlers.vim) file, and use the generic handler in
both places.
When you add a linter, make sure the language for the linter and the linter
itself are present in the table in the [README.md](README.md) file and in the
Vim [help file](doc/ale.txt). The programs and linters should be sorted
alphabetically in the table and list.
<a name="adding-new-options"></a>
# 3.ii. Adding New Options
If you add new options to the plugin, make sure to document those new options
in the [README.md](README.md) file, and also in the [help file](doc/ale.txt).
Follow the format of other options in each. Global options should appear in the
README file, and in the relevant section in the help file. Options specific
to a particular linter should appear in the section for that linter.
Linter options for customizing general argument lists should be named
`g:ale_<filetype>_<linter>_options`, so that all linters can have similar
global variable names.
Any options for linters should be set to some default value so it is always
easy to see what the default is with `:echo g:ale...`.

View File

@@ -1,19 +1,20 @@
FROM tweekmonster/vim-testbed:latest
RUN install_vim -tag v8.0.0027 -build \
-tag neovim:v0.2.0 -build \
-tag neovim:v0.3.0 -build
RUN install_vim -tag v8.0.0000 -build \
-tag v8.0.0027 -build
ENV PACKAGES="\
bash \
git \
python \
py-pip \
python=2.7.12-r0 \
py-pip=8.1.2-r0 \
nodejs \
"
RUN apk --update add $PACKAGES && \
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
RUN pip install vim-vint==0.3.15
RUN pip install vim-vint==0.3.9
RUN npm install -g eslint@3.7.1
RUN git clone https://github.com/junegunn/vader.vim vader && \
cd vader && git checkout c6243dd81c98350df4dec608fa972df98fa2a3af

View File

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

44
Makefile Normal file
View File

@@ -0,0 +1,44 @@
SHELL := /usr/bin/env bash
IMAGE ?= w0rp/ale
CURRENT_IMAGE_ID = 107e4efc4267
DOCKER_FLAGS = --rm -v $(PWD):/testplugin -v $(PWD)/test:/home "$(IMAGE)"
test-setup:
docker images -q w0rp/ale | grep ^$(CURRENT_IMAGE_ID) > /dev/null || \
docker pull $(IMAGE)
test: test-setup
@:; \
vims=$$(docker run --rm $(IMAGE) ls /vim-build/bin | grep -E '^n?vim'); \
if [ -z "$$vims" ]; then echo "No Vims found!"; exit 1; fi; \
EXIT=0; \
for vim in $$vims; do \
echo; \
echo '========================================'; \
echo "Running tests for $$vim"; \
echo '========================================'; \
echo; \
docker run -a stderr $(DOCKER_FLAGS) $$vim '+Vader! test/*' || EXIT=$$?; \
done; \
echo; \
echo '========================================'; \
echo 'Running Vint to lint our code'; \
echo '========================================'; \
echo 'Vint warnings/errors follow:'; \
echo; \
set -o pipefail; \
docker run -a stdout $(DOCKER_FLAGS) vint -s /testplugin | sed s:^/testplugin/:: || EXIT=$$?; \
set +o pipefail; \
echo; \
echo '========================================'; \
echo 'Running custom checks'; \
echo '========================================'; \
echo 'Custom warnings/errors follow:'; \
echo; \
set -o pipefail; \
docker run -a stdout $(DOCKER_FLAGS) /testplugin/custom-checks /testplugin | sed s:^/testplugin/:: || EXIT=$$?; \
set +o pipefail; \
echo; \
exit $$EXIT;
.DEFAULT_GOAL := test

View File

@@ -1,8 +0,0 @@
<!--
Before creating a pull request, do the following.
* Read the Contributing guide linked above first.
* Read the documentation that comes with ALE with `:help ale-development`.
Have fun!
-->

690
README.md
View File

@@ -1,10 +1,9 @@
# 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)
# Asynchronous Lint Engine [![Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale)
![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true)
ALE (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim
0.2.0+ and Vim 8 while you edit your text files.
and Vim 8 while you edit your text files.
![linting example](img/example.gif?raw=true)
@@ -16,55 +15,24 @@ back to a filesystem.
In other words, this plugin allows you to lint while you type.
ALE offers support for fixing code with command line tools in a non-blocking
manner with the `:ALEFix` feature, supporting tools in many languages, like
`prettier`, `eslint`, `autopep8`, and more.
ALE acts as a "language client" to support a variety of Language Server Protocol
features, including:
* Diagnostics (via Language Server Protocol linters)
* Go To Definition (`:ALEGoToDefinition`)
* Completion (`let g:ale_completion_enabled = 1`)
* Finding references (`:ALEFindReferences`)
* Hover information (`:ALEHover`)
If you don't care about Language Server Protocol, ALE won't load any of the code
for working with it unless needed. One of ALE's general missions is that you
won't pay for the features that you don't use.
## Table of Contents
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)
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. [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. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad)
14. [How can I configure my C or C++ project?](#faq-c-configuration)
15. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration)
16. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height)
1. [Installation with Pathogen](#installation-with-pathogen)
2. [Installation with Vundle](#installation-with-vundle)
3. [Manual Installation](#manual-installation)
4. [FAQ](#faq)
1. [How do I disable particular linters?](#faq-disable-linters)
2. [How can I keep the sign gutter open?](#faq-disable-linters)
3. [How can I change the signs ALE uses?](#faq-change-signs)
4. [How can I show errors or warnings in my statusline?](#faq-statusline)
5. [How can I change the format for echo messages?](#faq-echo-format)
6. [How can I execute some code when ALE stops linting?](#faq-autocmd)
7. [How can I navigate between errors quickly?](#faq-navigation)
8. [How can I run linters only when I save files?](#faq-lint-on-save)
9. [How can I use the quickfix list instead of the loclist?](#faq-quickfix)
<a name="supported-languages"></a>
@@ -77,127 +45,66 @@ tools will be run in combination, so they can be complementary.
Keep the table rows sorted alphabetically by the language name,
and the tools in the tools column sorted alphabetically by the tool
name. That seems to be the fairest way to arrange this table.
Remember to also update doc/ale.txt, which has a similar list with different
formatting.
-->
**Notes:**
* *^ No linters for text or Vim help filetypes are enabled by default.*
* *!! These linters check only files on disk. See `:help ale-lint-file-linters`*
| Language | Tools |
| -------- | ----- |
| ASM | [gcc](https://gcc.gnu.org) |
| Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) |
| API Blueprint | [drafter](https://github.com/apiaryio/drafter) |
| AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good) |
| Awk | [gawk](https://www.gnu.org/software/gawk/)|
| Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) |
| Bourne Shell | shell [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) |
| C | [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [clang](http://clang.llvm.org/), [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) |
| C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) !!, [clangtidy](http://clang.llvm.org/extra/clang-tidy/) !!, [clang-format](https://clang.llvm.org/docs/ClangFormat.html), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) !!, [cquery](https://github.com/cquery-project/cquery), [flawfinder](https://www.dwheeler.com/flawfinder/), [gcc](https://gcc.gnu.org/) |
| CUDA | [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) |
| C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details, [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) !! see:`help ale-cs-mcsc` for details and configuration|
| Bash | [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/) |
| Bourne Shell | [-n flag](http://linux.die.net/man/1/sh), [shellcheck](https://www.shellcheck.net/) |
| C | [cppcheck](http://cppcheck.sourceforge.net), [gcc](https://gcc.gnu.org/), [clang](http://clang.llvm.org/)|
| C++ (filetype cpp) | [cppcheck] (http://cppcheck.sourceforge.net), [gcc](https://gcc.gnu.org/)|
| C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) |
| Chef | [foodcritic](http://www.foodcritic.io/) |
| Clojure | [joker](https://github.com/candid82/joker) |
| CloudFormation | [cfn-python-lint](https://github.com/awslabs/cfn-python-lint) |
| CMake | [cmakelint](https://github.com/richq/cmake-lint) |
| CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) |
| Crystal | [crystal](https://crystal-lang.org/) !! |
| CSS | [csslint](http://csslint.net/), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) |
| Cucumber | [cucumber](https://cucumber.io/) |
| CSS | [csslint](http://csslint.net/), [stylelint](https://github.com/stylelint/stylelint) |
| Cython (pyrex filetype) | [cython](http://cython.org/) |
| D | [dmd](https://dlang.org/dmd-linux.html) |
| Dafny | [dafny](https://rise4fun.com/Dafny) !! |
| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) |
| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) |
| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!|
| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) |
| Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) |
| Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) |
| Fish | fish [-n flag](https://linux.die.net/man/1/fish)
| Dockerfile | [hadolint](https://github.com/lukasmartinelli/hadolint) |
| Elixir | [credo](https://github.com/rrrene/credo) |
| Elm | [elm-make](https://github.com/elm-lang/elm-make) |
| Erlang | [erlc](http://erlang.org/doc/man/erlc.html) |
| Fortran | [gcc](https://gcc.gnu.org/) |
| Fountain | [proselint](http://proselint.com/) |
| FusionScript | [fusion-lint](https://github.com/RyanSquared/fusionscript) |
| Git Commit Messages | [gitlint](https://github.com/jorisroovers/gitlint) |
| GLSL | [glslang](https://github.com/KhronosGroup/glslang), [glslls](https://github.com/svenstaro/glsl-language-server) |
| Go | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !! |
| GraphQL | [eslint](http://eslint.org/), [gqlint](https://github.com/happylinks/gqlint), [prettier](https://github.com/prettier/prettier) |
| Haml | [haml-lint](https://github.com/brigade/haml-lint) |
| Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) |
| Haskell | [brittany](https://github.com/lspitzner/brittany), [ghc](https://www.haskell.org/ghc/), [stack-ghc](https://haskellstack.org/), [stack-build](https://haskellstack.org/) !!, [ghc-mod](https://github.com/DanielG/ghc-mod), [stack-ghc-mod](https://github.com/DanielG/ghc-mod), [hlint](https://hackage.haskell.org/package/hlint), [hdevtools](https://hackage.haskell.org/package/hdevtools), [hfmt](https://github.com/danstiner/hfmt) |
| HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [write-good](https://github.com/btford/write-good) |
| Idris | [idris](http://www.idris-lang.org/) |
| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/) |
| JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo)
| JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) |
| Kotlin | [kotlinc](https://kotlinlang.org) !!, [ktlint](https://ktlint.github.io) !! see `:help ale-integration-kotlin` for configuration instructions |
| LaTeX | [alex](https://github.com/wooorm/alex) !!, [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) |
| Less | [lessc](https://www.npmjs.com/package/less), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) |
| LLVM | [llc](https://llvm.org/docs/CommandGuide/llc.html) |
| Lua | [luac](https://www.lua.org/manual/5.1/luac.html), [luacheck](https://github.com/mpeterv/luacheck) |
| Mail | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale) |
| Make | [checkmake](https://github.com/mrtazz/checkmake) |
| Markdown | [alex](https://github.com/wooorm/alex) !!, [markdownlint](https://github.com/DavidAnson/markdownlint) !!, [mdl](https://github.com/mivok/markdownlint), [prettier](https://github.com/prettier/prettier), [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [remark-lint](https://github.com/wooorm/remark-lint) !!, [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) |
| Go | [gofmt -e](https://golang.org/cmd/gofmt/), [go vet](https://golang.org/cmd/vet/), [golint](https://godoc.org/github.com/golang/lint), [go build](https://golang.org/cmd/go/) |
| Haskell | [ghc](https://www.haskell.org/ghc/), [hlint](https://hackage.haskell.org/package/hlint) |
| HTML | [HTMLHint](http://htmlhint.com/), [tidy](http://www.html-tidy.org/) |
| JavaScript | [eslint](http://eslint.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [flow](https://flowtype.org/) |
| JSON | [jsonlint](http://zaa.ch/jsonlint/) |
| LaTeX | [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck) |
| Lua | [luacheck](https://github.com/mpeterv/luacheck) |
| Markdown | [mdl](https://github.com/mivok/markdownlint), [proselint](http://proselint.com/)|
| MATLAB | [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) |
| Mercury | [mmc](http://mercurylang.org) !! |
| NASM | [nasm](https://www.nasm.us/) !! |
| Nim | [nim check](https://nim-lang.org/docs/nimc.html) !! |
| nix | [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) |
| nroff | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)|
| Objective-C | [clang](http://clang.llvm.org/) |
| Objective-C++ | [clang](http://clang.llvm.org/) |
| OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server) |
| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic), [perltidy](https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy) |
| PHP | [hack](http://hacklang.org/), [hackfmt](https://github.com/facebook/flow/tree/master/hack/hackfmt), [langserver](https://github.com/felixfbecker/php-language-server), [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions, [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), [phpmd](https://phpmd.org), [phpstan](https://github.com/phpstan/phpstan), [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer), [php-cs-fixer](http://cs.sensiolabs.org/) |
| PO | [alex](https://github.com/wooorm/alex) !!, [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html), [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) |
| Pod | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) |
| Pony | [ponyc](https://github.com/ponylang/ponyc) |
| proto | [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) |
| OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-integration-ocaml-merlin` for configuration instructions
| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic) |
| PHP | [hack](http://hacklang.org/), [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer) |
| Pug | [pug-lint](https://github.com/pugjs/pug-lint) |
| Puppet | [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) |
| Python | [autopep8](https://github.com/hhatto/autopep8), [black](https://github.com/ambv/black), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [prospector](http://github.com/landscapeio/prospector), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pyls](https://github.com/palantir/python-language-server), [pyre](https://github.com/facebook/pyre-check), [pylint](https://www.pylint.org/) !!, [yapf](https://github.com/google/yapf) |
| QML | [qmlfmt](https://github.com/jesperhh/qmlfmt), [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) |
| R | [lintr](https://github.com/jimhester/lintr) |
| ReasonML | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions, [ols](https://github.com/freebroccolo/ocaml-language-server), [refmt](https://github.com/reasonml/reason-cli) |
| reStructuredText | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [rstcheck](https://github.com/myint/rstcheck), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) |
| Re:VIEW | [redpen](http://redpen.cc/) |
| RPM spec | [rpmlint](https://github.com/rpm-software-management/rpmlint) (disabled by default; see `:help ale-integration-spec`) |
| Ruby | [brakeman](http://brakemanscanner.org/) !!, [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) !!, [reek](https://github.com/troessner/reek), [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org), [rufo](https://github.com/ruby-formatter/rufo) |
| Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) |
| Python | [flake8](http://flake8.pycqa.org/en/latest/), [mypy](http://mypy-lang.org/), [pylint](https://www.pylint.org/) |
| Ruby | [rubocop](https://github.com/bbatsov/rubocop) |
| Rust | [rustc](https://www.rust-lang.org/), cargo (see `:help ale-integration-rust` for configuration instructions) |
| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) |
| SCSS | [prettier](https://github.com/prettier/prettier), [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) |
| Scala | [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html), [scalac](http://scala-lang.org), [scalafmt](https://scalameta.org/scalafmt/), [scalastyle](http://www.scalastyle.org) |
| Slim | [slim-lint](https://github.com/sds/slim-lint) |
| SML | [smlnj](http://www.smlnj.org/) |
| Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) |
| Stylus | [stylelint](https://github.com/stylelint/stylelint) |
| SQL | [sqlint](https://github.com/purcell/sqlint) |
| Swift | [swiftlint](https://github.com/realm/SwiftLint), [swiftformat](https://github.com/nicklockwood/SwiftFormat) |
| Tcl | [nagelfar](http://nagelfar.sourceforge.net) !! |
| Terraform | [tflint](https://github.com/wata727/tflint) |
| Texinfo | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good)|
| Text^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [textlint](https://textlint.github.io/), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) |
| Thrift | [thrift](http://thrift.apache.org/) |
| TypeScript | [eslint](http://eslint.org/), [prettier](https://github.com/prettier/prettier), [tslint](https://github.com/palantir/tslint), tsserver, typecheck |
| SCSS | [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) |
| Scala | [scalac](http://scala-lang.org) |
| Swift | [swiftlint](https://swift.org/) |
| Tex | [proselint](http://proselint.com/) |
| Text^^ | [proselint](http://proselint.com/) |
| TypeScript | [tslint](https://github.com/palantir/tslint), typecheck |
| Verilog | [iverilog](https://github.com/steveicarus/iverilog), [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) |
| Vim | [vint](https://github.com/Kuniwak/vint) |
| Vim help^ | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) |
| Vue | [prettier](https://github.com/prettier/prettier) |
| XHTML | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [write-good](https://github.com/btford/write-good) |
| XML | [xmllint](http://xmlsoft.org/xmllint.html) |
| YAML | [swaglint](https://github.com/byCedric/swaglint), [yamllint](https://yamllint.readthedocs.io/) |
| YAML | [yamllint](https://yamllint.readthedocs.io/) |
* *^^ No text linters are enabled by default.*
If you would like to see support for more languages and tools, please
[create an issue](https://github.com/w0rp/ale/issues)
or [create a pull request](https://github.com/w0rp/ale/pulls).
If your tool can read from stdin or you have code to suggest which is good,
support can be happily added for it.
<a name="usage"></a>
## 2. Usage
<a name="usage-linting"></a>
### 2.i Linting
Once this plugin is installed, while editing your files in supported
languages and tools which have been correctly installed,
this plugin will send the contents of your text buffers to a variety of
@@ -210,155 +117,19 @@ 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-linter-options` for options specified to particular linters.
<a name="usage-fixing"></a>
### 2.ii Fixing
ALE can fix files with the `ALEFix` command. Functions need to be configured
either in each buffer with a `b:ale_fixers`, or globally with `g:ale_fixers`.
The recommended way to configure fixers is to define a List in an ftplugin file.
```vim
" In ~/.vim/ftplugin/javascript.vim, or somewhere similar.
" Fix files with prettier, and then ESLint.
let b:ale_fixers = ['prettier', 'eslint']
" Equivalent to the above.
let b:ale_fixers = {'javascript': ['prettier', 'eslint']}
```
You can also configure your fixers from vimrc using `g:ale_fixers`, before
or after ALE has been loaded.
```vim
" In ~/.vim/vimrc, or somewhere similar.
let g:ale_fixers = {
\ 'javascript': ['eslint'],
\}
```
If you want to automatically fix files when you save them, you need to turn
a setting on in vimrc.
```vim
" Set this variable to 1 to fix files when you save them.
let g:ale_fix_on_save = 1
```
The `:ALEFixSuggest` command will suggest some supported tools for fixing code.
Both `g:ale_fixers` and `b:ale_fixers` can also accept functions, including
lambda functions, as fixers, for fixing files with custom tools.
See `:help ale-fix` for complete information on how to fix files with ALE.
<a name="usage-completion"></a>
### 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.
```vim
" Enable completion where available.
let g:ale_completion_enabled = 1
```
See `:help ale-completion` for more information.
<a name="usage-go-to-definition"></a>
### 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`.
See `:help ale-go-to-definition` for more information.
<a name="usage-find-references"></a>
### 2.v Find References
ALE supports finding references for words under your cursor with the
`:ALEFindReferences` command using any enabled Language Server Protocol linters
and `tsserver`.
See `:help ale-find-references` for more information.
<a name="usage-hover"></a>
### 2.vi Hovering
ALE supports "hover" information for printing brief information about symbols at
the cursor taken from Language Server Protocol linters and `tsserver` with the
`ALEHover` command.
On vim/gvim with `balloon` support you can see the information in a tooltip
that appears under the mouse when you mouseover a symbol.
See `:help ale-hover` for more information.
<a name="installation"></a>
## 3. Installation
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
`%USERPROFILE%\_vim`, or another directory if you have configured
Vim differently. On Windows, your `~/.vimrc` file will be similarly
stored in `%USERPROFILE%\_vimrc`.
<a name="standard-installation"></a>
### 3.i. Installation with Vim package management
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.
#### Vim 8 on Unix
```bash
mkdir -p ~/.vim/pack/git-plugins/start
git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale
```
#### NeoVim on Unix
```bash
mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start
git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
```
#### Vim 8 on Windows
```bash
# Run these commands in the "Git for Windows" Bash terminal
mkdir -p ~/vimfiles/pack/git-plugins/start
git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale
```
#### 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
" 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
```
<a name="installation-with-pathogen"></a>
### 3.ii. Installation with Pathogen
### 3.i. 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
@@ -372,7 +143,7 @@ git clone https://github.com/w0rp/ale.git
<a name="installation-with-vundle"></a>
### 3.iii. Installation with Vundle
### 3.ii. 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.
@@ -383,53 +154,55 @@ Plugin 'w0rp/ale'
See the Vundle documentation for more information.
<a name="contributing"></a>
<a name="manual-installation"></a>
## 4. Contributing
### 3.iii. Manual Installation
If you would like to see support for more languages and tools, please
[create an issue](https://github.com/w0rp/ale/issues)
or [create a pull request](https://github.com/w0rp/ale/pulls).
If your tool can read from stdin or you have code to suggest which is good,
support can be happily added for it.
For installation without a package manager, you can clone this git repository
into a bundle directory as with pathogen, and add the repository to your
runtime path yourself. First clone the repository.
If you are interested in the general direction of the project, check out the
[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a
Roadmap for the future, and more.
```bash
cd ~/.vim/bundle
git clone https://github.com/w0rp/ale.git
```
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).
Then, modify your `~/.vimrc` file to add this plugin to your runtime path.
```vim
set nocompatible
filetype off
let &runtimepath.=',~/.vim/bundle/ale'
filetype plugin on
```
You can add the following line 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
silent! helptags ALL
```
Because the author of this plugin is a weird nerd, this is his preferred
installation method.
<a name="faq"></a>
## 5. FAQ
## 4. FAQ
<a name="faq-disable-linters"></a>
### 5.i. How do I disable particular linters?
### 4.i. How do I disable particular linters?
By default, all available tools for all supported languages will be run. If you
want to only select a subset of the tools, you can define `b:ale_linters` for a
single buffer, or `g:ale_linters` globally.
The recommended way to configure linters is to define a List in an ftplugin
file.
By default, all available tools for all supported languages will be run.
If you want to only select a subset of the tools, simply create a
`g:ale_linters` dictionary in your vimrc file mapping filetypes
to lists of linters to run.
```vim
" In ~/.vim/ftplugin/javascript.vim, or somewhere similar.
" Enable ESLint only for JavaScript.
let b:ale_linters = ['eslint']
" Equivalent to the above.
let b:ale_linters = {'javascript': ['eslint']}
```
You can also declare which linters you want to run in your vimrc file, before or
after ALE has been loaded.
```vim
" In ~/.vim/vimrc, or somewhere similar.
let g:ale_linters = {
\ 'javascript': ['eslint'],
\}
@@ -440,21 +213,13 @@ be run for those languages, just as when the dictionary is not defined.
Running many linters should not typically obstruct editing in Vim,
as they will all be executed in separate processes simultaneously.
If you don't want ALE to run anything other than what you've explicitly asked
for, you can set `g:ale_linters_explicit` to `1`.
```vim
" Only run linters named in ale_linters settings.
let g:ale_linters_explicit = 1
```
This plugin will look for linters in the [`ale_linters`](ale_linters) directory.
Each directory within corresponds to a particular filetype in Vim, and each file
in each directory corresponds to the name of a particular linter.
<a name="faq-keep-signs"></a>
### 5.ii. How can I keep the sign gutter open?
### 4.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
@@ -465,7 +230,7 @@ let g:ale_sign_column_always = 1
<a name="faq-change-signs"></a>
### 5.iii. How can I change the signs ALE uses?
### 4.iii. How can I change the signs ALE uses?
Use these options to specify what text should be used for signs:
@@ -483,93 +248,43 @@ highlight clear ALEErrorSign
highlight clear ALEWarningSign
```
<a name="faq-change-highlights"></a>
### 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
highlighted depend on the linters being used, and the information provided to
ALE.
Highlighting can be disabled completely by setting `g:ale_set_highlights` to
`0`.
```vim
" Set this in your vimrc file to disabling highlighting
let g:ale_set_highlights = 0
```
You can control all of the highlights ALE uses, say if you are using a different
color scheme which produces ugly highlights. For example:
```vim
highlight ALEWarning ctermbg=DarkMagenta
```
See `:help ale-highlights` for more information.
<a name="faq-statusline"></a>
### 5.v. How can I show errors or warnings in my statusline?
### 4.iv. 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
status for ALE in a nice format, it is recommended to use vim-airline with ALE.
The airline extension can be enabled by adding the following to your vimrc:
You can use `ALEGetStatusLine()` to integrate ALE into vim statusline.
To enable it, you should have in your `statusline` settings
```vim
" Set this. Airline will handle the rest.
let g:airline#extensions#ale#enabled = 1
%{ALEGetStatusLine()}
```
If you don't want to use vim-airline, you can implement your own statusline
function without adding any other plugins. ALE provides a function for counting
the number of problems for this purpose, named `ale#statusline#Count`.
When errors are detected a string showing the number of errors will be shown.
You can customize the output format using the global list `g:ale_statusline_format` where:
Say you want to display all errors as one figure, and all non-errors as another
figure. You can do the following:
- The 1st element is for errors
- The 2nd element is for warnings
- The 3rd element is for when no errors are detected
e.g
```vim
function! LinterStatus() abort
let l:counts = ale#statusline#Count(bufnr(''))
let l:all_errors = l:counts.error + l:counts.style_error
let l:all_non_errors = l:counts.total - l:all_errors
return l:counts.total == 0 ? 'OK' : printf(
\ '%dW %dE',
\ all_non_errors,
\ all_errors
\)
endfunction
set statusline=%{LinterStatus()}
let g:ale_statusline_format = ['⨉ %d', '⚠ %d', '⬥ ok']
```
See `:help ale#statusline#Count()` for more information.
<a name="faq-lightline"></a>
### 5.vi. How can I show errors or warnings in my 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).
![Statusline with issues](img/issues.png)
![Statusline with no issues](img/no_issues.png)
<a name="faq-echo-format"></a>
### 5.vii. How can I change the format for echo messages?
### 4.v. 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
* `%s` is the error message itself
* `%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.
@@ -585,34 +300,24 @@ Will give you:
![Echoed message](img/echo.png)
See `:help g:ale_echo_msg_format` for more information.
<a name="faq-autocmd"></a>
### 5.viii. How can I execute some code when ALE starts or stops linting?
### 4.vi. How can I execute some code when ALE stops linting?
ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html)
events when a lint or fix cycle are started and stopped. There is also an event
that runs when a linter job has been successfully started. These events can be
used to call arbitrary functions during these respective parts of the ALE's
operation.
event whenever has a linter has been successfully executed and processed. This
autocmd event can be used to call arbitrary functions after ALE stops linting.
```vim
augroup YourGroup
autocmd!
autocmd User ALELintPre call YourFunction()
autocmd User ALELintPost call YourFunction()
autocmd User ALEJobStarted call YourFunction()
autocmd User ALEFixPre call YourFunction()
autocmd User ALEFixPost call YourFunction()
autocmd User ALELint call YourFunction()
augroup END
```
<a name="faq-navigation"></a>
### 5.ix. How can I navigate between errors quickly?
### 4.vii. 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
@@ -628,27 +333,25 @@ For more information, consult the online documentation with
<a name="faq-lint-on-save"></a>
### 5.x. How can I run linters only when I save files?
### 4.viii. 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.
when files are saved. If you wish to run linters when files are saved, not
as you are editing files, then you can turn the option for linting
when text is changed off too.
```vim
" Write this in your vimrc file
let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 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`.
<a name="faq-quickfix"></a>
### 5.xi. How can I use the quickfix list instead of the loclist?
### 4.ix. 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
@@ -672,146 +375,3 @@ let g:ale_open_list = 1
" some other plugin which sets quickfix errors, etc.
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.
<a name="faq-jsx-stylelint-eslint"></a>
### 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).
Supposing you have installed both tools correctly, configure your .jsx files so
`jsx` is included in the filetype. You can use an `autocmd` for this.
```vim
augroup FiletypeGroup
autocmd!
au BufNewFile,BufRead *.jsx set filetype=javascript.jsx
augroup END
```
Supposing the filetype has been set correctly, you can set the following
options in a jsx.vim ftplugin file.
```vim
" In ~/.vim/ftplugin/jsx.vim, or somewhere similar.
let b:ale_linters = ['stylelint', 'eslint']
let b:ale_linter_aliases = ['css']
```
Or if you want, you can configure the linters from your vimrc file.
```vim
" In ~/.vim/vimrc, or somewhere similar.
let g:ale_linters = {'jsx': ['stylelint', 'eslint']}
let g:ale_linter_aliases = {'jsx': 'css'}
```
ALE will alias the `jsx` filetype so it uses the `css` filetype linters, and
use the original Array of selected linters for `jsx` from the `g:ale_linters`
object. All available linters will be used for the filetype `javascript`, and
no linter will be run twice for the same file.
<a name="faq-my-battery-is-sad"></a>
### 5.xiii. 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>
### 5.xiv. 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
formats for project configuration files. ALE can run compilers easily, but
ALE cannot easily detect which compiler flags to use.
Some tools and build configurations can generate
[compile_commands.json](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
files. The `cppcheck`, `clangcheck`, `clangtidy` and `cquery` linters can read
these files for automatically determining the appropriate compiler flags to
use.
For linting with compilers like `gcc` and `clang`, and with other tools, you
will need to tell ALE which compiler flags to use yourself. You can use
different options for different projects with the `g:ale_pattern_options`
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.
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.
<a name="faq-buffer-configuration"></a>
### 5.xv. How can I configure ALE differently for different buffers?
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.
```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.xvi. 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
```

View File

@@ -0,0 +1,9 @@
" Author: Bjorn Neergaard <bjorn@neersighted.com>
" Description: ansible-lint for ansible-yaml files
call ale#linter#Define('ansible', {
\ 'name': 'ansible',
\ 'executable': 'ansible',
\ 'command': g:ale#util#stdin_wrapper . ' .yml ansible-lint -p',
\ 'callback': 'ale#handlers#HandlePEP8Format',
\})

View File

@@ -1,49 +0,0 @@
" Author: Bjorn Neergaard <bjorn@neersighted.com>
" Description: ansible-lint for ansible-yaml files
function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort
for l:line in a:lines[:10]
if match(l:line, '^Traceback') >= 0
return [{
\ 'lnum': 1,
\ 'text': 'An exception was thrown. See :ALEDetail',
\ 'detail': join(a:lines, "\n"),
\}]
endif
endfor
" Matches patterns line the following:
"
" test.yml:35: [EANSIBLE0002] Trailing whitespace
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: \[?([[:alnum:]]+)\]? (.*)$'
let l:output = []
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
return l:output
endfunction
call ale#linter#Define('ansible', {
\ 'name': 'ansible',
\ 'executable': 'ansible',
\ 'command': 'ansible-lint -p %t',
\ 'callback': 'ale_linters#ansible#ansible_lint#Handle',
\})

View File

@@ -1,36 +0,0 @@
" Author: nametake https://nametake.github.io
" Description: apiblueprint parser
function! ale_linters#apiblueprint#drafter#HandleErrors(buffer, lines) abort
" Matches patterns line the following:
"
" warning: (3) unable to parse response signature, expected 'response [<HTTP status code>] [(<media type>)]'; line 4, column 3k - line 4, column 22
" warning: (10) message-body asset is expected to be a pre-formatted code block, separate it by a newline and indent every of its line by 12 spaces or 3 tabs; line 30, column 5 - line 30, column 9; line 31, column 9 - line 31, column 14; line 32, column 9 - line 32, column 14
let l:pattern = '\(^.*\): (\d\+) \(.\{-\}\); line \(\d\+\), column \(\d\+\) - line \d\+, column \d\+\(.*; line \d\+, column \d\+ - line \(\d\+\), column \(\d\+\)\)\{-\}$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines[2:], l:pattern)
let l:item = {
\ 'type': l:match[1] is# 'warning' ? 'W' : 'E',
\ 'text': l:match[2],
\ 'lnum': l:match[3] + 0,
\ 'col': l:match[4] + 0,
\}
if l:match[5] isnot# ''
let l:item.end_lnum = l:match[6] + 0
let l:item.end_col = l:match[7] + 0
endif
call add(l:output, l:item)
endfor
return l:output
endfunction
call ale#linter#Define('apiblueprint', {
\ 'name': 'drafter',
\ 'output_stream': 'stderr',
\ 'executable': 'drafter',
\ 'command': 'drafter --use-line-num --validate %t',
\ 'callback': 'ale_linters#apiblueprint#drafter#HandleErrors',
\})

View File

@@ -1,11 +0,0 @@
" Author: Johannes Wienke <languitar@semipol.de>
" Description: alex for asciidoc files
call ale#linter#Define('help', {
\ 'name': 'alex',
\ 'executable': 'alex',
\ 'command': 'alex %s -t',
\ 'output_stream': 'stderr',
\ 'callback': 'ale#handlers#alex#Handle',
\ 'lint_file': 1,
\})

View File

@@ -1,9 +0,0 @@
" Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for AsciiDoc files
call ale#linter#Define('asciidoc', {
\ 'name': 'proselint',
\ 'executable': 'proselint',
\ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})

View File

@@ -1,9 +0,0 @@
" Author: rhysd https://rhysd.github.io
" Description: Redpen, a proofreading tool (http://redpen.cc)
call ale#linter#Define('asciidoc', {
\ 'name': 'redpen',
\ 'executable': 'redpen',
\ 'command': 'redpen -f asciidoc -r json %t',
\ 'callback': 'ale#handlers#redpen#HandleRedpenOutput',
\})

View File

@@ -1,9 +0,0 @@
" Author: Sumner Evans <sumner.evans98@gmail.com>
" Description: write-good for AsciiDoc files
call ale#linter#Define('asciidoc', {
\ 'name': 'write-good',
\ 'executable_callback': 'ale#handlers#writegood#GetExecutable',
\ 'command_callback': 'ale#handlers#writegood#GetCommand',
\ 'callback': 'ale#handlers#writegood#Handle',
\})

View File

@@ -1,39 +0,0 @@
" Author: Lucas Kolstad <lkolstad@uw.edu>
" Description: gcc linter for asm files
call ale#Set('asm_gcc_executable', 'gcc')
call ale#Set('asm_gcc_options', '-Wall')
function! ale_linters#asm#gcc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'asm_gcc_executable')
endfunction
function! ale_linters#asm#gcc#GetCommand(buffer) abort
return ale#Escape(ale_linters#asm#gcc#GetExecutable(a:buffer))
\ . ' -x assembler -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
endfunction
function! ale_linters#asm#gcc#Handle(buffer, lines) abort
let l:pattern = '^.\+:\(\d\+\): \([^:]\+\): \(.\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'type': l:match[2] =~? 'error' ? 'E' : 'W',
\ 'text': l:match[3],
\})
endfor
return l:output
endfunction
call ale#linter#Define('asm', {
\ 'name': 'gcc',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#asm#gcc#GetExecutable',
\ 'command_callback': 'ale_linters#asm#gcc#GetCommand',
\ 'callback': 'ale_linters#asm#gcc#Handle',
\})

View File

@@ -1,30 +0,0 @@
" Author: kmarc <korondi.mark@gmail.com>
" Description: This file adds support for using GNU awk with sripts.
let g:ale_awk_gawk_executable =
\ get(g:, 'ale_awk_gawk_executable', 'gawk')
let g:ale_awk_gawk_options =
\ get(g:, 'ale_awk_gawk_options', '')
function! ale_linters#awk#gawk#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'awk_gawk_executable')
endfunction
function! ale_linters#awk#gawk#GetCommand(buffer) abort
" note the --source 'BEGIN ...' is to prevent
" gawk from attempting to execute the body of the script
" it is linting.
return ale_linters#awk#gawk#GetExecutable(a:buffer)
\ . " --source 'BEGIN { exit } END { exit 1 }'"
\ . ' ' . ale#Var(a:buffer, 'awk_gawk_options')
\ . ' ' . '-f %t --lint /dev/null'
endfunction
call ale#linter#Define('awk', {
\ 'name': 'gawk',
\ 'executable_callback': 'ale_linters#awk#gawk#GetExecutable',
\ 'command_callback': 'ale_linters#awk#gawk#GetCommand',
\ 'callback': 'ale#handlers#gawk#HandleGawkFormat',
\ 'output_stream': 'both'
\})

View File

@@ -1,32 +1,20 @@
" 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#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_clang_executable')
endfunction
function! ale_linters#c#clang#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#c#clang#GetExecutable(a:buffer))
\ . ' -S -x c -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
\ . l:cflags
\ . ale#Var(a:buffer, 'c_clang_options') . ' -'
endfunction
" Set this option to change the Clang options for warnings for C.
if !exists('g:ale_c_clang_options')
" let g:ale_c_clang_options = '-Wall'
" let g:ale_c_clang_options = '-std=c99 -Wall'
" c11 compatible
let g:ale_c_clang_options = '-std=c11 -Wall'
endif
call ale#linter#Define('c', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#c#clang#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#c#clang#GetCommand'}
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'executable': 'clang',
\ 'command': 'clang -S -x c -fsyntax-only '
\ . g:ale_c_clang_options
\ . ' -',
\ 'callback': 'ale#handlers#HandleGCCFormat',
\})

View File

@@ -1,64 +0,0 @@
" Author: vdeurzen <tim@kompiler.org>, w0rp <devw0rp@gmail.com>,
" gagbo <gagbobada@gmail.com>, Andrej Radovic <r.andrej@gmail.com>
" Description: clang-tidy linter for c files
call ale#Set('c_clangtidy_executable', 'clang-tidy')
" Set this option to check the checks clang-tidy will apply.
" The number of checks that can be applied to C files is limited in contrast to
" C++
"
" Consult the check list in clang-tidy's documentation:
" 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.
" This will disable compile_commands.json detection.
call ale#Set('c_clangtidy_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#c#clangtidy#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_clangtidy_executable')
endfunction
function! s:GetBuildDirectory(buffer) abort
" Don't include build directory for header files, as compile_commands.json
" files don't consider headers to be translation units, and provide no
" commands for compiling header files.
if expand('#' . a:buffer) =~# '\v\.(h|hpp)$'
return ''
endif
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
" c_build_dir has the priority if defined
if !empty(l:build_dir)
return l:build_dir
endif
return ale#c#FindCompileCommands(a:buffer)
endfunction
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',')
let l:build_dir = s:GetBuildDirectory(a:buffer)
" Get the extra options if we couldn't find a build directory.
let l:options = empty(l:build_dir)
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
\ : ''
return ale#Escape(ale_linters#c#clangtidy#GetExecutable(a:buffer))
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . ' %s'
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . (!empty(l:options) ? ' -- ' . l:options : '')
endfunction
call ale#linter#Define('c', {
\ 'name': 'clangtidy',
\ 'output_stream': 'stdout',
\ 'executable_callback': 'ale_linters#c#clangtidy#GetExecutable',
\ 'command_callback': 'ale_linters#c#clangtidy#GetCommand',
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

View File

@@ -1,39 +1,16 @@
" Author: Bart Libert <bart.libert@gmail.com>
" Description: cppcheck linter for c files
call ale#Set('c_cppcheck_executable', 'cppcheck')
call ale#Set('c_cppcheck_options', '--enable=style')
function! ale_linters#c#cppcheck#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_cppcheck_executable')
endfunction
function! ale_linters#c#cppcheck#GetCommand(buffer) abort
" Search upwards from the file for compile_commands.json.
"
" If we find it, we'll `cd` to where the compile_commands.json file is,
" then use the file to set up import paths, etc.
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
let l:cd_command = !empty(l:compile_commmands_path)
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
\ : ''
let l:compile_commands_option = !empty(l:compile_commmands_path)
\ ? '--project=compile_commands.json '
\ : ''
return l:cd_command
\ . ale#Escape(ale_linters#c#cppcheck#GetExecutable(a:buffer))
\ . ' -q --language=c '
\ . l:compile_commands_option
\ . ale#Var(a:buffer, 'c_cppcheck_options')
\ . ' %t'
endfunction
" Set this option to change the cppcheck options
if !exists('g:ale_c_cppcheck_options')
let g:ale_c_cppcheck_options = '--enable=style'
endif
call ale#linter#Define('c', {
\ 'name': 'cppcheck',
\ 'output_stream': 'both',
\ 'executable_callback': 'ale_linters#c#cppcheck#GetExecutable',
\ 'command_callback': 'ale_linters#c#cppcheck#GetCommand',
\ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat',
\ 'executable': 'cppcheck',
\ 'command': g:ale#util#stdin_wrapper . ' .c cppcheck -q --language=c '
\ . g:ale_c_cppcheck_options,
\ 'callback': 'ale#handlers#HandleCppCheckFormat',
\})

View File

@@ -1,31 +0,0 @@
" Author: Christian Gibbons <cgibbons@gmu.edu>
" Description: flawfinder linter for c files
call ale#Set('c_flawfinder_executable', 'flawfinder')
call ale#Set('c_flawfinder_options', '')
call ale#Set('c_flawfinder_minlevel', 1)
call ale#Set('c_flawfinder_error_severity', 6)
function! ale_linters#c#flawfinder#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_flawfinder_executable')
endfunction
function! ale_linters#c#flawfinder#GetCommand(buffer) abort
" Set the minimum vulnerability level for flawfinder to bother with
let l:minlevel = ' --minlevel=' . ale#Var(a:buffer, 'c_flawfinder_minlevel')
return ale#Escape(ale_linters#c#flawfinder#GetExecutable(a:buffer))
\ . ' -CDQS'
\ . ale#Var(a:buffer, 'c_flawfinder_options')
\ . l:minlevel
\ . ' %t'
endfunction
call ale#linter#Define('c', {
\ 'name': 'flawfinder',
\ 'output_stream': 'stdout',
\ 'executable_callback': 'ale_linters#c#flawfinder#GetExecutable',
\ 'command_callback': 'ale_linters#c#flawfinder#GetCommand',
\ 'callback': 'ale#handlers#flawfinder#HandleFlawfinderFormat',
\})

View File

@@ -1,32 +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')
" Set this option to change the GCC options for warnings for C.
if !exists('g:ale_c_gcc_options')
" let g:ale_c_gcc_options = '-Wall'
" let g:ale_c_gcc_options = '-std=c99 -Wall'
" c11 compatible
let g:ale_c_gcc_options = '-std=c11 -Wall'
endif
function! ale_linters#c#gcc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_gcc_executable')
endfunction
function! ale_linters#c#gcc#GetCommand(buffer) abort
return 'gcc -S -x c -fsyntax-only '
\ . g:ale_c_gcc_options . ' -'
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 ale#Escape(ale_linters#c#gcc#GetExecutable(a:buffer))
\ . ' -S -x c -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
\ . l:cflags
\ . ale#Var(a:buffer, 'c_gcc_options') . ' -'
endfunction
call ale#linter#Define('c', {
\ 'name': 'gcc',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#c#gcc#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#c#gcc#GetCommand'}
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'executable': 'gcc',
\ 'command_callback': 'ale_linters#c#gcc#GetCommand',
\ 'callback': 'ale#handlers#HandleGCCFormat',
\})

View File

@@ -1,38 +1,31 @@
" Author: Edward Larkey <edwlarkey@mac.com>
" Author: Jose Junior <jose.junior@gmail.com>
" Author: w0rp <devw0rp@gmail.com>
" Description: This file adds the foodcritic linter for Chef files.
call ale#Set('chef_foodcritic_executable', 'foodcritic')
call ale#Set('chef_foodcritic_options', '')
function! ale_linters#chef#foodcritic#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'chef_foodcritic_executable')
endfunction
function! ale_linters#chef#foodcritic#GetCommand(buffer) abort
let l:executable = ale_linters#chef#foodcritic#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'chef_foodcritic_options')
return ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . escape(l:options, '~') : '')
\ . ' %s'
endfunction
function! ale_linters#chef#foodcritic#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" FC002: Avoid string interpolation where not required: httpd.rb:13
let l:pattern = '\v([^:]+): (.+): ([a-zA-Z]?:?[^:]+):(\d+)$'
let l:pattern = '^\(.\+:\s.\+\):\s\(.\+\):\(\d\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
let l:text = l:match[1]
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'code': l:match[1],
\ 'text': l:match[2],
\ 'filename': l:match[3],
\ 'lnum': l:match[4] + 0,
\ 'bufnr': a:buffer,
\ 'lnum': l:match[3] + 0,
\ 'vcol': 0,
\ 'col': 0,
\ 'text': l:text,
\ 'type': 'W',
\ 'nr': -1,
\})
endfor
@@ -41,8 +34,8 @@ endfunction
call ale#linter#Define('chef', {
\ 'name': 'foodcritic',
\ 'executable_callback': 'ale_linters#chef#foodcritic#GetExecutable',
\ 'command_callback': 'ale_linters#chef#foodcritic#GetCommand',
\ 'executable': 'foodcritic',
\ 'command': g:ale#util#stdin_wrapper . ' .rb foodcritic',
\ 'callback': 'ale_linters#chef#foodcritic#Handle',
\ 'lint_file': 1,
\})

View File

@@ -1,32 +0,0 @@
" Author: Nic West <nicwest@mailbox.org>
" Description: linter for clojure using joker https://github.com/candid82/joker
function! ale_linters#clojure#joker#HandleJokerFormat(buffer, lines) abort
" output format
" <filename>:<line>:<column>: <issue type>: <message>
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+):? ((Read error|Parse error|Parse warning|Exception): ?(.+))$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:type = 'E'
if l:match[4] is? 'Parse 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': 'joker',
\ 'output_stream': 'stderr',
\ 'executable': 'joker',
\ 'command': 'joker --lint %t',
\ 'callback': 'ale_linters#clojure#joker#HandleJokerFormat',
\})

View File

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

View File

@@ -1,24 +0,0 @@
" Author: Kenneth Benzie <k.benzie83@gmail.com>
" Description: cmakelint for cmake files
let g:ale_cmake_cmakelint_executable =
\ get(g:, 'ale_cmake_cmakelint_executable', 'cmakelint')
let g:ale_cmake_cmakelint_options =
\ get(g:, 'ale_cmake_cmakelint_options', '')
function! ale_linters#cmake#cmakelint#Executable(buffer) abort
return ale#Var(a:buffer, 'cmake_cmakelint_executable')
endfunction
function! ale_linters#cmake#cmakelint#Command(buffer) abort
return ale_linters#cmake#cmakelint#Executable(a:buffer)
\ . ' ' . ale#Var(a:buffer, 'cmake_cmakelint_options') . ' %t'
endfunction
call ale#linter#Define('cmake', {
\ 'name': 'cmakelint',
\ 'executable_callback': 'ale_linters#cmake#cmakelint#Executable',
\ 'command_callback': 'ale_linters#cmake#cmakelint#Command',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})

View File

@@ -1,23 +1,10 @@
" Author: KabbAmine - https://github.com/KabbAmine
" Description: Coffee for checking coffee files
function! ale_linters#coffee#coffee#GetExecutable(buffer) abort
return ale#path#ResolveLocalPath(
\ a:buffer,
\ 'node_modules/.bin/coffee',
\ 'coffee'
\)
endfunction
function! ale_linters#coffee#coffee#GetCommand(buffer) abort
return ale_linters#coffee#coffee#GetExecutable(a:buffer)
\ . ' -cp -s'
endfunction
call ale#linter#Define('coffee', {
\ 'name': 'coffee',
\ 'executable_callback': 'ale_linters#coffee#coffee#GetExecutable',
\ 'command_callback': 'ale_linters#coffee#coffee#GetCommand',
\ 'executable': 'coffee',
\ 'command': 'coffee -cp -s',
\ 'output_stream': 'stderr',
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'callback': 'ale#handlers#HandleGCCFormat',
\})

View File

@@ -1,19 +1,6 @@
" Author: Prashanth Chandra https://github.com/prashcr
" Description: coffeelint linter for coffeescript files
function! ale_linters#coffee#coffeelint#GetExecutable(buffer) abort
return ale#path#ResolveLocalPath(
\ a:buffer,
\ 'node_modules/.bin/coffeelint',
\ 'coffeelint'
\)
endfunction
function! ale_linters#coffee#coffeelint#GetCommand(buffer) abort
return ale_linters#coffee#coffeelint#GetExecutable(a:buffer)
\ . ' --stdin --reporter csv'
endfunction
function! ale_linters#coffee#coffeelint#Handle(buffer, lines) abort
" Matches patterns like the following:
"
@@ -21,14 +8,30 @@ function! ale_linters#coffee#coffeelint#Handle(buffer, lines) abort
" stdin,14,,error,Throwing strings is forbidden
"
" Note that we currently ignore lineNumberEnd for multiline errors
let l:pattern = 'stdin,\(\d\+\),\(\d*\),\(.\{-1,}\),\(.\+\)'
let l:pattern = 'stdin,\(\d\+\),\(\d*\),\(.\+\),\(.\+\)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
let l:line = l:match[1] + 0
let l:column = 1
let l:type = l:match[3] ==# 'error' ? 'E' : 'W'
let l:text = l:match[4]
" vcol is needed to indicate that the column is a character
call add(l:output, {
\ 'lnum': str2nr(l:match[1]),
\ 'type': l:match[3] is# 'error' ? 'E' : 'W',
\ 'text': l:match[4],
\ 'bufnr': a:buffer,
\ 'lnum': l:line,
\ 'vcol': 0,
\ 'col': l:column,
\ 'text': l:text,
\ 'type': l:type,
\ 'nr': -1,
\})
endfor
@@ -37,7 +40,7 @@ endfunction
call ale#linter#Define('coffee', {
\ 'name': 'coffeelint',
\ 'executable_callback': 'ale_linters#coffee#coffeelint#GetExecutable',
\ 'command_callback': 'ale_linters#coffee#coffeelint#GetCommand',
\ 'executable': 'coffeelint',
\ 'command': 'coffeelint --stdin --reporter csv',
\ 'callback': 'ale_linters#coffee#coffeelint#Handle',
\})

View File

@@ -1,32 +0,0 @@
" 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#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_clang_executable')
endfunction
function! ale_linters#cpp#clang#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#cpp#clang#GetExecutable(a:buffer))
\ . ' -S -x c++ -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
\ . l:cflags
\ . ale#Var(a:buffer, 'cpp_clang_options') . ' -'
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#cpp#clang#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#cpp#clang#GetCommand'},
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})

View File

@@ -1,39 +0,0 @@
" Author: gagbo <gagbobada@gmail.com>
" Description: clang-check linter for cpp files
call ale#Set('cpp_clangcheck_executable', 'clang-check')
call ale#Set('cpp_clangcheck_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangcheck#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_clangcheck_executable')
endfunction
function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
let l:user_options = ale#Var(a:buffer, 'cpp_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:build_dir = 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 ale#Escape(ale_linters#cpp#clangcheck#GetExecutable(a:buffer))
\ . ' -analyze %s'
\ . (empty(l:build_dir) ? ' -extra-arg -Xclang -extra-arg -analyzer-output=text' : '')
\ . (!empty(l:user_options) ? ' ' . l:user_options : '')
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'clangcheck',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#cpp#clangcheck#GetExecutable',
\ 'command_callback': 'ale_linters#cpp#clangcheck#GetCommand',
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

View File

@@ -1,58 +0,0 @@
" Author: vdeurzen <tim@kompiler.org>, w0rp <devw0rp@gmail.com>,
" gagbo <gagbobada@gmail.com>
" Description: clang-tidy linter for cpp files
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.
" This will disable compile_commands.json detection.
call ale#Set('cpp_clangtidy_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangtidy#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_clangtidy_executable')
endfunction
function! s:GetBuildDirectory(buffer) abort
" Don't include build directory for header files, as compile_commands.json
" files don't consider headers to be translation units, and provide no
" commands for compiling header files.
if expand('#' . a:buffer) =~# '\v\.(h|hpp)$'
return ''
endif
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
" c_build_dir has the priority if defined
if !empty(l:build_dir)
return l:build_dir
endif
return ale#c#FindCompileCommands(a:buffer)
endfunction
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',')
let l:build_dir = s:GetBuildDirectory(a:buffer)
" Get the extra options if we couldn't find a build directory.
let l:options = empty(l:build_dir)
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
\ : ''
return ale#Escape(ale_linters#cpp#clangtidy#GetExecutable(a:buffer))
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . ' %s'
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . (!empty(l:options) ? ' -- ' . l:options : '')
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'clangtidy',
\ 'output_stream': 'stdout',
\ 'executable_callback': 'ale_linters#cpp#clangtidy#GetExecutable',
\ 'command_callback': 'ale_linters#cpp#clangtidy#GetCommand',
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

View File

@@ -1,39 +1,16 @@
" Author: Bart Libert <bart.libert@gmail.com>
" Description: cppcheck linter for cpp files
call ale#Set('cpp_cppcheck_executable', 'cppcheck')
call ale#Set('cpp_cppcheck_options', '--enable=style')
function! ale_linters#cpp#cppcheck#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_cppcheck_executable')
endfunction
function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
" Search upwards from the file for compile_commands.json.
"
" If we find it, we'll `cd` to where the compile_commands.json file is,
" then use the file to set up import paths, etc.
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
let l:cd_command = !empty(l:compile_commmands_path)
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
\ : ''
let l:compile_commands_option = !empty(l:compile_commmands_path)
\ ? '--project=compile_commands.json '
\ : ''
return l:cd_command
\ . ale#Escape(ale_linters#cpp#cppcheck#GetExecutable(a:buffer))
\ . ' -q --language=c++ '
\ . l:compile_commands_option
\ . ale#Var(a:buffer, 'cpp_cppcheck_options')
\ . ' %t'
endfunction
" Set this option to change the cppcheck options
if !exists('g:ale_cpp_cppcheck_options')
let g:ale_cpp_cppcheck_options = '--enable=style'
endif
call ale#linter#Define('cpp', {
\ 'name': 'cppcheck',
\ 'output_stream': 'both',
\ 'executable_callback': 'ale_linters#cpp#cppcheck#GetExecutable',
\ 'command_callback': 'ale_linters#cpp#cppcheck#GetCommand',
\ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat',
\ 'executable': 'cppcheck',
\ 'command': g:ale#util#stdin_wrapper . ' .cpp cppcheck -q --language=c++ '
\ . g:ale_cpp_cppcheck_options,
\ 'callback': 'ale#handlers#HandleCppCheckFormat',
\})

View File

@@ -1,26 +0,0 @@
" Author: Dawid Kurek https://github.com/dawikur
" Description: cpplint for cpp files
call ale#Set('cpp_cpplint_executable', 'cpplint')
call ale#Set('cpp_cpplint_options', '')
function! ale_linters#cpp#cpplint#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_cpplint_executable')
endfunction
function! ale_linters#cpp#cpplint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'cpp_cpplint_options')
return ale#Escape(ale_linters#cpp#cpplint#GetExecutable(a:buffer))
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %s'
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'cpplint',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#cpp#cpplint#GetExecutable',
\ 'command_callback': 'ale_linters#cpp#cpplint#GetCommand',
\ 'callback': 'ale#handlers#cpplint#HandleCppLintFormat',
\ 'lint_file': 1,
\})

View File

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

View File

@@ -1,31 +0,0 @@
" Author: Christian Gibbons <cgibbons@gmu.edu>
" Description: flawfinder linter for c++ files
call ale#Set('cpp_flawfinder_executable', 'flawfinder')
call ale#Set('cpp_flawfinder_options', '')
call ale#Set('cpp_flawfinder_minlevel', 1)
call ale#Set('c_flawfinder_error_severity', 6)
function! ale_linters#cpp#flawfinder#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_flawfinder_executable')
endfunction
function! ale_linters#cpp#flawfinder#GetCommand(buffer) abort
" Set the minimum vulnerability level for flawfinder to bother with
let l:minlevel = ' --minlevel=' . ale#Var(a:buffer, 'cpp_flawfinder_minlevel')
return ale#Escape(ale_linters#cpp#flawfinder#GetExecutable(a:buffer))
\ . ' -CDQS'
\ . ale#Var(a:buffer, 'cpp_flawfinder_options')
\ . l:minlevel
\ . ' %t'
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'flawfinder',
\ 'output_stream': 'stdout',
\ 'executable_callback': 'ale_linters#cpp#flawfinder#GetExecutable',
\ 'command_callback': 'ale_linters#cpp#flawfinder#GetCommand',
\ 'callback': 'ale#handlers#flawfinder#HandleFlawfinderFormat',
\})

View File

@@ -1,33 +1,30 @@
" 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#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cpp_gcc_executable')
endfunction
" Set this option to change the GCC options for warnings for C.
if !exists('g:ale_cpp_gcc_options')
" added c++14 standard support
" POSIX thread and standard c++ thread and atomic library Linker
" let g:ale_cpp_gcc_options = '-std=c++1z' for c++17
" for previous version and default, you can just use
" let g:ale_cpp_gcc_options = '-Wall'
" for more see man pages of gcc
" $ man g++
" make sure g++ in your $PATH
" Add flags according to your requirements
let g:ale_cpp_gcc_options = '-std=c++14 -Wall'
endif
function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
function! ale_linters#cpp#gcc#GetCommand(buffer) abort
return 'gcc -S -x c++ -fsyntax-only '
\ . g:ale_cpp_gcc_options . ' -'
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#cpp#gcc#GetExecutable(a:buffer))
\ . ' -S -x c++ -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
\ . l:cflags
\ . ale#Var(a:buffer, 'cpp_gcc_options') . ' -'
endfunction
call ale#linter#Define('cpp', {
\ 'name': 'gcc',
\ 'aliases': ['g++'],
\ 'name': 'g++',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#cpp#gcc#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#cpp#gcc#GetCommand'},
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'executable': 'g++',
\ 'command_callback': 'ale_linters#cpp#gcc#GetCommand',
\ 'callback': 'ale#handlers#HandleGCCFormat',
\})

View File

@@ -1,31 +0,0 @@
" Author: Jordan Andree <https://github.com/jordanandree>, David Alexander <opensource@thelonelyghost.com>
" Description: This file adds support for checking Crystal with crystal build
function! ale_linters#crystal#crystal#Handle(buffer, lines) abort
let l:output = []
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
call add(l:output, {
\ 'lnum': l:error.line + 0,
\ 'col': l:error.column + 0,
\ 'text': l:error.message,
\})
endfor
return l:output
endfunction
function! ale_linters#crystal#crystal#GetCommand(buffer) abort
return 'crystal build -f json --no-codegen --no-color -o '
\ . ale#Escape(g:ale#util#nul_file)
\ . ' %s'
endfunction
call ale#linter#Define('crystal', {
\ 'name': 'crystal',
\ 'executable': 'crystal',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\ 'command_callback': 'ale_linters#crystal#crystal#GetCommand',
\ 'callback': 'ale_linters#crystal#crystal#Handle',
\})

View File

@@ -1,23 +1,29 @@
let g:ale_cs_mcs_options = get(g:, 'ale_cs_mcs_options', '')
function! ale_linters#cs#mcs#GetCommand(buffer) abort
return 'mcs -unsafe --parse ' . ale#Var(a:buffer, 'cs_mcs_options') . ' %t'
endfunction
if !exists('g:ale_cs_mcs_options')
let g:ale_cs_mcs_options = ''
endif
function! ale_linters#cs#mcs#Handle(buffer, lines) abort
" Look for lines like the following.
"
" Tests.cs(12,29): error CSXXXX: ; expected
let l:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$'
let l:pattern = '^.\+.cs(\(\d\+\),\(\d\+\)): \(.\+\): \(.\+\)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
call add(l:output, {
\ '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],
\ 'bufnr': a:buffer,
\ 'lnum': l:match[1] + 0,
\ 'vcol': 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3] . ': ' . l:match[4],
\ 'type': l:match[3] =~# '^error' ? 'E' : 'W',
\ 'nr': -1,
\})
endfor
@@ -25,9 +31,10 @@ function! ale_linters#cs#mcs#Handle(buffer, lines) abort
endfunction
call ale#linter#Define('cs',{
\ 'name': 'mcs',
\ 'output_stream': 'stderr',
\ 'executable': 'mcs',
\ 'command_callback': 'ale_linters#cs#mcs#GetCommand',
\ 'callback': 'ale_linters#cs#mcs#Handle',
\})
\ 'name': 'mcs',
\ 'output_stream': 'stderr',
\ 'executable': 'mcs',
\ 'command': g:ale#util#stdin_wrapper . ' .cs mcs -unsafe --parse' . g:ale_cs_mcs_options,
\ 'callback': 'ale_linters#cs#mcs#Handle',
\ })

View File

@@ -1,81 +0,0 @@
call ale#Set('cs_mcsc_options', '')
call ale#Set('cs_mcsc_source', '')
call ale#Set('cs_mcsc_assembly_path', [])
call ale#Set('cs_mcsc_assemblies', [])
function! s:GetWorkingDirectory(buffer) abort
let l:working_directory = ale#Var(a:buffer, 'cs_mcsc_source')
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
" Pass assembly paths via the -lib: parameter.
let l:path_list = ale#Var(a:buffer, 'cs_mcsc_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_mcsc_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
let l:out = tempname()
call ale#engine#ManageFile(a:buffer, l:out)
" The code is compiled as a module and the output is redirected to a
" temporary file.
return ale#path#CdString(s:GetWorkingDirectory(a:buffer))
\ . 'mcs -unsafe'
\ . ' ' . ale#Var(a:buffer, 'cs_mcsc_options')
\ . ' ' . l:lib_option
\ . ' ' . l:r_option
\ . ' -out:' . l:out
\ . ' -t:module'
\ . ' -recurse:' . ale#Escape('*.cs')
endfunction
function! ale_linters#cs#mcsc#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:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$'
let l:output = []
let l:dir = s:GetWorkingDirectory(a:buffer)
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
endfunction
call ale#linter#Define('cs',{
\ 'name': 'mcsc',
\ 'output_stream': 'stderr',
\ 'executable': 'mcs',
\ 'command_callback': 'ale_linters#cs#mcsc#GetCommand',
\ 'callback': 'ale_linters#cs#mcsc#Handle',
\ 'lint_file': 1
\})

View File

@@ -1,18 +1,9 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: This file adds support for checking CSS code with csslint.
function! ale_linters#css#csslint#GetCommand(buffer) abort
let l:csslintrc = ale#path#FindNearestFile(a:buffer, '.csslintrc')
let l:config_option = !empty(l:csslintrc)
\ ? '--config=' . ale#Escape(l:csslintrc)
\ : ''
return 'csslint --format=compact ' . l:config_option . ' %t'
endfunction
call ale#linter#Define('css', {
\ 'name': 'csslint',
\ 'executable': 'csslint',
\ 'command_callback': 'ale_linters#css#csslint#GetCommand',
\ 'callback': 'ale#handlers#css#HandleCSSLintFormat',
\ 'command': g:ale#util#stdin_wrapper . ' .css csslint --format=compact',
\ 'callback': 'ale#handlers#HandleCSSLintFormat',
\})

View File

@@ -1,18 +1,25 @@
" Author: diartyz <diartyz@gmail.com>
call ale#Set('css_stylelint_executable', 'stylelint')
call ale#Set('css_stylelint_options', '')
call ale#Set('css_stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
let g:ale_css_stylelint_executable =
\ get(g:, 'ale_css_stylelint_executable', 'stylelint')
let g:ale_css_stylelint_use_global =
\ get(g:, 'ale_css_stylelint_use_global', 0)
function! ale_linters#css#stylelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'css_stylelint', [
if g:ale_css_stylelint_use_global
return g:ale_css_stylelint_executable
endif
return ale#util#ResolveLocalPath(
\ a:buffer,
\ 'node_modules/.bin/stylelint',
\])
\ g:ale_css_stylelint_executable
\)
endfunction
function! ale_linters#css#stylelint#GetCommand(buffer) abort
return ale_linters#css#stylelint#GetExecutable(a:buffer)
\ . ' ' . ale#Var(a:buffer, 'css_stylelint_options')
\ . ' --stdin-filename %s'
endfunction
@@ -20,5 +27,5 @@ call ale#linter#Define('css', {
\ 'name': 'stylelint',
\ 'executable_callback': 'ale_linters#css#stylelint#GetExecutable',
\ 'command_callback': 'ale_linters#css#stylelint#GetCommand',
\ 'callback': 'ale#handlers#css#HandleStyleLintFormat',
\ 'callback': 'ale#handlers#HandleStyleLintFormat',
\})

View File

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

View File

@@ -1,56 +0,0 @@
" Author: blahgeek <i@blahgeek.com>
" Description: NVCC linter for cuda files
call ale#Set('cuda_nvcc_executable', 'nvcc')
call ale#Set('cuda_nvcc_options', '-std=c++11')
function! ale_linters#cuda#nvcc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'cuda_nvcc_executable')
endfunction
function! ale_linters#cuda#nvcc#GetCommand(buffer) abort
" Unused: use ale#util#nul_file
" let l:output_file = tempname() . '.ii'
" call ale#engine#ManageFile(a:buffer, l:output_file)
return ale#Escape(ale_linters#cuda#nvcc#GetExecutable(a:buffer))
\ . ' -cuda '
\ . ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
\ . ale#Var(a:buffer, 'cuda_nvcc_options') . ' %s'
\ . ' -o ' . g:ale#util#nul_file
endfunction
function! ale_linters#cuda#nvcc#HandleNVCCFormat(buffer, lines) abort
" Look for lines like the following.
"
" test.cu(8): error: argument of type "void *" is incompatible with parameter of type "int *"
let l:pattern = '\v^([^:\(\)]+):?\(?(\d+)\)?:(\d+)?:?\s*\w*\s*(error|warning): (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:item = {
\ 'lnum': str2nr(l:match[2]),
\ 'type': l:match[4] =~# 'error' ? 'E' : 'W',
\ 'text': l:match[5],
\ 'filename': fnamemodify(l:match[1], ':p'),
\}
if !empty(l:match[3])
let l:item.col = str2nr(l:match[3])
endif
call add(l:output, l:item)
endfor
return l:output
endfunction
call ale#linter#Define('cuda', {
\ 'name': 'nvcc',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#cuda#nvcc#GetExecutable',
\ 'command_callback': 'ale_linters#cuda#nvcc#GetCommand',
\ 'callback': 'ale_linters#cuda#nvcc#HandleNVCCFormat',
\ 'lint_file': 1,
\})

View File

@@ -5,7 +5,7 @@ function! s:FindDUBConfig(buffer) abort
" Find a DUB configuration file in ancestor paths.
" The most DUB-specific names will be tried first.
for l:possible_filename in ['dub.sdl', 'dub.json', 'package.json']
let l:dub_file = ale#path#FindNearestFile(a:buffer, l:possible_filename)
let l:dub_file = ale#util#FindNearestFile(a:buffer, l:possible_filename)
if !empty(l:dub_file)
return l:dub_file
@@ -31,7 +31,7 @@ function! ale_linters#d#dmd#DUBCommand(buffer) abort
" 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'))
return 'cd ' . fnameescape(fnamemodify(l:dub_file, ':h'))
\ . ' && dub describe --import-paths'
endfunction
@@ -42,11 +42,13 @@ function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort
for l:line in a:dub_output
if !empty(l:line)
" The arguments must be '-Ifilename', not '-I filename'
call add(l:import_list, '-I' . ale#Escape(l:line))
call add(l:import_list, '-I' . fnameescape(l:line))
endif
endfor
return 'dmd '. join(l:import_list) . ' -o- -wi -vcolumns -c %t'
return g:ale#util#stdin_wrapper . ' .d dmd '
\ . join(l:import_list)
\ . ' -o- -vcolumns -c'
endfunction
function! ale_linters#d#dmd#Handle(buffer, lines) abort
@@ -56,12 +58,27 @@ function! ale_linters#d#dmd#Handle(buffer, lines) abort
let l:pattern = '^[^(]\+(\([0-9]\+\)\,\?\([0-9]*\)): \([^:]\+\): \(.\+\)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
break
endif
let l:line = l:match[1] + 0
let l:column = l:match[2] + 0
let l:type = l:match[3]
let l:text = l:match[4]
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'lnum': l:match[1],
\ 'col': l:match[2],
\ 'type': l:match[3] is# 'Warning' ? 'W' : 'E',
\ 'text': l:match[4],
\ 'bufnr': bufnr('%'),
\ 'lnum': l:line,
\ 'vcol': 0,
\ 'col': l:column,
\ 'text': l:text,
\ 'type': l:type ==# 'Warning' ? 'W' : 'E',
\ 'nr': -1,
\})
endfor

View File

@@ -1,25 +0,0 @@
" Author: Taylor Blau <me@ttaylorr.com>
function! ale_linters#dafny#dafny#Handle(buffer, lines) abort
let l:pattern = '\v(.*)\((\d+),(\d+)\): (.*): (.*)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'col': l:match[3] + 0,
\ 'lnum': l:match[2] + 0,
\ 'text': l:match[5],
\ 'type': l:match[4] =~# '^Error' ? 'E' : 'W'
\ })
endfor
return l:output
endfunction
call ale#linter#Define('dafny', {
\ 'name': 'dafny',
\ 'executable': 'dafny',
\ 'command': 'dafny %s /compile:0',
\ 'callback': 'ale_linters#dafny#dafny#Handle',
\ 'lint_file': 1,
\ })

View File

@@ -1,41 +0,0 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Check Dart files with dartanalyzer
call ale#Set('dart_dartanalyzer_executable', 'dartanalyzer')
function! ale_linters#dart#dartanalyzer#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'dart_dartanalyzer_executable')
endfunction
function! ale_linters#dart#dartanalyzer#GetCommand(buffer) abort
let l:executable = ale_linters#dart#dartanalyzer#GetExecutable(a:buffer)
let l:path = ale#path#FindNearestFile(a:buffer, '.packages')
return ale#Escape(l:executable)
\ . (!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_callback': 'ale_linters#dart#dartanalyzer#GetExecutable',
\ 'command_callback': 'ale_linters#dart#dartanalyzer#GetCommand',
\ 'callback': 'ale_linters#dart#dartanalyzer#Handle',
\ 'lint_file': 1,
\})

View File

@@ -1,25 +0,0 @@
" Author: aurieh <me@aurieh.me>
" Description: A language server for dart
call ale#Set('dart_language_server_executable', 'dart_language_server')
function! ale_linters#dart#language_server#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'dart_language_server_executable')
endfunction
function! ale_linters#dart#language_server#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
call ale#linter#Define('dart', {
\ 'name': 'language_server',
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#dart#language_server#GetExecutable',
\ 'command_callback': 'ale_linters#dart#language_server#GetExecutable',
\ 'language': 'dart',
\ 'project_root_callback': 'ale_linters#dart#language_server#GetProjectRoot',
\})

View File

@@ -1,97 +1,45 @@
" Author: hauleth - https://github.com/hauleth
" always, yes, never
call ale#Set('dockerfile_hadolint_use_docker', 'never')
call ale#Set('dockerfile_hadolint_docker_image', 'hadolint/hadolint')
function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" /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:output = []
" Matches patterns line the following:
"
" stdin:19: F: Pipe chain should start with a raw value.
let l:pattern = '\v^/dev/stdin:?(\d+)? (\S+) (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:lnum = 0
let l:colnum = 0
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if l:match[1] isnot# ''
let l:lnum = l:match[1] + 0
endif
if l:match[2] isnot# ''
let l:colnum = l:match[2] + 0
endif
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/'
if l:match[4] is# 'SC'
let l:domain = 'https://github.com/koalaman/shellcheck/wiki/'
endif
if l:match[5] isnot# ''
let l:code = l:match[4] . l:match[5]
let l:link = ' ( ' . l:domain . l:code . ' )'
let l:detail = l:code . l:link . "\n\n" . l:detail
else
let l:type = 'E'
endif
call add(l:output, {
\ 'lnum': l:lnum,
\ 'col': l:colnum,
\ 'type': l:type,
\ 'text': l:text,
\ 'detail': l:detail
\})
endfor
return l:output
endfunction
" This is a little different than the typical 'executable' callback. We want
" to afford the user the chance to say always use docker, never use docker,
" and use docker if the hadolint executable is not present on the system.
"
" In the case of neither docker nor hadolint executables being present, it
" really doesn't matter which we return -- either will have the effect of
" 'nope, can't use this linter!'.
function! ale_linters#dockerfile#hadolint#GetExecutable(buffer) abort
let l:use_docker = ale#Var(a:buffer, 'dockerfile_hadolint_use_docker')
" check for mandatory directives
if l:use_docker is# 'never'
return 'hadolint'
elseif l:use_docker is# 'always'
return 'docker'
if len(l:match) == 0
continue
endif
" if we reach here, we want to use 'hadolint' if present...
if executable('hadolint')
return 'hadolint'
let l:lnum = 0
if l:match[1] !=# ''
let l:lnum = l:match[1] + 0
endif
"... and 'docker' as a fallback.
return 'docker'
endfunction
let l:type = 'W'
let l:text = l:match[3]
function! ale_linters#dockerfile#hadolint#GetCommand(buffer) abort
let l:command = ale_linters#dockerfile#hadolint#GetExecutable(a:buffer)
if l:command is# 'docker'
return 'docker run --rm -i ' . ale#Var(a:buffer, 'dockerfile_hadolint_docker_image')
endif
return 'hadolint -'
endfunction
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:lnum,
\ 'vcol': 0,
\ 'col': 0,
\ 'type': l:type,
\ 'text': l:text,
\ 'nr': l:match[2],
\})
endfor
return l:output
endfunction
call ale#linter#Define('dockerfile', {
\ 'name': 'hadolint',
\ 'executable_callback': 'ale_linters#dockerfile#hadolint#GetExecutable',
\ 'command_callback': 'ale_linters#dockerfile#hadolint#GetCommand',
\ 'callback': 'ale_linters#dockerfile#hadolint#Handle',
\})
\ 'name': 'hadolint',
\ 'executable': 'hadolint',
\ 'command': 'hadolint -',
\ 'callback': 'ale_linters#dockerfile#hadolint#Handle' })

View File

@@ -1,37 +1,45 @@
" Author: hauleth - https://github.com/hauleth
function! ale_linters#elixir#credo#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" lib/filename.ex:19:7: F: Pipe chain should start with a raw value.
let l:pattern = '\v:(\d+):?(\d+)?: (.): (.+)$'
let l:output = []
" Matches patterns line the following:
"
" stdin:19: F: Pipe chain should start with a raw value.
let l:pattern = '\v^stdin:(\d+):?(\d+)?: (.): (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:type = l:match[3]
let l:text = l:match[4]
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if l:type is# 'C'
let l:type = 'E'
elseif l:type is# 'R'
let l:type = 'W'
endif
if len(l:match) == 0
continue
endif
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'type': l:type,
\ 'text': l:text,
\})
endfor
let l:type = l:match[3]
let l:text = l:match[4]
return l:output
if l:type ==# 'C'
let l:type = 'E'
elseif l:type ==# 'R'
let l:type = 'W'
endif
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:match[1] + 0,
\ 'vcol': 0,
\ 'col': l:match[2] + 0,
\ 'type': l:type,
\ 'text': l:text,
\ 'nr': -1,
\})
endfor
return l:output
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'credo',
\ 'executable': 'mix',
\ 'command': 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s',
\ 'callback': 'ale_linters#elixir#credo#Handle',
\})
\ 'name': 'credo',
\ 'executable': 'mix',
\ 'command': 'mix credo suggest --format=flycheck --read-from-stdin',
\ 'callback': 'ale_linters#elixir#credo#Handle' })

View File

@@ -1,34 +0,0 @@
" Author: Fran C. - https://github.com/franciscoj
" Description: Add dialyzer support for elixir through dialyxir
" https://github.com/jeremyjh/dialyxir
function! ale_linters#elixir#dialyxir#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" lib/filename.ex:19: Function fname/1 has no local return
let l:pattern = '\v(.+):(\d+): (.+)$'
let l:output = []
let l:type = 'W'
for l:match in ale#util#GetMatches(a:lines, l:pattern)
if bufname(a:buffer) == l:match[1]
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:match[2] + 0,
\ 'col': 0,
\ 'type': l:type,
\ 'text': l:match[3],
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'dialyxir',
\ 'executable': 'mix',
\ 'command': 'mix dialyzer',
\ 'callback': 'ale_linters#elixir#dialyxir#Handle',
\})

View File

@@ -1,38 +0,0 @@
" Author: archseer - https://github.com/archSeer
function! ale_linters#elixir#dogma#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" lib/filename.ex:19:7: F: Pipe chain should start with a raw value.
let l:pattern = '\v:(\d+):?(\d+)?: (.): (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:type = l:match[3]
let l:text = l:match[4]
if l:type is# 'C'
let l:type = 'E'
elseif l:type is# 'R'
let l:type = 'W'
endif
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'type': l:type,
\ 'text': l:text,
\})
endfor
return l:output
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'dogma',
\ 'executable': 'mix',
\ 'command': 'mix help dogma && mix dogma %s --format=flycheck',
\ 'lint_file': 1,
\ 'callback': 'ale_linters#elixir#dogma#Handle',
\})

View File

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

View File

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

View File

@@ -3,12 +3,7 @@
let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '')
function! ale_linters#erlang#erlc#GetCommand(buffer) abort
let l:output_file = tempname()
call ale#engine#ManageFile(a:buffer, l:output_file)
return 'erlc -o ' . ale#Escape(l:output_file)
\ . ' ' . ale#Var(a:buffer, 'erlang_erlc_options')
\ . ' %t'
return g:ale#util#stdin_wrapper . ' .erl erlc ' . g:ale_erlang_erlc_options
endfunction
function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
@@ -17,7 +12,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+): (Warning: )?(.+)$'
let l:pattern = '\v^([^:]+):(\d+): (Warning: )?(.+)$'
" parse_transforms are a special case. The error message does not indicate a location:
" error.erl: undefined parse transform 'some_parse_transform'
@@ -27,7 +22,7 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
let l:pattern_no_module_definition = '\v(no module definition)$'
let l:pattern_unused = '\v(.* is unused)$'
let l:is_hrl = fnamemodify(bufname(a:buffer), ':e') is# 'hrl'
let l:is_hrl = fnamemodify(bufname(a:buffer), ':e') ==# 'hrl'
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
@@ -48,9 +43,11 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': 0,
\ 'vcol': 0,
\ 'col': 0,
\ 'type': 'E',
\ 'text': l:match_parse_transform[0],
\ 'nr': -1,
\})
continue
@@ -76,12 +73,15 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
let l:type = 'E'
endif
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:line,
\ 'vcol': 0,
\ 'col': 0,
\ 'type': l:type,
\ 'text': l:text,
\ 'nr': -1,
\})
endfor

View File

@@ -1,53 +0,0 @@
" Author: Dmitri Vereshchagin <dmitri.vereshchagin@gmail.com>
" Description: SyntaxErl linter for Erlang files
call ale#Set('erlang_syntaxerl_executable', 'syntaxerl')
function! ale_linters#erlang#syntaxerl#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'erlang_syntaxerl_executable')
endfunction
function! ale_linters#erlang#syntaxerl#FeatureCheck(buffer) abort
return s:GetEscapedExecutable(a:buffer) . ' -h'
endfunction
function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output) abort
let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1
return s:GetEscapedExecutable(a:buffer) . (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': l:match[1] + 0,
\ 'text': l:match[3],
\ 'type': empty(l:match[2]) ? 'E' : 'W',
\})
endfor
return l:loclist
endfunction
function! s:GetEscapedExecutable(buffer) abort
return ale#Escape(ale_linters#erlang#syntaxerl#GetExecutable(a:buffer))
endfunction
call ale#linter#Define('erlang', {
\ 'name': 'syntaxerl',
\ 'executable_callback': 'ale_linters#erlang#syntaxerl#GetExecutable',
\ 'command_chain': [
\ {'callback': 'ale_linters#erlang#syntaxerl#FeatureCheck'},
\ {'callback': 'ale_linters#erlang#syntaxerl#GetCommand'},
\ ],
\ 'callback': 'ale_linters#erlang#syntaxerl#Handle',
\})

View File

@@ -1,25 +0,0 @@
" Author: Matthias Guenther - https://wikimatze.de, Eddie Lebow https://github.com/elebow
" Description: ERB from the Ruby standard library, for eruby/erb files
function! ale_linters#eruby#erb#GetCommand(buffer) abort
let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
if empty(l:rails_root)
return 'erb -P -T - -x %t | ruby -c'
endif
" 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(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c'
endfunction
call ale#linter#Define('eruby', {
\ 'name': 'erb',
\ 'aliases': ['erubylint'],
\ 'executable': 'erb',
\ 'output_stream': 'stderr',
\ 'command_callback': 'ale_linters#eruby#erb#GetCommand',
\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
\})

View File

@@ -1,35 +0,0 @@
" Author: Eddie Lebow https://github.com/elebow
" Description: eruby checker using `erubi`
function! ale_linters#eruby#erubi#CheckErubi(buffer) abort
return 'ruby -r erubi/capture_end -e ' . ale#Escape('""')
endfunction
function! ale_linters#eruby#erubi#GetCommand(buffer, check_erubi_output) abort
let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
if (!empty(a:check_erubi_output))
" The empty command in CheckErubi returns nothing if erubi runs and
" emits an error if erubi is not present
return ''
endif
if empty(l:rails_root)
return 'ruby -r erubi/capture_end -e ' . ale#Escape('puts Erubi::CaptureEndEngine.new($stdin.read).src') . '< %t | ruby -c'
endif
" Rails-flavored eRuby does not comply with the standard as understood by
" Erubi, 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 erubi/capture_end -e ' . ale#Escape('puts Erubi::CaptureEndEngine.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c'
endfunction
call ale#linter#Define('eruby', {
\ 'name': 'erubi',
\ 'executable': 'ruby',
\ 'command_chain': [
\ {'callback': 'ale_linters#eruby#erubi#CheckErubi'},
\ {'callback': 'ale_linters#eruby#erubi#GetCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
\})

View File

@@ -1,23 +0,0 @@
" Author: Jake Zimmerman <jake@zimmerman.io>, Eddie Lebow https://github.com/elebow
" Description: eruby checker using `erubis`, instead of `erb`
function! ale_linters#eruby#erubis#GetCommand(buffer) abort
let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
if empty(l:rails_root)
return 'erubis -x %t | ruby -c'
endif
" Rails-flavored eRuby does not comply with the standard as understood by
" Erubis, 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 erubis -e ' . ale#Escape('puts Erubis::Eruby.new($stdin.read.gsub(%{<%=},%{<%})).src') . '< %t | ruby -c'
endfunction
call ale#linter#Define('eruby', {
\ 'name': 'erubis',
\ 'executable': 'erubis',
\ 'output_stream': 'stderr',
\ 'command_callback': 'ale_linters#eruby#erubis#GetCommand',
\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
\})

View File

@@ -1,67 +0,0 @@
" Author: Niraj Thapaliya - https://github.com/nthapaliya
" Description: Lints fish files using fish -n
function! ale_linters#fish#fish#Handle(buffer, lines) abort
" Matches patterns such as:
"
" home/.config/fish/functions/foo.fish (line 1): Missing end to balance this function definition
" function foo
" ^
"
" OR, patterns such as:
"
" Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.
" /tmp/vLz620o/258/test.fish (line 2): if set -q SSH_CLIENT || set -q SSH_TTY
" ^
"
" fish -n can return errors in either format.
let l:pattern = '^\(.* (line \(\d\+\)): \)\(.*\)$'
let l:column_pattern = '^ *\^'
let l:output = []
let l:column_offset = 0
let l:last_line_with_message = ''
for l:line in a:lines
" Look for error lines first.
let l:match = matchlist(l:line, l:pattern)
if !empty(l:match)
if !empty(l:last_line_with_message)
let l:text = l:last_line_with_message
else
let l:text = l:match[3]
endif
let l:column_offset = len(l:match[1])
let l:last_line_with_message = ''
call add(l:output, {
\ 'col': 0,
\ 'lnum': str2nr(l:match[2]),
\ 'text': l:text,
\})
else
" Look for column markers like ' ^' second.
" The column index will be set according to how long the line is.
let l:column_match = matchstr(l:line, l:column_pattern)
if !empty(l:column_match) && !empty(l:output)
let l:output[-1].col = len(l:column_match) - l:column_offset
let l:last_line_with_message = ''
else
let l:last_line_with_message = l:line
let l:column_offset = 0
endif
endif
endfor
return l:output
endfunction
call ale#linter#Define('fish', {
\ 'name': 'fish',
\ 'output_stream': 'stderr',
\ 'executable': 'fish',
\ 'command': 'fish -n %t',
\ 'callback': 'ale_linters#fish#fish#Handle',
\})

View File

@@ -1,15 +1,6 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: gcc for Fortran files
" This option can be set to 0 to use -ffixed-form
if !exists('g:ale_fortran_gcc_use_free_form')
let g:ale_fortran_gcc_use_free_form = 1
endif
if !exists('g:ale_fortran_gcc_executable')
let g:ale_fortran_gcc_executable = 'gcc'
endif
" Set this option to change the GCC options for warnings for Fortran.
if !exists('g:ale_fortran_gcc_options')
let g:ale_fortran_gcc_options = '-Wall'
@@ -44,13 +35,15 @@ function! ale_linters#fortran#gcc#Handle(buffer, lines) abort
" Now we have the text, we can set it and add the error.
let l:last_loclist_obj.text = l:match[2]
let l:last_loclist_obj.type = l:match[1] is# 'Warning' ? 'W' : 'E'
let l:last_loclist_obj.type = l:match[1] ==# 'Warning' ? 'W' : 'E'
call add(l:output, l:last_loclist_obj)
else
let l:last_loclist_obj = {
\ 'bufnr': a:buffer,
\ 'lnum': l:match[1] + 0,
\ 'vcol': 0,
\ 'col': l:match[2] + 0,
\ 'nr': -1,
\}
" Start looking for the message and error type.
@@ -61,26 +54,12 @@ function! ale_linters#fortran#gcc#Handle(buffer, lines) abort
return l:output
endfunction
function! ale_linters#fortran#gcc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'fortran_gcc_executable')
endfunction
function! ale_linters#fortran#gcc#GetCommand(buffer) abort
let l:layout_option = ale#Var(a:buffer, 'fortran_gcc_use_free_form')
\ ? '-ffree-form'
\ : '-ffixed-form'
return ale_linters#fortran#gcc#GetExecutable(a:buffer)
\ . ' -S -x f95 -fsyntax-only '
\ . l:layout_option . ' '
\ . ale#Var(a:buffer, 'fortran_gcc_options') . ' '
\ . '-'
endfunction
call ale#linter#Define('fortran', {
\ 'name': 'gcc',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#fortran#gcc#GetExecutable',
\ 'command_callback': 'ale_linters#fortran#gcc#GetCommand',
\ 'executable': 'gcc',
\ 'command': 'gcc -S -x f95 -fsyntax-only -ffree-form '
\ . g:ale_fortran_gcc_options
\ . ' -',
\ 'callback': 'ale_linters#fortran#gcc#Handle',
\})

View File

@@ -1,9 +0,0 @@
" Author: Jansen Mitchell https://github.com/JansenMitchell
" Description: proselint for Fountain files
call ale#linter#Define('fountain', {
\ 'name': 'proselint',
\ 'executable': 'proselint',
\ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})

View File

@@ -1,41 +0,0 @@
" Author: RyanSquared <vandor2012@gmail.com>
" Description: `fusion-lint` linter for FusionScript files
let g:ale_fuse_fusionlint_executable =
\ get(g:, 'ale_fuse_fusionlint_executable', 'fusion-lint')
let g:ale_fuse_fusionlint_options =
\ get(g:, 'ale_fuse_fusionlint_options', '')
function! ale_linters#fuse#fusionlint#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'fuse_fusionlint_executable')
endfunction
function! ale_linters#fuse#fusionlint#GetCommand(buffer) abort
return ale#Escape(ale_linters#fuse#fusionlint#GetExecutable(a:buffer))
\ . ' ' . ale#Var(a:buffer, 'fuse_fusionlint_options')
\ . ' --filename %s -i'
endfunction
function! ale_linters#fuse#fusionlint#Handle(buffer, lines) abort
let l:pattern = '^.*:\(\d\+\):\(\d\+\): (\([WE]\)\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,
\ 'text': l:match[4],
\ 'type': l:match[3],
\})
endfor
return l:output
endfunction
call ale#linter#Define('fuse', {
\ 'name': 'fusionlint',
\ 'executable_callback': 'ale_linters#fuse#fusionlint#GetExecutable',
\ 'command_callback': 'ale_linters#fuse#fusionlint#GetCommand',
\ 'callback': 'ale_linters#fuse#fusionlint#Handle',
\})

View File

@@ -1,56 +0,0 @@
" Author: Nick Yamane <nick.diego@gmail.com>
" Description: gitlint for git commit message files
let g:ale_gitcommit_gitlint_executable =
\ get(g:, 'ale_gitcommit_gitlint_executable', 'gitlint')
let g:ale_gitcommit_gitlint_options = get(g:, 'ale_gitcommit_gitlint_options', '')
let g:ale_gitcommit_gitlint_use_global = get(g:, 'ale_gitcommit_gitlint_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#gitcommit#gitlint#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'gitcommit_gitlint', ['gitlint'])
endfunction
function! ale_linters#gitcommit#gitlint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'gitcommit_gitlint_options')
let l:executable = ale_linters#gitcommit#gitlint#GetExecutable(a:buffer)
return ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' lint'
endfunction
function! ale_linters#gitcommit#gitlint#Handle(buffer, lines) abort
" Matches patterns line the following:
let l:pattern = '\v^(\d+): (\w+) (.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:code = l:match[2]
if l:code is# 'T2' && !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
continue
endif
let l:item = {
\ 'lnum': l:match[1] + 0,
\ 'text': l:match[3],
\ 'code': l:code,
\ 'type': 'E',
\}
call add(l:output, l:item)
endfor
return l:output
endfunction
call ale#linter#Define('gitcommit', {
\ 'name': 'gitlint',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#gitcommit#gitlint#GetExecutable',
\ 'command_callback': 'ale_linters#gitcommit#gitlint#GetCommand',
\ 'callback': 'ale_linters#gitcommit#gitlint#Handle',
\})

View File

@@ -1,46 +0,0 @@
" Author: Sven-Hendrik Haase <svenstaro@gmail.com>
" Description: glslang-based linter for glsl files
"
" TODO: Once https://github.com/KhronosGroup/glslang/pull/1047 is accepted,
" we can use stdin.
let g:ale_glsl_glslang_executable =
\ get(g:, 'ale_glsl_glslang_executable', 'glslangValidator')
let g:ale_glsl_glslang_options = get(g:, 'ale_glsl_glslang_options', '')
function! ale_linters#glsl#glslang#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'glsl_glslang_executable')
endfunction
function! ale_linters#glsl#glslang#GetCommand(buffer) abort
return ale_linters#glsl#glslang#GetExecutable(a:buffer)
\ . ' ' . ale#Var(a:buffer, 'glsl_glslang_options')
\ . ' ' . '-C %t'
endfunction
function! ale_linters#glsl#glslang#Handle(buffer, lines) abort
" Matches patterns like the following:
"
" ERROR: 0:5: 'foo' : undeclared identifier
let l:pattern = '^\(.\+\): \(\d\+\):\(\d\+\): \(.\+\)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': str2nr(l:match[3]),
\ 'col': str2nr(l:match[2]),
\ 'text': l:match[4],
\ 'type': l:match[1] is# 'ERROR' ? 'E' : 'W',
\})
endfor
return l:output
endfunction
call ale#linter#Define('glsl', {
\ 'name': 'glslang',
\ 'executable_callback': 'ale_linters#glsl#glslang#GetExecutable',
\ 'command_callback': 'ale_linters#glsl#glslang#GetCommand',
\ 'callback': 'ale_linters#glsl#glslang#Handle',
\})

View File

@@ -1,34 +0,0 @@
" Author: Sven-Hendrik Haase <svenstaro@gmail.com>
" Description: A language server for glsl
call ale#Set('glsl_glslls_executable', 'glslls')
call ale#Set('glsl_glslls_logfile', '')
function! ale_linters#glsl#glslls#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'glsl_glslls_executable')
endfunction
function! ale_linters#glsl#glslls#GetCommand(buffer) abort
let l:executable = ale_linters#glsl#glslls#GetExecutable(a:buffer)
let l:logfile = ale#Var(a:buffer, 'glsl_glslls_logfile')
let l:logfile_args = ''
if l:logfile isnot# ''
let l:logfile_args = ' --verbose -l ' . l:logfile
endif
return ale#Escape(l:executable) . l:logfile_args . ' --stdin'
endfunction
function! ale_linters#glsl#glslls#GetProjectRoot(buffer) abort
let l:project_root = ale#c#FindProjectRoot(a:buffer)
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h:h') : ''
endfunction
call ale#linter#Define('glsl', {
\ 'name': 'glslls',
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#glsl#glslls#GetExecutable',
\ 'command_callback': 'ale_linters#glsl#glslls#GetCommand',
\ 'language': 'glsl',
\ 'project_root_callback': 'ale_linters#glsl#glslls#GetProjectRoot',
\})

View File

@@ -1,72 +1,204 @@
" Author: Joshua Rubin <joshua@rubixconsulting.com>, Ben Reedy <https://github.com/breed808>,
" Jeff Willette <jrwillette88@gmail.com>
" Author: Joshua Rubin <joshua@rubixconsulting.com>
" Description: go build for Go files
" inspired by work from dzhou121 <dzhou121@gmail.com>
call ale#Set('go_gobuild_options', '')
function! ale_linters#go#gobuild#ResetEnv() abort
unlet! s:go_env
endfunction
function! ale_linters#go#gobuild#GoEnv(buffer) abort
if exists('s:go_env')
return ''
if exists('s:go_env')
return ''
endif
return 'go env GOPATH GOROOT'
endfunction
let s:SplitChar = has('unix') ? ':' : ':'
" get a list of all source directories from $GOPATH and $GOROOT
function! s:SrcDirs() abort
let l:paths = split(s:go_env.GOPATH, s:SplitChar)
call add(l:paths, s:go_env.GOROOT)
return l:paths
endfunction
" figure out from a directory like `/home/user/go/src/some/package` that the
" import for that path is simply `some/package`
function! s:PackageImportPath(buffer) abort
let l:bufname = resolve(bufname(a:buffer))
let l:pkgdir = fnamemodify(l:bufname, ':p:h')
for l:path in s:SrcDirs()
let l:path = l:path . '/src/'
if stridx(l:pkgdir, l:path) == 0
return l:pkgdir[strlen(l:path):]
endif
endfor
return ''
endfunction
" get the package info data structure using `go list`
function! ale_linters#go#gobuild#GoList(buffer, goenv_output) abort
if !empty(a:goenv_output)
let s:go_env = {
\ 'GOPATH': a:goenv_output[0],
\ 'GOROOT': a:goenv_output[1],
\}
endif
return 'go list -json ' . shellescape(s:PackageImportPath(a:buffer))
endfunction
let s:filekeys = [
\ 'GoFiles',
\ 'CgoFiles',
\ 'CFiles',
\ 'CXXFiles',
\ 'MFiles',
\ 'HFiles',
\ 'FFiles',
\ 'SFiles',
\ 'SwigFiles',
\ 'SwigCXXFiles',
\ 'SysoFiles',
\ 'TestGoFiles',
\ 'XTestGoFiles',
\]
" get the go and test go files from the package
" will return empty list if the package has any cgo or other invalid files
function! s:PkgFiles(pkginfo) abort
let l:files = []
for l:key in s:filekeys
if has_key(a:pkginfo, l:key)
call extend(l:files, a:pkginfo[l:key])
endif
endfor
" resolve the path of the file relative to the window directory
return map(l:files, 'shellescape(fnamemodify(resolve(a:pkginfo.Dir . ''/'' . v:val), '':p''))')
endfunction
function! ale_linters#go#gobuild#CopyFiles(buffer, golist_output) abort
let l:tempdir = tempname()
let l:temppkgdir = l:tempdir . '/src/' . s:PackageImportPath(a:buffer)
call mkdir(l:temppkgdir, 'p', 0700)
if empty(a:golist_output)
return 'echo ' . shellescape(l:tempdir)
endif
" parse the output
let l:pkginfo = json_decode(join(a:golist_output, "\n"))
" get all files for the package
let l:files = s:PkgFiles(l:pkginfo)
" copy the files to a temp directory with $GOPATH structure
return 'cp ' . join(l:files, ' ') . ' ' . shellescape(l:temppkgdir) . ' && echo ' . shellescape(l:tempdir)
endfunction
function! ale_linters#go#gobuild#GetCommand(buffer, copy_output) abort
let l:tempdir = a:copy_output[0]
let l:importpath = s:PackageImportPath(a:buffer)
" write the a:buffer and any modified buffers from the package to the tempdir
for l:bufnum in range(1, bufnr('$'))
" ignore unloaded buffers (can't be a:buffer or a modified buffer)
if !bufloaded(l:bufnum)
continue
endif
return 'go env GOPATH GOROOT'
endfunction
function! ale_linters#go#gobuild#GetCommand(buffer, goenv_output) abort
let l:options = ale#Var(a:buffer, 'go_gobuild_options')
if !exists('s:go_env')
let s:go_env = {
\ 'GOPATH': a:goenv_output[0],
\ 'GOROOT': a:goenv_output[1],
\}
" ignore non-Go buffers
if getbufvar(l:bufnum, '&ft') !=# 'go'
continue
endif
let l:gopath_env_command = has('win32')
\ ? 'set GOPATH=' . ale#Escape(s:go_env.GOPATH) . ' && '
\ : 'GOPATH=' . ale#Escape(s:go_env.GOPATH) . ' '
" only consider buffers other than a:buffer if they have the same import
" path as a:buffer and are modified
if l:bufnum != a:buffer
if s:PackageImportPath(l:bufnum) !=# l:importpath
continue
endif
" Run go test in local directory with relative path
return l:gopath_env_command
\ . ale#path#BufferCdString(a:buffer)
\ . 'go test'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -c -o /dev/null ./'
if !getbufvar(l:bufnum, '&mod')
continue
endif
endif
call writefile(getbufline(l:bufnum, 1, '$'), l:tempdir . '/src/' . s:PkgFile(l:bufnum))
endfor
let l:gopaths = [ l:tempdir ]
call extend(l:gopaths, split(s:go_env.GOPATH, s:SplitChar))
return 'GOPATH=' . shellescape(join(l:gopaths, s:SplitChar)) . ' go test -c -o /dev/null ' . shellescape(l:importpath)
endfunction
function! ale_linters#go#gobuild#GetMatches(lines) abort
" Matches patterns like the following:
"
" file.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args
" file.go:53:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
" file.go:5:2: expected declaration, found 'STRING' "log"
function! s:PkgFile(buffer) abort
let l:bufname = resolve(bufname(a:buffer))
let l:importpath = s:PackageImportPath(a:buffer)
let l:fname = fnamemodify(l:bufname, ':t')
" go test returns relative paths so use tail of filename as part of pattern matcher
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? (.+)$'
return ale#util#GetMatches(a:lines, l:pattern)
return l:importpath . '/' . l:fname
endfunction
function! s:FindBuffer(file) abort
for l:buffer in range(1, bufnr('$'))
if !buflisted(l:buffer)
continue
endif
let l:pkgfile = s:PkgFile(l:buffer)
if a:file =~ '/' . l:pkgfile . '$'
return l:buffer
endif
endfor
return -1
endfunction
let s:path_pattern = '[a-zA-Z]\?\\\?:\?[[:alnum:]/\.\-_]\+'
let s:handler_pattern = '^\(' . s:path_pattern . '\):\(\d\+\):\?\(\d\+\)\?: \(.\+\)$'
let s:multibuffer = 0
function! ale_linters#go#gobuild#Handler(buffer, lines) abort
let l:dir = expand('#' . a:buffer . ':p:h')
let l:output = []
let l:output = []
for l:match in ale_linters#go#gobuild#GetMatches(a:lines)
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4],
\ 'type': 'E',
\})
endfor
for l:line in a:lines
let l:match = matchlist(l:line, s:handler_pattern)
return l:output
if len(l:match) == 0
continue
endif
let l:buffer = s:FindBuffer(l:match[1])
if l:buffer == -1
continue
endif
if !s:multibuffer && l:buffer != a:buffer
" strip lines from other buffers
continue
endif
call add(l:output, {
\ 'bufnr': l:buffer,
\ 'lnum': l:match[2] + 0,
\ 'vcol': 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4],
\ 'type': 'E',
\ 'nr': -1,
\})
endfor
return l:output
endfunction
call ale#linter#Define('go', {
@@ -74,8 +206,9 @@ call ale#linter#Define('go', {
\ 'executable': 'go',
\ 'command_chain': [
\ {'callback': 'ale_linters#go#gobuild#GoEnv', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#go#gobuild#GoList', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#go#gobuild#CopyFiles', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#go#gobuild#GetCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale_linters#go#gobuild#Handler',
\ 'lint_file': 1,
\})

View File

@@ -5,6 +5,6 @@ call ale#linter#Define('go', {
\ 'name': 'gofmt',
\ 'output_stream': 'stderr',
\ 'executable': 'gofmt',
\ 'command': 'gofmt -e %t',
\ 'callback': 'ale#handlers#unix#HandleAsError',
\ 'command': g:ale#util#stdin_wrapper . ' .go gofmt -e',
\ 'callback': 'ale#handlers#HandleUnixFormatAsError',
\})

View File

@@ -3,8 +3,7 @@
call ale#linter#Define('go', {
\ 'name': 'golint',
\ 'output_stream': 'both',
\ 'executable': 'golint',
\ 'command': 'golint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\ 'command': g:ale#util#stdin_wrapper . ' .go golint',
\ 'callback': 'ale#handlers#HandleUnixFormatAsWarning',
\})

View File

@@ -1,62 +0,0 @@
" Author: Ben Reedy <https://github.com/breed808>, Jeff Willette <jrwillette88@gmail.com>
" Description: Adds support for the gometalinter suite for Go files
call ale#Set('go_gometalinter_options', '')
call ale#Set('go_gometalinter_executable', 'gometalinter')
call ale#Set('go_gometalinter_lint_package', 0)
function! ale_linters#go#gometalinter#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'go_gometalinter_executable')
endfunction
function! ale_linters#go#gometalinter#GetCommand(buffer) abort
let l:executable = ale_linters#go#gometalinter#GetExecutable(a:buffer)
let l:filename = expand('#' . a:buffer . ':t')
let l:options = ale#Var(a:buffer, 'go_gometalinter_options')
let l:lint_package = ale#Var(a:buffer, 'go_gometalinter_lint_package')
" BufferCdString is used so that we can be sure the paths output from gometalinter can
" be calculated to absolute paths in the Handler
if l:lint_package
return ale#path#BufferCdString(a:buffer)
\ . ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif
return ale#path#BufferCdString(a:buffer)
\ . ale#Escape(l:executable)
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename))
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endfunction
function! ale_linters#go#gometalinter#GetMatches(lines) abort
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:?:?(warning|error):?\s\*?(.+)$'
return ale#util#GetMatches(a:lines, l:pattern)
endfunction
function! ale_linters#go#gometalinter#Handler(buffer, lines) abort
let l:dir = expand('#' . a:buffer . ':p:h')
let l:output = []
for l:match in ale_linters#go#gometalinter#GetMatches(a:lines)
" l:match[1] will already be an absolute path, output from gometalinter
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'type': tolower(l:match[4]) is# 'warning' ? 'W' : 'E',
\ 'text': l:match[5],
\})
endfor
return l:output
endfunction
call ale#linter#Define('go', {
\ 'name': 'gometalinter',
\ 'executable_callback': 'ale_linters#go#gometalinter#GetExecutable',
\ 'command_callback': 'ale_linters#go#gometalinter#GetCommand',
\ 'callback': 'ale_linters#go#gometalinter#Handler',
\ 'lint_file': 1,
\})

View File

@@ -1,15 +0,0 @@
" Author: Ben Reedy <https://github.com/breed808>
" Description: gosimple for Go files
function! ale_linters#go#gosimple#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer) . ' gosimple .'
endfunction
call ale#linter#Define('go', {
\ 'name': 'gosimple',
\ 'executable': 'gosimple',
\ 'command_callback': 'ale_linters#go#gosimple#GetCommand',
\ 'callback': 'ale#handlers#go#Handler',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})

View File

@@ -1,20 +0,0 @@
" Author: Jelte Fennema <github-public@jeltef.nl>
" Description: gotype for Go files
function! ale_linters#go#gotype#GetCommand(buffer) abort
if expand('#' . a:buffer . ':p') =~# '_test\.go$'
return
endif
return ale#path#BufferCdString(a:buffer) . ' gotype .'
endfunction
call ale#linter#Define('go', {
\ 'name': 'gotype',
\ 'output_stream': 'stderr',
\ 'executable': 'gotype',
\ 'command_callback': 'ale_linters#go#gotype#GetCommand',
\ 'callback': 'ale#handlers#go#Handler',
\ 'lint_file': 1,
\})

View File

@@ -1,18 +1,10 @@
" Author: neersighted <bjorn@neersighted.com>
" Description: go vet for Go files
"
" Author: John Eikenberry <jae@zhar.net>
" Description: updated to work with go1.10
function! ale_linters#go#govet#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer) . ' go vet .'
endfunction
call ale#linter#Define('go', {
\ 'name': 'go vet',
\ 'output_stream': 'stderr',
\ 'executable': 'go',
\ 'command_callback': 'ale_linters#go#govet#GetCommand',
\ 'callback': 'ale#handlers#go#Handler',
\ 'lint_file': 1,
\ 'command': g:ale#util#stdin_wrapper . ' .go go vet',
\ 'callback': 'ale#handlers#HandleUnixFormatAsError',
\})

View File

@@ -1,33 +0,0 @@
" Author: Ben Reedy <https://github.com/breed808>
" Description: staticcheck for Go files
call ale#Set('go_staticcheck_options', '')
call ale#Set('go_staticcheck_lint_package', 0)
function! ale_linters#go#staticcheck#GetCommand(buffer) abort
let l:filename = expand('#' . a:buffer . ':t')
let l:options = ale#Var(a:buffer, 'go_staticcheck_options')
let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package')
" BufferCdString is used so that we can be sure the paths output from
" staticcheck can be calculated to absolute paths in the Handler
if l:lint_package
return ale#path#BufferCdString(a:buffer)
\ . 'staticcheck'
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif
return ale#path#BufferCdString(a:buffer)
\ . 'staticcheck'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' ' . ale#Escape(l:filename)
endfunction
call ale#linter#Define('go', {
\ 'name': 'staticcheck',
\ 'executable': 'staticcheck',
\ 'command_callback': 'ale_linters#go#staticcheck#GetCommand',
\ 'callback': 'ale#handlers#go#Handler',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})

View File

@@ -1,9 +0,0 @@
" Author: Benjie Gillam <code@benjiegillam.com>
" Description: eslint for GraphQL files
call ale#linter#Define('graphql', {
\ 'name': 'eslint',
\ 'executable_callback': 'ale#handlers#eslint#GetExecutable',
\ 'command_callback': 'ale#handlers#eslint#GetCommand',
\ 'callback': 'ale#handlers#eslint#Handle',
\})

View File

@@ -1,9 +0,0 @@
" Author: Michiel Westerbeek <happylinks@gmail.com>
" Description: Linter for GraphQL Schemas
call ale#linter#Define('graphql', {
\ 'name': 'gqlint',
\ 'executable': 'gqlint',
\ 'command': 'gqlint --reporter=simple %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})

View File

@@ -1,51 +0,0 @@
" Author: Patrick Lewis - https://github.com/patricklewis, thenoseman - https://github.com/thenoseman
" Description: haml-lint for Haml files
function! ale_linters#haml#hamllint#GetCommand(buffer) abort
let l:prefix = ''
let l:rubocop_config_file_path = ale#path#FindNearestFile(a:buffer, '.rubocop.yml')
let l:hamllint_config_file_path = ale#path#FindNearestFile(a:buffer, '.haml-lint.yml')
" Set HAML_LINT_RUBOCOP_CONF variable as it is needed for haml-lint to
" pick up the rubocop config.
"
" See https://github.com/brigade/haml-lint/blob/master/lib/haml_lint/linter/rubocop.rb#L89
" HamlLint::Linter::RuboCop#rubocop_flags
if !empty(l:rubocop_config_file_path)
if ale#Has('win32')
let l:prefix = 'set HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path) . ' &&'
else
let l:prefix = 'HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path)
endif
endif
return (!empty(l:prefix) ? l:prefix . ' ' : '')
\ . 'haml-lint'
\ . (!empty(l:hamllint_config_file_path) ? ' --config ' . ale#Escape(l:hamllint_config_file_path) : '')
\ . ' %t'
endfunction
function! ale_linters#haml#hamllint#Handle(buffer, lines) abort
" Matches patterns like the following:
" <path>:51 [W] RuboCop: Use the new Ruby 1.9 hash syntax.
let l:pattern = '\v^.*:(\d+) \[([EW])\] (.+)$'
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],
\ 'text': l:match[3]
\})
endfor
return l:output
endfunction
call ale#linter#Define('haml', {
\ 'name': 'hamllint',
\ 'executable': 'haml-lint',
\ 'command_callback': 'ale_linters#haml#hamllint#GetCommand',
\ 'callback': 'ale_linters#haml#hamllint#Handle'
\})

View File

@@ -1,48 +0,0 @@
" Author: Adrian Zalewski <aazalewski@hotmail.com>
" Description: Ember-template-lint for checking Handlebars files
call ale#Set('handlebars_embertemplatelint_executable', 'ember-template-lint')
call ale#Set('handlebars_embertemplatelint_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#handlebars#embertemplatelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'handlebars_embertemplatelint', [
\ 'node_modules/.bin/ember-template-lint',
\])
endfunction
function! ale_linters#handlebars#embertemplatelint#GetCommand(buffer) abort
return ale_linters#handlebars#embertemplatelint#GetExecutable(a:buffer)
\ . ' --json %t'
endfunction
function! ale_linters#handlebars#embertemplatelint#Handle(buffer, lines) abort
let l:output = []
let l:json = ale#util#FuzzyJSONDecode(a:lines, {})
for l:error in get(values(l:json), 0, [])
if has_key(l:error, 'fatal')
call add(l:output, {
\ 'lnum': get(l:error, 'line', 1),
\ 'col': get(l:error, 'column', 1),
\ 'text': l:error.message,
\ 'type': l:error.severity == 1 ? 'W' : 'E',
\})
else
call add(l:output, {
\ 'lnum': l:error.line,
\ 'col': l:error.column,
\ 'text': l:error.rule . ': ' . l:error.message,
\ 'type': l:error.severity == 1 ? 'W' : 'E',
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('handlebars', {
\ 'name': 'ember-template-lint',
\ 'executable_callback': 'ale_linters#handlebars#embertemplatelint#GetExecutable',
\ 'command_callback': 'ale_linters#handlebars#embertemplatelint#GetCommand',
\ 'callback': 'ale_linters#handlebars#embertemplatelint#Handle',
\})

View File

@@ -1,16 +0,0 @@
" Author: wizzup <wizzup@gmail.com>
" Description: ghc-mod for Haskell files
call ale#linter#Define('haskell', {
\ 'name': 'ghc-mod',
\ 'executable': 'ghc-mod',
\ 'command': 'ghc-mod --map-file %s=%t check %s',
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\})
call ale#linter#Define('haskell', {
\ 'name': 'stack-ghc-mod',
\ 'executable': 'stack',
\ 'command': 'stack exec ghc-mod -- --map-file %s=%t check %s',
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\})

View File

@@ -1,18 +1,73 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: ghc for Haskell files
call ale#Set('haskell_ghc_options', '-fno-code -v0')
if exists('g:loaded_ale_linters_haskell_ghc')
finish
endif
function! ale_linters#haskell#ghc#GetCommand(buffer) abort
return 'ghc '
\ . ale#Var(a:buffer, 'haskell_ghc_options')
\ . ' %t'
let g:loaded_ale_linters_haskell_ghc = 1
function! ale_linters#haskell#ghc#Handle(buffer, lines) abort
" Look for lines like the following.
"
" /dev/stdin:28:26: Not in scope: `>>>>>'
let l:pattern = '^[^:]\+:\(\d\+\):\(\d\+\): \(.\+\)$'
let l:output = []
" For some reason the output coming out of the GHC through the wrapper
" script breaks the lines up in strange ways. So we have to join some
" lines back together again.
let l:corrected_lines = []
for l:line in a:lines
if len(matchlist(l:line, l:pattern)) > 0
call add(l:corrected_lines, l:line)
if l:line !~# ': error:$'
call add(l:corrected_lines, '')
endif
elseif l:line ==# ''
call add(l:corrected_lines, l:line)
else
if len(l:corrected_lines) > 0
let l:line = substitute(l:line, '\v\s+', ' ', '')
let l:corrected_lines[-1] .= l:line
endif
endif
endfor
for l:line in l:corrected_lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:match[1] + 0,
\ 'vcol': 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'type': 'E',
\ 'nr': -1,
\})
endfor
return l:output
endfunction
call ale#linter#Define('haskell', {
\ 'name': 'ghc',
\ 'output_stream': 'stderr',
\ 'executable': 'ghc',
\ 'command_callback': 'ale_linters#haskell#ghc#GetCommand',
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\ 'command': g:ale#util#stdin_wrapper . ' .hs ghc -fno-code -v0',
\ 'callback': 'ale_linters#haskell#ghc#Handle',
\})
call ale#linter#Define('haskell', {
\ 'name': 'stack-ghc',
\ 'output_stream': 'stderr',
\ 'executable': 'stack',
\ 'command': g:ale#util#stdin_wrapper . ' .hs stack ghc -- -fno-code -v0',
\ 'callback': 'ale_linters#haskell#ghc#Handle',
\})

View File

@@ -1,22 +0,0 @@
" Author: rob-b, Takano Akio <tak@anoak.io>
" Description: hdevtools for Haskell files
call ale#Set('haskell_hdevtools_executable', 'hdevtools')
call ale#Set('haskell_hdevtools_options', get(g:, 'hdevtools_options', '-g -Wall'))
function! ale_linters#haskell#hdevtools#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'haskell_hdevtools_executable')
endfunction
function! ale_linters#haskell#hdevtools#GetCommand(buffer) abort
return ale#Escape(ale_linters#haskell#hdevtools#GetExecutable(a:buffer))
\ . ' check ' . ale#Var(a:buffer, 'haskell_hdevtools_options')
\ . ' -p %s %t'
endfunction
call ale#linter#Define('haskell', {
\ 'name': 'hdevtools',
\ 'executable_callback': 'ale_linters#haskell#hdevtools#GetExecutable',
\ 'command_callback': 'ale_linters#haskell#hdevtools#GetCommand',
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\})

View File

@@ -2,24 +2,19 @@
" Description: hlint for Haskell files
function! ale_linters#haskell#hlint#Handle(buffer, lines) abort
let l:errors = json_decode(join(a:lines, ''))
let l:output = []
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
if l:error.severity is# 'Error'
let l:type = 'E'
elseif l:error.severity is# 'Suggestion'
let l:type = 'I'
else
let l:type = 'W'
endif
for l:error in l:errors
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'lnum': str2nr(l:error.startLine),
\ 'col': str2nr(l:error.startColumn),
\ 'end_lnum': str2nr(l:error.endLine),
\ 'end_col': str2nr(l:error.endColumn),
\ 'bufnr': a:buffer,
\ 'lnum': l:error.startLine + 0,
\ 'vcol': 0,
\ 'col': l:error.startColumn + 0,
\ 'text': l:error.severity . ': ' . l:error.hint . '. Found: ' . l:error.from . ' Why not: ' . l:error.to,
\ 'type': l:type,
\ 'type': l:error.severity ==# 'Error' ? 'E' : 'W',
\})
endfor

View File

@@ -1,22 +0,0 @@
" Author: Jake Zimmerman <jake@zimmerman.io>
" Description: Like stack-ghc, but for entire projects
"
" Note: Ideally, this would *only* typecheck. Right now, it also does codegen.
" See <https://github.com/commercialhaskell/stack/issues/977>.
call ale#Set('haskell_stack_build_options', '--fast')
function! ale_linters#haskell#stack_build#GetCommand(buffer) abort
let l:flags = ale#Var(a:buffer, 'haskell_stack_build_options')
return 'stack build ' . l:flags
endfunction
call ale#linter#Define('haskell', {
\ 'name': 'stack-build',
\ 'output_stream': 'stderr',
\ 'executable': 'stack',
\ 'command_callback': 'ale_linters#haskell#stack_build#GetCommand',
\ 'lint_file': 1,
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\})

View File

@@ -1,10 +0,0 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: ghc for Haskell files, using Stack
call ale#linter#Define('haskell', {
\ 'name': 'stack-ghc',
\ 'output_stream': 'stderr',
\ 'executable': 'stack',
\ 'command': 'stack ghc -- -fno-code -v0 %t',
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
\})

View File

@@ -1,11 +0,0 @@
" Author: Johannes Wienke <languitar@semipol.de>
" Description: alex for help files
call ale#linter#Define('help', {
\ 'name': 'alex',
\ 'executable': 'alex',
\ 'command': 'alex %s -t',
\ 'output_stream': 'stderr',
\ 'callback': 'ale#handlers#alex#Handle',
\ 'lint_file': 1,
\})

View File

@@ -1,9 +0,0 @@
" Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for Vim help files
call ale#linter#Define('help', {
\ 'name': 'proselint',
\ 'executable': 'proselint',
\ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})

View File

@@ -1,9 +0,0 @@
" Author: Sumner Evans <sumner.evans98@gmail.com>
" Description: write-good for vim Help files
call ale#linter#Define('help', {
\ 'name': 'write-good',
\ 'executable_callback': 'ale#handlers#writegood#GetExecutable',
\ 'command_callback': 'ale#handlers#writegood#GetCommand',
\ 'callback': 'ale#handlers#writegood#Handle',
\})

View File

@@ -1,11 +0,0 @@
" Author: Johannes Wienke <languitar@semipol.de>
" Description: alex for HTML files
call ale#linter#Define('html', {
\ 'name': 'alex',
\ 'executable': 'alex',
\ 'command': 'alex %s -t',
\ 'output_stream': 'stderr',
\ 'callback': 'ale#handlers#alex#Handle',
\ 'lint_file': 1,
\})

View File

@@ -1,38 +1,36 @@
" Author: KabbAmine <amine.kabb@gmail.com>, deathmaz <00maz1987@gmail.com>, diartyz <diartyz@gmail.com>
" Description: HTMLHint for checking html files
call ale#Set('html_htmlhint_options', '')
call ale#Set('html_htmlhint_executable', 'htmlhint')
call ale#Set('html_htmlhint_use_global', get(g:, 'ale_use_global_executables', 0))
" CLI options
let g:ale_html_htmlhint_options = get(g:, 'ale_html_htmlhint_options', '--format=unix')
let g:ale_html_htmlhint_executable =
\ get(g:, 'ale_html_htmlhint_executable', 'htmlhint')
let g:ale_html_htmlhint_use_global =
\ get(g:, 'ale_html_htmlhint_use_global', 0)
function! ale_linters#html#htmlhint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'html_htmlhint', [
if g:ale_html_htmlhint_use_global
return g:ale_html_htmlhint_executable
endif
return ale#util#ResolveLocalPath(
\ a:buffer,
\ 'node_modules/.bin/htmlhint',
\])
\ g:ale_html_htmlhint_executable
\)
endfunction
function! ale_linters#html#htmlhint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'html_htmlhint_options')
let l:config = l:options !~# '--config'
\ ? ale#path#FindNearestFile(a:buffer, '.htmlhintrc')
\ : ''
if !empty(l:config)
let l:options .= ' --config ' . ale#Escape(l:config)
endif
if !empty(l:options)
let l:options = substitute(l:options, '--format=unix', '', '')
endif
return ale#Escape(ale_linters#html#htmlhint#GetExecutable(a:buffer))
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --format=unix %t'
return g:ale#util#stdin_wrapper . ' .html '
\ . ale_linters#html#htmlhint#GetExecutable(a:buffer)
\ . ' ' . g:ale_html_htmlhint_options
endfunction
call ale#linter#Define('html', {
\ 'name': 'htmlhint',
\ 'executable_callback': 'ale_linters#html#htmlhint#GetExecutable',
\ 'command_callback': 'ale_linters#html#htmlhint#GetCommand',
\ 'callback': 'ale#handlers#unix#HandleAsError',
\ 'callback': 'ale#handlers#HandleUnixFormatAsError',
\})

View File

@@ -1,9 +0,0 @@
" Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for HTML files
call ale#linter#Define('html', {
\ 'name': 'proselint',
\ 'executable': 'proselint',
\ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})

View File

@@ -1,8 +1,9 @@
" Author: KabbAmine <amine.kabb@gmail.com>
" Description: This file adds support for checking HTML code with tidy.
" CLI options
let g:ale_html_tidy_executable = get(g:, 'ale_html_tidy_executable', 'tidy')
let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', '-q -e -language en')
let g:ale_html_tidy_args = get(g:, 'ale_html_tidy_args', '-q -e -language en')
function! ale_linters#html#tidy#GetCommand(buffer) abort
" Specify file encoding in options
@@ -22,23 +23,11 @@ function! ale_linters#html#tidy#GetCommand(buffer) abort
\ 'utf-8': '-utf8',
\ }, &fileencoding, '-utf8')
" On macOS, old tidy (released on 31 Oct 2006) is installed. It does not
" consider HTML5 so we should avoid it.
let l:executable = ale#Var(a:buffer, 'html_tidy_executable')
if has('mac') && l:executable is# 'tidy' && exists('*exepath')
\ && exepath(l:executable) is# '/usr/bin/tidy'
return ''
endif
return printf('%s %s %s -',
\ l:executable,
\ ale#Var(a:buffer, 'html_tidy_options'),
\ g:ale_html_tidy_executable,
\ g:ale_html_tidy_args,
\ l:file_encoding
\)
endfunction
function! ale_linters#html#tidy#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'html_tidy_executable')
\ )
endfunction
function! ale_linters#html#tidy#Handle(buffer, lines) abort
@@ -48,17 +37,27 @@ function! ale_linters#html#tidy#Handle(buffer, lines) abort
let l:pattern = '^line \(\d\+\) column \(\d\+\) - \(Warning\|Error\): \(.\+\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
let l:line = l:match[1] + 0
let l:col = l:match[2] + 0
let l:type = l:match[3] is# 'Error' ? 'E' : 'W'
let l:type = l:match[3] ==# 'Error' ? 'E' : 'W'
let l:text = l:match[4]
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:line,
\ 'vcol': 0,
\ 'col': l:col,
\ 'text': l:text,
\ 'type': l:type,
\ 'nr': -1,
\})
endfor
@@ -67,7 +66,7 @@ endfunction
call ale#linter#Define('html', {
\ 'name': 'tidy',
\ 'executable_callback': 'ale_linters#html#tidy#GetExecutable',
\ 'executable': g:ale_html_tidy_executable,
\ 'output_stream': 'stderr',
\ 'command_callback': 'ale_linters#html#tidy#GetCommand',
\ 'callback': 'ale_linters#html#tidy#Handle',

View File

@@ -1,9 +0,0 @@
" Author: Sumner Evans <sumner.evans98@gmail.com>
" Description: write-good for nroff files
call ale#linter#Define('html', {
\ 'name': 'write-good',
\ 'executable_callback': 'ale#handlers#writegood#GetExecutable',
\ 'command_callback': 'ale#handlers#writegood#GetCommand',
\ 'callback': 'ale#handlers#writegood#Handle',
\})

View File

@@ -1,87 +0,0 @@
" Author: Scott Bonds <scott@ggr.com>
" Description: default Idris compiler
call ale#Set('idris_idris_executable', 'idris')
call ale#Set('idris_idris_options', '--total --warnpartial --warnreach --warnipkg')
function! ale_linters#idris#idris#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'idris_idris_executable')
endfunction
function! ale_linters#idris#idris#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'idris_idris_options')
return ale#Escape(ale_linters#idris#idris#GetExecutable(a:buffer))
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --check %s'
endfunction
function! ale_linters#idris#idris#Handle(buffer, lines) abort
" This was copied almost verbatim from ale#handlers#haskell#HandleGHCFormat
" Look for lines like the following:
" foo.idr:2:6:When checking right hand side of main with expected type
" bar.idr:11:11-13:
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)(-\d+)?:(.*)?$'
let l:output = []
let l:corrected_lines = []
for l:line in a:lines
if len(matchlist(l:line, l:pattern)) > 0
call add(l:corrected_lines, l:line)
elseif len(l:corrected_lines) > 0
if l:line is# ''
let l:corrected_lines[-1] .= ' ' " turn a blank line into a space
else
let l:corrected_lines[-1] .= l:line
endif
let l:corrected_lines[-1] = substitute(l:corrected_lines[-1], '\s\+', ' ', 'g')
endif
endfor
for l:line in l:corrected_lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
if !ale#path#IsBufferPath(a:buffer, l:match[1])
continue
endif
let l:errors = matchlist(l:match[5], '\v([wW]arning|[eE]rror) - ?(.*)')
if len(l:errors) > 0
let l:ghc_type = l:errors[1]
let l:text = l:errors[2]
else
let l:ghc_type = ''
let l:text = l:match[5][:0] is# ' ' ? l:match[5][1:] : l:match[5]
endif
if l:ghc_type is? 'Warning'
let l:type = 'W'
else
let l:type = 'E'
endif
call add(l:output, {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:text,
\ 'type': l:type,
\})
endfor
return l:output
endfunction
call ale#linter#Define('idris', {
\ 'name': 'idris',
\ 'executable_callback': 'ale_linters#idris#idris#GetExecutable',
\ 'command_callback': 'ale_linters#idris#idris#GetCommand',
\ 'callback': 'ale_linters#idris#idris#Handle',
\})

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