diff --git a/vim/bundle/ale/.gitattributes b/vim/bundle/ale/.gitattributes
new file mode 100644
index 0000000..4da669b
--- /dev/null
+++ b/vim/bundle/ale/.gitattributes
@@ -0,0 +1,12 @@
+.* export-ignore
+/CODE_OF_CONDUCT.md export-ignore
+/CONTRIBUTING.md export-ignore
+/Dockerfile export-ignore
+/ISSUE_TEMPLATE.md export-ignore
+/Makefile export-ignore
+/PULL_REQUEST_TEMPLATE.md export-ignore
+/README.md export-ignore
+/custom-checks export-ignore
+/img export-ignore
+/run-tests export-ignore
+/test export-ignore
diff --git a/vim/bundle/ale/.gitignore b/vim/bundle/ale/.gitignore
new file mode 100644
index 0000000..30ab9ad
--- /dev/null
+++ b/vim/bundle/ale/.gitignore
@@ -0,0 +1,5 @@
+/init.vim
+/doc/tags
+.*
+*.obj
+tags
diff --git a/vim/bundle/ale/.travis.yml b/vim/bundle/ale/.travis.yml
new file mode 100644
index 0000000..2423732
--- /dev/null
+++ b/vim/bundle/ale/.travis.yml
@@ -0,0 +1,7 @@
+---
+sudo: required
+services:
+ - docker
+language: python
+script: |
+ ./run-tests
diff --git a/vim/bundle/ale/CODE_OF_CONDUCT.md b/vim/bundle/ale/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..587bb37
--- /dev/null
+++ b/vim/bundle/ale/CODE_OF_CONDUCT.md
@@ -0,0 +1,3 @@
+Codes of conduct are totally unnecessary and dumb.
+
+Just don't be a jerk and have fun.
diff --git a/vim/bundle/ale/CONTRIBUTING.md b/vim/bundle/ale/CONTRIBUTING.md
new file mode 100644
index 0000000..a32a596
--- /dev/null
+++ b/vim/bundle/ale/CONTRIBUTING.md
@@ -0,0 +1,173 @@
+# Contributing to ALE
+
+1. [Guidelines](#guidelines)
+2. [Creating Issues](#issues)
+3. [Creating Pull Requests](#pull-requests)
+ 1. [Adding a New Linter](#adding-a-new-linter)
+ 2. [Adding New Options](#adding-new-options)
+4. [Writing Documentation](#writing-documentation)
+ 1. [Documenting New Linters](#documenting-new-linters)
+ 2. [Editing the Online Documentation](#editing-online-documentation)
+ 3. [Documenting Linter Options](#documenting-linter-options)
+5. [In Case of Busses](#in-case-of-busses)
+
+
+
+## 1. Guidelines
+
+Have fun, and work on whatever floats your boat. Take It Easy :tm:.
+
+Don't forget to **write documentation** for whatever it is you are doing.
+See the ["Writing Documentation"](#writing-documentation) section.
+
+Remember to write Vader tests for most of the code you write. You can look at
+existing Vader tests in the `test` directory for examples.
+
+When writing code, follow the [Google Vimscript Style
+Guide](https://google.github.io/styleguide/vimscriptguide.xml), and run `vint
+-s` on your files to check for most of what the guide mentions and more. If you
+install this plugin (ALE) and install [Vint](https://github.com/Kuniwak/vint), it
+will check your code while you type.
+
+
+
+## 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
+issue has already been reported, but you have some new insight, please add
+a comment to the existing issue.
+
+Please read the FAQ in the README before creating any issues. A feature
+you desire may already exist and be documented, or the FAQ might explain
+how to solve a problem you have already.
+
+Please try and describe any issues reported with as much detail as you can
+provide about your Vim version, the linter you were trying to run, your
+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.
+
+
+
+## 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
+" 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 , Jane Doe
+```
+
+
+
+### 3.i. Adding a New Linter
+
+If you add a new linter, look for existing handlers first in the
+[handlers](autoload/ale/handlers) directory. One of the handlers there may
+already be able to handle your lines of output. If you find that your new
+linter replicates an existing error handler, consider pulling it up into the
+[handlers](autoload/ale/handlers) directory, and use the generic handler in
+both places.
+
+When you add a linter, make sure the language for the linter and the linter
+itself are present in the table in the [README.md](README.md) file and in the
+Vim [help file](doc/ale.txt). The programs and linters should be sorted
+alphabetically in the table and list.
+
+
+
+### 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___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...`.
+
+
+
+## 4. Writing Documentation
+
+If you are adding new linters, changing the API, adding new options, etc., you
+_must_ write some documentation describing it in the `doc/ale.txt` file. New
+linters _must_ be added to the `README.md` file too, so other users can get a
+quick overview of the supported tools.
+
+
+
+### 4.i Documenting New Linters
+
+If you add a new linter to the project, edit the table in the `README.md` file,
+and edit the list of linters at the top of the `doc/ale.txt` file. The linters
+should be sorted vertically in lexicographic (alphabetical) order by the
+programming language name or filetype, and the tools for each language should
+be sorted in lexicographic order horizontally. Sorting in this manner is a fair
+manner of presenting all of the information in an easy to scan way, without
+giving some unfair preference to any particular tool or language.
+
+
+
+### 4.ii Editing the Online Documentation
+
+The "online documentation" file used for this project lives in `doc/ale.txt`.
+This is the file used for generating `:help` text inside Vim itself. There are
+some guidlines to follow for this file.
+
+1. Keep all text within a column size of 79 characters, inclusive.
+2. Open a section with 79 `=` or `-` characters, for headings and subheadings.
+3. Sections should have a _single_ blank line before or after.
+4. Between descriptions of variables/functions/commands, use _two_ blank lines.
+5. Up-indent the description of a variable/function/command by two spaces.
+6. Place tags at the ends of lines, with the final characters on column 79.
+ All of the tags should line up perfectly on the same column as you scan
+ down through the document.
+7. Keep the table of contents balanced so the longest tag link ends on column
+ 79, and so all links line up perfectly on their first character, on the
+ left.
+
+
+
+### 4.iii Documenting Linter Options
+
+For documenting new linter options, please add a new sub-section under the
+"Linter Specific Options" section describing all of the global options added
+for each linter, and what the default values of the options are. All global
+options for linters should be set to some default value. This will allow users
+to look up the default value easily by typing `:echo g:ale_...`.
+
+
+
+## 5. In Case of Busses
+
+Should the principal author of the ALE project and all collaborators with the
+required access needed to properly administrate the project on GitHub or any
+other website either perish or disappear, whether by tragic traffic accident
+or government adduction, etc., action should be taken to ensure that the
+project continues. If no one is left to administer the project where it is
+hosted, please fork the project and nominate someone capable to administer it.
+Preferably, in such an event, a single fork of the project will replace the
+original, and life will go on, except the life of whoever vanished, because
+then they will probably be dead.
+
+Should w0rp suddenly disappear, then he was probably killed in a traffic
+accident, or the government finally decided to kill him and make it look like
+suicide. In the latter event, please subvert said government and restore
+order to the universe, and ensure peace for mankind.
diff --git a/vim/bundle/ale/Dockerfile b/vim/bundle/ale/Dockerfile
new file mode 100644
index 0000000..eba9a1f
--- /dev/null
+++ b/vim/bundle/ale/Dockerfile
@@ -0,0 +1,18 @@
+FROM tweekmonster/vim-testbed:latest
+
+RUN install_vim -tag v8.0.0027 -build \
+ -tag neovim:v0.1.7 -build
+
+ENV PACKAGES="\
+ bash \
+ git \
+ python \
+ py-pip \
+"
+RUN apk --update add $PACKAGES && \
+ rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
+
+RUN pip install vim-vint==0.3.9
+
+RUN git clone https://github.com/junegunn/vader.vim vader && \
+ cd vader && git checkout c6243dd81c98350df4dec608fa972df98fa2a3af
diff --git a/vim/bundle/ale/ISSUE_TEMPLATE.md b/vim/bundle/ale/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..45d5350
--- /dev/null
+++ b/vim/bundle/ale/ISSUE_TEMPLATE.md
@@ -0,0 +1,8 @@
+
diff --git a/vim/bundle/ale/LICENSE b/vim/bundle/ale/LICENSE
new file mode 100644
index 0000000..650050f
--- /dev/null
+++ b/vim/bundle/ale/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2016-2017, w0rp
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vim/bundle/ale/PULL_REQUEST_TEMPLATE.md b/vim/bundle/ale/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..9411653
--- /dev/null
+++ b/vim/bundle/ale/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,21 @@
+
diff --git a/vim/bundle/ale/README.md b/vim/bundle/ale/README.md
new file mode 100644
index 0000000..cbfef30
--- /dev/null
+++ b/vim/bundle/ale/README.md
@@ -0,0 +1,559 @@
+# 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
+and Vim 8 while you edit your text files.
+
+![linting example](img/example.gif?raw=true)
+
+ALE makes use of NeoVim and Vim 8 job control functions and timers to
+run linters on the contents of text buffers and return errors as
+text is changed in Vim. This allows for displaying warnings and
+errors in files being edited in Vim before files have been saved
+back to a filesystem.
+
+In other words, this plugin allows you to lint while you type.
+
+In addition to linting support, ALE offers some support for fixing code with
+formatting tools, and completion via Language Server Protocol servers, or
+servers with similar enough protocols, like `tsserver`.
+
+## 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)
+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 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)
+ 10. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint)
+ 11. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad)
+
+
+
+## 1. Supported Languages and Tools
+
+This plugin supports the following languages and tools. All available
+tools will be run in combination, so they can be complementary.
+
+
+
+| Language | Tools |
+| -------- | ----- |
+| ASM | [gcc](https://gcc.gnu.org) |
+| Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) |
+| AsciiDoc | [proselint](http://proselint.com/)|
+| Awk | [gawk](https://www.gnu.org/software/gawk/)|
+| 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/), [clang-format](https://clang.llvm.org/docs/ClangFormat.html)|
+| C++ (filetype cpp) | [clang](http://clang.llvm.org/), [clangcheck](http://clang.llvm.org/docs/ClangCheck.html), [clangtidy](http://clang.llvm.org/extra/clang-tidy/), [cppcheck](http://cppcheck.sourceforge.net), [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint), [gcc](https://gcc.gnu.org/), [clang-format](https://clang.llvm.org/docs/ClangFormat.html)|
+| C# | [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) |
+| Chef | [foodcritic](http://www.foodcritic.io/) |
+| 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/), [stylelint](https://github.com/stylelint/stylelint) |
+| Cython (pyrex filetype) | [cython](http://cython.org/) |
+| D | [dmd](https://dlang.org/dmd-linux.html) |
+| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) |
+| Dockerfile | [hadolint](https://github.com/lukasmartinelli/hadolint) |
+| Elixir | [credo](https://github.com/rrrene/credo), [dogma](https://github.com/lpil/dogma) |
+| Elm | [elm-make](https://github.com/elm-lang/elm-make) |
+| Erb | [erb](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) |
+| Fortran | [gcc](https://gcc.gnu.org/) |
+| FusionScript | [fusion-lint](https://github.com/RyanSquared/fusionscript) |
+| Go | [gofmt -e](https://golang.org/cmd/gofmt/), [go vet](https://golang.org/cmd/vet/), [golint](https://godoc.org/github.com/golang/lint), [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 | [gqlint](https://github.com/happylinks/gqlint) |
+| Haml | [haml-lint](https://github.com/brigade/haml-lint)
+| Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) |
+| Haskell | [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) |
+| HTML | [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/) |
+| Idris | [idris](http://www.idris-lang.org/) |
+| Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html) |
+| JavaScript | [eslint](http://eslint.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [flow](https://flowtype.org/), [standard](http://standardjs.com/), [prettier](https://github.com/prettier/prettier) (and `prettier-eslint`, `prettier-standard`), [xo](https://github.com/sindresorhus/xo)
+| JSON | [jsonlint](http://zaa.ch/jsonlint/) |
+| Kotlin | [kotlinc](https://kotlinlang.org), [ktlint](https://ktlint.github.io) see `:help ale-integration-kotlin` for configuration instructions
+| LaTeX | [chktex](http://www.nongnu.org/chktex/), [lacheck](https://www.ctan.org/pkg/lacheck), [proselint](http://proselint.com/) |
+| Lua | [luacheck](https://github.com/mpeterv/luacheck) |
+| Markdown | [mdl](https://github.com/mivok/markdownlint), [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale) |
+| MATLAB | [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) |
+| Nim | [nim](https://nim-lang.org/docs/nimc.html) |
+| nix | [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) |
+| nroff | [proselint](http://proselint.com/)|
+| 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-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/), [langserver](https://github.com/felixfbecker/php-language-server), [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) |
+| Pod | [proselint](http://proselint.com/)|
+| 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), [flake8](http://flake8.pycqa.org/en/latest/), [isort](https://github.com/timothycrosley/isort), [mypy](http://mypy-lang.org/), [pycodestyle](https://github.com/PyCQA/pycodestyle), [pylint](https://www.pylint.org/), [yapf](https://github.com/google/yapf) |
+| R | [lintr](https://github.com/jimhester/lintr) |
+| ReasonML | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-integration-reason-merlin` for configuration instructions
+| reStructuredText | [proselint](http://proselint.com/)|
+| 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) |
+| Rust | cargo (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/) |
+| SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) |
+| 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), [scalastyle](http://www.scalastyle.org) |
+| Slim | [slim-lint](https://github.com/sds/slim-lint)
+| SML | [smlnj](http://www.smlnj.org/) |
+| 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)|
+| Texinfo | [proselint](http://proselint.com/)|
+| Text^ | [proselint](http://proselint.com/), [vale](https://github.com/ValeLint/vale) |
+| TypeScript | [eslint](http://eslint.org/), [tslint](https://github.com/palantir/tslint), tsserver, 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^ | [proselint](http://proselint.com/)|
+| XHTML | [proselint](http://proselint.com/)|
+| XML | [xmllint](http://xmlsoft.org/xmllint.html/)|
+| YAML | [swaglint](https://github.com/byCedric/swaglint), [yamllint](https://yamllint.readthedocs.io/) |
+
+* *^ No linters for text or Vim help filetypes are enabled by default.*
+
+
+
+## 2. Usage
+
+
+
+### 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
+programs for checking the syntax and semantics of your programs. By default,
+linters will be re-run in the background to check your syntax when you open
+new buffers or as you make edits to your files.
+
+The behaviour of linting can be configured with a variety of options,
+documented in [the Vim help file](doc/ale.txt). For more information on the
+options ALE offers, consult `:help ale-options` for global options and `:help
+ale-linter-options` for options specified to particular linters.
+
+
+
+### 2.ii Fixing
+
+ALE can fix files with the `ALEFix` command. Functions need to be configured
+for different filetypes with the `g:ale_fixers` variable. For example, the
+following code can be used to fix JavaScript code with ESLint:
+
+```vim
+" Put this in vimrc or a plugin file of your own.
+" After this is configured, :ALEFix will try and fix your JS code with ESLint.
+let g:ale_fixers = {
+\ 'javascript': ['eslint'],
+\}
+
+" Set this setting in vimrc if you want to fix files automatically on save.
+" This is off by default.
+let g:ale_fix_on_save = 1
+```
+
+The `:ALEFixSuggest` command will suggest some supported tools for fixing code,
+but fixers can be also implemented with functions, including lambda functions
+too. See `:help ale-fix` for detailed information.
+
+
+
+### 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 similar protocols. At the moment, completion is only
+supported for TypeScript code with `tsserver`, when `tsserver` is enabled. You
+can enable completion like so:
+
+```vim
+" Enable completion where available.
+let g:ale_completion_enabled = 1
+```
+
+See `:help ale-completion` for more information.
+
+
+
+## 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
+Vim differently. On Windows, your `~/.vimrc` file will be similarly
+stored in `%USERPROFILE%\_vimrc`.
+
+
+
+### 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
+```
+
+
+
+### 3.ii. Installation with Pathogen
+
+To install this module with [Pathogen](https://github.com/tpope/vim-pathogen),
+you should clone this repository to your bundle directory, and ensure
+you have the line `execute pathogen#infect()` in your `~/.vimrc` file.
+You can run the following commands in your terminal to do so:
+
+```bash
+cd ~/.vim/bundle
+git clone https://github.com/w0rp/ale.git
+```
+
+
+
+### 3.iii. Installation with Vundle
+
+You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.vim)
+by using the path on GitHub for this repository.
+
+```vim
+Plugin 'w0rp/ale'
+```
+
+See the Vundle documentation for more information.
+
+
+
+## 4. Contributing
+
+If you would like to see support for more languages and tools, please
+[create an issue](https://github.com/w0rp/ale/issues)
+or [create a pull request](https://github.com/w0rp/ale/pulls).
+If your tool can read from stdin or you have code to suggest which is good,
+support can be happily added for it.
+
+If you are interested in the general direction of the project, check out the
+[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a
+Roadmap for the future, and more.
+
+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).
+
+
+
+## 5. FAQ
+
+
+
+### 5.i. How do I disable particular linters?
+
+By default, all available tools for all supported languages will be run.
+If you want to only select a subset of the tools, simply create a
+`g:ale_linters` dictionary in your vimrc file mapping filetypes
+to lists of linters to run.
+
+```vim
+let g:ale_linters = {
+\ 'javascript': ['eslint'],
+\}
+```
+
+For all languages unspecified in the dictionary, all possible linters will
+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.
+
+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.
+
+
+
+### 5.ii. How can I keep the sign gutter open?
+
+You can keep the sign gutter open at all times by setting the
+`g:ale_sign_column_always` to 1
+
+```vim
+let g:ale_sign_column_always = 1
+```
+
+
+
+### 5.iii. How can I change the signs ALE uses?
+
+Use these options to specify what text should be used for signs:
+
+```vim
+let g:ale_sign_error = '>>'
+let g:ale_sign_warning = '--'
+```
+
+ALE sets some background colors automatically for warnings and errors
+in the sign gutter, with the names `ALEErrorSign` and `ALEWarningSign`.
+These colors can be customised, or even removed completely:
+
+```vim
+highlight clear ALEErrorSign
+highlight clear ALEWarningSign
+```
+
+
+
+### 5.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:
+
+```vim
+" Set this. Airline will handle the rest.
+let g:airline#extensions#ale#enabled = 1
+```
+
+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`.
+
+Say you want to display all errors as one figure, and all non-errors as another
+figure. You can do the following:
+
+```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()}
+```
+
+See `:help ale#statusline#Count()` for more information.
+
+
+
+### 5.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
+ * `%linter%` is the linter name
+ * `%severity` is the severity type
+- `g:ale_echo_msg_error_str` is the string used for error severity.
+- `g:ale_echo_msg_warning_str` is the string used for warning severity.
+
+So for example this:
+
+```vim
+let g:ale_echo_msg_error_str = 'E'
+let g:ale_echo_msg_warning_str = 'W'
+let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
+```
+
+Will give you:
+
+![Echoed message](img/echo.png)
+
+
+
+### 5.vi. How can I execute some code when ALE stops linting?
+
+ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html)
+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 ALELint call YourFunction()
+augroup END
+```
+
+
+
+### 5.vii. How can I navigate between errors quickly?
+
+ALE offers some commands with `` keybinds for moving between warnings and
+errors quickly. You can map the keys Ctrl+j and Ctrl+k to moving between errors
+for example:
+
+```vim
+nmap (ale_previous_wrap)
+nmap (ale_next_wrap)
+```
+
+For more information, consult the online documentation with
+`:help ale-navigation-commands`.
+
+
+
+### 5.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.
+
+```vim
+" Write this in your vimrc file
+let g:ale_lint_on_text_changed = 'never'
+" 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`.
+
+
+
+### 5.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
+the `g:ale_set_loclist` option.
+
+```vim
+" Write this in your vimrc file
+let g:ale_set_loclist = 0
+let g:ale_set_quickfix = 1
+```
+
+If you wish to show Vim windows for the loclist or quickfix items
+when a file contains warnings or errors, `g:ale_open_list` can be
+set to `1`. `g:ale_keep_list_window_open` can be set to `1`
+if you wish to keep the window open even after errors disappear.
+
+```vim
+let g:ale_open_list = 1
+" Set this if you want to.
+" This can be useful if you are combining ALE with
+" some other plugin which sets quickfix errors, etc.
+let g:ale_keep_list_window_open = 1
+```
+
+
+
+### 5.x. 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 your vimrc file:
+
+```vim
+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.
+
+
+
+### 5.xi. 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`.
diff --git a/vim/bundle/ale/after/plugin/ale.vim b/vim/bundle/ale/after/plugin/ale.vim
new file mode 100644
index 0000000..d738dbd
--- /dev/null
+++ b/vim/bundle/ale/after/plugin/ale.vim
@@ -0,0 +1,37 @@
+" Author: w0rp
+" Description: Follow-up checks for the plugin: warn about conflicting plugins.
+
+" A flag for ensuring that this is not run more than one time.
+if exists('g:loaded_ale_after')
+ finish
+endif
+
+" Set the flag so this file is not run more than one time.
+let g:loaded_ale_after = 1
+
+" Check if the flag is available and set to 0 to disable checking for and
+" emitting conflicting plugin warnings.
+if exists('g:ale_emit_conflict_warnings') && !g:ale_emit_conflict_warnings
+ finish
+endif
+
+" Conflicting Plugins Checks
+
+function! s:GetConflictingPluginWarning(plugin_name) abort
+ return 'ALE conflicts with ' . a:plugin_name
+ \ . '. Uninstall it, or disable this warning with '
+ \ . '`let g:ale_emit_conflict_warnings = 0` in your vimrc file, '
+ \ . '*before* plugins are loaded.'
+endfunction
+
+if exists('g:loaded_syntastic_plugin')
+ throw s:GetConflictingPluginWarning('Syntastic')
+endif
+
+if exists('g:loaded_neomake')
+ throw s:GetConflictingPluginWarning('Neomake')
+endif
+
+if exists('g:loaded_validator_plugin')
+ throw s:GetConflictingPluginWarning('Validator')
+endif
diff --git a/vim/bundle/ale/ale_linters/ansible/ansible_lint.vim b/vim/bundle/ale/ale_linters/ansible/ansible_lint.vim
new file mode 100644
index 0000000..7d68cde
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/ansible/ansible_lint.vim
@@ -0,0 +1,48 @@
+" Author: Bjorn Neergaard
+" 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# 'EANSIBLE002'
+ \&& !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:code . ': ' . l:match[5],
+ \ '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',
+\})
diff --git a/vim/bundle/ale/ale_linters/asciidoc/proselint.vim b/vim/bundle/ale/ale_linters/asciidoc/proselint.vim
new file mode 100644
index 0000000..b636c06
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/asciidoc/proselint.vim
@@ -0,0 +1,9 @@
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/asm/gcc.vim b/vim/bundle/ale/ale_linters/asm/gcc.vim
new file mode 100644
index 0000000..39b1f7c
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/asm/gcc.vim
@@ -0,0 +1,33 @@
+" Author: Lucas Kolstad
+" Description: gcc linter for asm files
+
+let g:ale_asm_gcc_options = get(g:, 'ale_asm_gcc_options', '-Wall')
+
+function! ale_linters#asm#gcc#GetCommand(buffer) abort
+ return 'gcc -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': 'gcc',
+\ 'command_callback': 'ale_linters#asm#gcc#GetCommand',
+\ 'callback': 'ale_linters#asm#gcc#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/awk/gawk.vim b/vim/bundle/ale/ale_linters/awk/gawk.vim
new file mode 100644
index 0000000..ac6e915
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/awk/gawk.vim
@@ -0,0 +1,26 @@
+" Author: kmarc
+" 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
+ return ale_linters#awk#gawk#GetExecutable(a:buffer)
+ \ . ' ' . 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#cpplint#HandleCppLintFormat',
+\ 'output_stream': 'both'
+\})
diff --git a/vim/bundle/ale/ale_linters/c/clang.vim b/vim/bundle/ale/ale_linters/c/clang.vim
new file mode 100644
index 0000000..7680305
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/c/clang.vim
@@ -0,0 +1,29 @@
+" 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) abort
+ let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
+
+ " -iquote with the directory the file is in makes #include work for
+ " headers in the same directory.
+ return ale#Escape(ale_linters#c#clang#GetExecutable(a:buffer))
+ \ . ' -S -x c -fsyntax-only '
+ \ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
+ \ . ale#c#IncludeOptions(l:paths)
+ \ . ale#Var(a:buffer, 'c_clang_options') . ' -'
+endfunction
+
+call ale#linter#Define('c', {
+\ 'name': 'clang',
+\ 'output_stream': 'stderr',
+\ 'executable_callback': 'ale_linters#c#clang#GetExecutable',
+\ 'command_callback': 'ale_linters#c#clang#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/c/cppcheck.vim b/vim/bundle/ale/ale_linters/c/cppcheck.vim
new file mode 100644
index 0000000..4db93f7
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/c/cppcheck.vim
@@ -0,0 +1,39 @@
+" Author: Bart Libert
+" 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
+
+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',
+\})
diff --git a/vim/bundle/ale/ale_linters/c/gcc.vim b/vim/bundle/ale/ale_linters/c/gcc.vim
new file mode 100644
index 0000000..4b241e3
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/c/gcc.vim
@@ -0,0 +1,29 @@
+" Author: w0rp
+" Description: gcc linter for c files
+
+call ale#Set('c_gcc_executable', 'gcc')
+call ale#Set('c_gcc_options', '-std=c11 -Wall')
+
+function! ale_linters#c#gcc#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'c_gcc_executable')
+endfunction
+
+function! ale_linters#c#gcc#GetCommand(buffer) abort
+ let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
+
+ " -iquote with the directory the file is in makes #include work for
+ " headers in the same directory.
+ return ale#Escape(ale_linters#c#gcc#GetExecutable(a:buffer))
+ \ . ' -S -x c -fsyntax-only '
+ \ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
+ \ . ale#c#IncludeOptions(l:paths)
+ \ . 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_callback': 'ale_linters#c#gcc#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/chef/foodcritic.vim b/vim/bundle/ale/ale_linters/chef/foodcritic.vim
new file mode 100644
index 0000000..079e304
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/chef/foodcritic.vim
@@ -0,0 +1,42 @@
+" Author: Edward Larkey
+" Author: Jose Junior
+" Description: This file adds the foodcritic linter for Chef files.
+
+" Support options!
+let g:ale_chef_foodcritic_options = get(g:, 'ale_chef_foodcritic_options', '')
+let g:ale_chef_foodcritic_executable = get(g:, 'ale_chef_foodcritic_executable', 'foodcritic')
+
+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 = '^\(.\+:\s.\+\):\s\(.\+\):\(\d\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:text = l:match[1]
+
+ call add(l:output, {
+ \ 'lnum': l:match[3] + 0,
+ \ 'text': l:text,
+ \ 'type': 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+function! ale_linters#chef#foodcritic#GetCommand(buffer) abort
+ return printf('%s %s %%t',
+ \ ale#Var(a:buffer, 'chef_foodcritic_executable'),
+ \ escape(ale#Var(a:buffer, 'chef_foodcritic_options'), '~')
+ \)
+endfunction
+
+
+call ale#linter#Define('chef', {
+\ 'name': 'foodcritic',
+\ 'executable': 'foodcritic',
+\ 'command_callback': 'ale_linters#chef#foodcritic#GetCommand',
+\ 'callback': 'ale_linters#chef#foodcritic#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/cmake/cmakelint.vim b/vim/bundle/ale/ale_linters/cmake/cmakelint.vim
new file mode 100644
index 0000000..7867651
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/cmake/cmakelint.vim
@@ -0,0 +1,24 @@
+" Author: Kenneth Benzie
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/coffee/coffee.vim b/vim/bundle/ale/ale_linters/coffee/coffee.vim
new file mode 100644
index 0000000..f253928
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/coffee/coffee.vim
@@ -0,0 +1,23 @@
+" 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',
+\ 'output_stream': 'stderr',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/coffee/coffeelint.vim b/vim/bundle/ale/ale_linters/coffee/coffeelint.vim
new file mode 100644
index 0000000..6d3df35
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/coffee/coffeelint.vim
@@ -0,0 +1,43 @@
+" 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:
+ "
+ " path,lineNumber,lineNumberEnd,level,message
+ " 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:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': str2nr(l:match[1]),
+ \ 'type': l:match[3] is# 'error' ? 'E' : 'W',
+ \ 'text': l:match[4],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('coffee', {
+\ 'name': 'coffeelint',
+\ 'executable_callback': 'ale_linters#coffee#coffeelint#GetExecutable',
+\ 'command_callback': 'ale_linters#coffee#coffeelint#GetCommand',
+\ 'callback': 'ale_linters#coffee#coffeelint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/cpp/clang.vim b/vim/bundle/ale/ale_linters/cpp/clang.vim
new file mode 100644
index 0000000..105df82
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/cpp/clang.vim
@@ -0,0 +1,29 @@
+" Author: Tomota Nakamura
+" 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) abort
+ let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
+
+ " -iquote with the directory the file is in makes #include work for
+ " headers in the same directory.
+ return ale#Escape(ale_linters#cpp#clang#GetExecutable(a:buffer))
+ \ . ' -S -x c++ -fsyntax-only '
+ \ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
+ \ . ale#c#IncludeOptions(l:paths)
+ \ . 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_callback': 'ale_linters#cpp#clang#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/cpp/clangcheck.vim b/vim/bundle/ale/ale_linters/cpp/clangcheck.vim
new file mode 100644
index 0000000..4b6169c
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/cpp/clangcheck.vim
@@ -0,0 +1,39 @@
+" Author: gagbo
+" 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:user_options) ? ' ' . l:user_options : '')
+ \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
+ \ . (empty(l:build_dir) ? ' -extra-arg -Xanalyzer -extra-arg -analyzer-output=text' : '')
+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,
+\})
diff --git a/vim/bundle/ale/ale_linters/cpp/clangtidy.vim b/vim/bundle/ale/ale_linters/cpp/clangtidy.vim
new file mode 100644
index 0000000..1d5fb77
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/cpp/clangtidy.vim
@@ -0,0 +1,58 @@
+" Author: vdeurzen , w0rp ,
+" gagbo
+" 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,
+\})
diff --git a/vim/bundle/ale/ale_linters/cpp/cppcheck.vim b/vim/bundle/ale/ale_linters/cpp/cppcheck.vim
new file mode 100644
index 0000000..8b2aa80
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/cpp/cppcheck.vim
@@ -0,0 +1,39 @@
+" Author: Bart Libert
+" 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
+
+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',
+\})
diff --git a/vim/bundle/ale/ale_linters/cpp/cpplint.vim b/vim/bundle/ale/ale_linters/cpp/cpplint.vim
new file mode 100644
index 0000000..346ac81
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/cpp/cpplint.vim
@@ -0,0 +1,26 @@
+" 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,
+\})
diff --git a/vim/bundle/ale/ale_linters/cpp/gcc.vim b/vim/bundle/ale/ale_linters/cpp/gcc.vim
new file mode 100644
index 0000000..40dffc9
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/cpp/gcc.vim
@@ -0,0 +1,29 @@
+" Author: geam
+" 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
+
+function! ale_linters#cpp#gcc#GetCommand(buffer) abort
+ let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
+
+ " -iquote with the directory the file is in makes #include work for
+ " headers in the same directory.
+ return ale#Escape(ale_linters#cpp#gcc#GetExecutable(a:buffer))
+ \ . ' -S -x c++ -fsyntax-only '
+ \ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
+ \ . ale#c#IncludeOptions(l:paths)
+ \ . ale#Var(a:buffer, 'cpp_gcc_options') . ' -'
+endfunction
+
+call ale#linter#Define('cpp', {
+\ 'name': 'g++',
+\ 'output_stream': 'stderr',
+\ 'executable_callback': 'ale_linters#cpp#gcc#GetExecutable',
+\ 'command_callback': 'ale_linters#cpp#gcc#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/crystal/crystal.vim b/vim/bundle/ale/ale_linters/crystal/crystal.vim
new file mode 100644
index 0000000..81579d6
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/crystal/crystal.vim
@@ -0,0 +1,31 @@
+" Author: Jordan Andree , David Alexander
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/cs/mcs.vim b/vim/bundle/ale/ale_linters/cs/mcs.vim
new file mode 100644
index 0000000..3d042f9
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/cs/mcs.vim
@@ -0,0 +1,32 @@
+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
+
+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 = '^.\+.cs(\(\d\+\),\(\d\+\)): \(.\+\): \(.\+\)'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 0,
+ \ 'text': l:match[3] . ': ' . l:match[4],
+ \ 'type': l:match[3] =~# '^error' ? 'E' : 'W',
+ \})
+ endfor
+
+ return l:output
+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',
+\})
diff --git a/vim/bundle/ale/ale_linters/css/csslint.vim b/vim/bundle/ale/ale_linters/css/csslint.vim
new file mode 100644
index 0000000..98b7fdd
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/css/csslint.vim
@@ -0,0 +1,18 @@
+" Author: w0rp
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/css/stylelint.vim b/vim/bundle/ale/ale_linters/css/stylelint.vim
new file mode 100644
index 0000000..9f68319
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/css/stylelint.vim
@@ -0,0 +1,24 @@
+" Author: diartyz
+
+call ale#Set('css_stylelint_executable', 'stylelint')
+call ale#Set('css_stylelint_options', '')
+call ale#Set('css_stylelint_use_global', 0)
+
+function! ale_linters#css#stylelint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'css_stylelint', [
+ \ 'node_modules/.bin/stylelint',
+ \])
+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
+
+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',
+\})
diff --git a/vim/bundle/ale/ale_linters/d/dmd.vim b/vim/bundle/ale/ale_linters/d/dmd.vim
new file mode 100644
index 0000000..b91238a
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/d/dmd.vim
@@ -0,0 +1,79 @@
+" Author: w0rp
+" Description: "dmd for D files"
+
+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)
+
+ if !empty(l:dub_file)
+ return l:dub_file
+ endif
+ endfor
+
+ return ''
+endfunction
+
+function! ale_linters#d#dmd#DUBCommand(buffer) abort
+ " If we can't run dub, then skip this command.
+ if !executable('dub')
+ " Returning an empty string skips to the DMD command.
+ return ''
+ endif
+
+ let l:dub_file = s:FindDUBConfig(a:buffer)
+
+ if empty(l:dub_file)
+ return ''
+ endif
+
+ " To support older dub versions, we just change the directory to
+ " the directory where we found the dub config, and then run `dub describe`
+ " from that directory.
+ return 'cd ' . ale#Escape(fnamemodify(l:dub_file, ':h'))
+ \ . ' && dub describe --import-paths'
+endfunction
+
+function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort
+ let l:import_list = []
+
+ " Build a list of import paths generated from DUB, if available.
+ 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))
+ endif
+ endfor
+
+ return 'dmd '. join(l:import_list) . ' -o- -vcolumns -c %t'
+endfunction
+
+function! ale_linters#d#dmd#Handle(buffer, lines) abort
+ " Matches patterns lines like the following:
+ " /tmp/tmp.qclsa7qLP7/file.d(1): Error: function declaration without return type. (Note that constructors are always named 'this')
+ " /tmp/tmp.G1L5xIizvB.d(8,8): Error: module weak_reference is in file 'dstruct/weak_reference.d' which cannot be read
+ let l:pattern = '^[^(]\+(\([0-9]\+\)\,\?\([0-9]*\)): \([^:]\+\): \(.\+\)'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[1],
+ \ 'col': l:match[2],
+ \ 'type': l:match[3] is# 'Warning' ? 'W' : 'E',
+ \ 'text': l:match[4],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('d', {
+\ 'name': 'dmd',
+\ 'executable': 'dmd',
+\ 'command_chain': [
+\ {'callback': 'ale_linters#d#dmd#DUBCommand', 'output_stream': 'stdout'},
+\ {'callback': 'ale_linters#d#dmd#DMDCommand', 'output_stream': 'stderr'},
+\ ],
+\ 'callback': 'ale_linters#d#dmd#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/dart/dartanalyzer.vim b/vim/bundle/ale/ale_linters/dart/dartanalyzer.vim
new file mode 100644
index 0000000..f7b82c4
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/dart/dartanalyzer.vim
@@ -0,0 +1,40 @@
+" Author: w0rp
+" 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) : '')
+ \ . ' %t'
+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',
+\})
diff --git a/vim/bundle/ale/ale_linters/dockerfile/hadolint.vim b/vim/bundle/ale/ale_linters/dockerfile/hadolint.vim
new file mode 100644
index 0000000..5550d69
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/dockerfile/hadolint.vim
@@ -0,0 +1,77 @@
+" Author: hauleth - https://github.com/hauleth
+
+" always, yes, never
+call ale#Set('dockerfile_hadolint_use_docker', 'never')
+call ale#Set('dockerfile_hadolint_docker_image', 'lukasmartinelli/hadolint')
+
+function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
+ " 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
+
+ if l:match[1] isnot# ''
+ let l:lnum = l:match[1] + 0
+ endif
+
+ let l:type = 'W'
+ let l:text = l:match[3]
+
+ call add(l:output, {
+ \ 'lnum': l:lnum,
+ \ 'col': 0,
+ \ 'type': l:type,
+ \ 'text': l:text,
+ \ 'nr': l:match[2],
+ \})
+ 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'
+ endif
+
+ " if we reach here, we want to use 'hadolint' if present...
+ if executable('hadolint')
+ return 'hadolint'
+ endif
+
+ "... and 'docker' as a fallback.
+ return 'docker'
+endfunction
+
+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
+
+
+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',
+\})
diff --git a/vim/bundle/ale/ale_linters/elixir/credo.vim b/vim/bundle/ale/ale_linters/elixir/credo.vim
new file mode 100644
index 0000000..3699dd2
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/elixir/credo.vim
@@ -0,0 +1,37 @@
+" 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 = []
+
+ 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': 'credo',
+\ 'executable': 'mix',
+\ 'command': 'mix credo suggest --format=flycheck --read-from-stdin %s',
+\ 'callback': 'ale_linters#elixir#credo#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/elixir/dogma.vim b/vim/bundle/ale/ale_linters/elixir/dogma.vim
new file mode 100644
index 0000000..b4f32b0
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/elixir/dogma.vim
@@ -0,0 +1,38 @@
+" 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 dogma %s --format=flycheck',
+\ 'lint_file': 1,
+\ 'callback': 'ale_linters#elixir#dogma#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/elm/make.vim b/vim/bundle/ale/ale_linters/elm/make.vim
new file mode 100644
index 0000000..04563a4
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/elm/make.vim
@@ -0,0 +1,77 @@
+" Author: buffalocoder - https://github.com/buffalocoder
+" Description: Elm linting in Ale. Closely follows the Syntastic checker in https://github.com/ElmCast/elm-vim.
+
+function! ale_linters#elm#make#Handle(buffer, lines) abort
+ let l:output = []
+ let l:is_windows = has('win32')
+ let l:temp_dir = l:is_windows ? $TMP : $TMPDIR
+ let l:unparsed_lines = []
+ for l:line in a:lines
+ if l:line[0] is# '['
+ let l:errors = json_decode(l:line)
+
+ for l:error in l:errors
+ " Check if file is from the temp directory.
+ " Filters out any errors not related to the buffer.
+ if l:is_windows
+ let l:file_is_buffer = l:error.file[0:len(l:temp_dir) - 1] is? l:temp_dir
+ else
+ let l:file_is_buffer = l:error.file[0:len(l:temp_dir) - 1] is# l:temp_dir
+ endif
+
+ if l:file_is_buffer
+ call add(l:output, {
+ \ 'lnum': l:error.region.start.line,
+ \ 'col': l:error.region.start.column,
+ \ 'end_lnum': l:error.region.end.line,
+ \ 'end_col': l:error.region.end.column,
+ \ 'type': (l:error.type is? 'error') ? 'E' : 'W',
+ \ 'text': l:error.overview,
+ \ 'detail': l:error.overview . "\n\n" . l:error.details
+ \})
+ endif
+ endfor
+ elseif l:line isnot# 'Successfully generated /dev/null'
+ call add(l:unparsed_lines, l:line)
+ endif
+ endfor
+
+ 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
+
+" 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_package = ale#path#FindNearestFile(a:buffer, 'elm-package.json')
+ if empty(l:elm_package)
+ let l:dir_set_cmd = ''
+ else
+ let l:root_dir = fnamemodify(l:elm_package, ':p:h')
+ let l:dir_set_cmd = 'cd ' . ale#Escape(l:root_dir) . ' && '
+ endif
+
+ " 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-make/blob/master/src/Flags.hs
+ let l:elm_cmd = 'elm-make --report=json --output='.ale#Escape('/dev/null')
+
+ return l:dir_set_cmd . ' ' . l:elm_cmd . ' %t'
+endfunction
+
+call ale#linter#Define('elm', {
+\ 'name': 'make',
+\ 'executable': 'elm-make',
+\ 'output_stream': 'both',
+\ 'command_callback': 'ale_linters#elm#make#GetCommand',
+\ 'callback': 'ale_linters#elm#make#Handle'
+\})
diff --git a/vim/bundle/ale/ale_linters/erlang/erlc.vim b/vim/bundle/ale/ale_linters/erlang/erlc.vim
new file mode 100644
index 0000000..559dc67
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/erlang/erlc.vim
@@ -0,0 +1,96 @@
+" Author: Magnus Ottenklinger - https://github.com/evnu
+
+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'
+endfunction
+
+function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ "
+ " 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^([^:]+):(\d+): (Warning: )?(.+)$'
+
+ " parse_transforms are a special case. The error message does not indicate a location:
+ " error.erl: undefined parse transform 'some_parse_transform'
+ let l:pattern_parse_transform = '\v(undefined parse transform .*)$'
+ let l:output = []
+
+ 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'
+
+ for l:line in a:lines
+ let l:match = matchlist(l:line, l:pattern)
+
+ " Determine if the output indicates an error. We distinguish between two cases:
+ "
+ " 1) normal errors match l:pattern
+ " 2) parse_transform errors match l:pattern_parse_transform
+ "
+ " If none of the patterns above match, the line can be ignored
+ if len(l:match) == 0 " not a 'normal' warning or error
+ let l:match_parse_transform = matchlist(l:line, l:pattern_parse_transform)
+
+ if len(l:match_parse_transform) == 0 " also not a parse_transform error
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': 0,
+ \ 'col': 0,
+ \ 'type': 'E',
+ \ 'text': l:match_parse_transform[0],
+ \})
+
+ continue
+ endif
+
+ let l:line = l:match[2]
+ let l:warning_or_text = l:match[3]
+ let l:text = l:match[4]
+
+ " If this file is a header .hrl, ignore the following expected messages:
+ " - 'no module definition'
+ " - 'X is unused'
+ if l:is_hrl && (
+ \ match(l:text, l:pattern_no_module_definition) != -1
+ \ || match(l:text, l:pattern_unused) != -1
+ \)
+ continue
+ endif
+
+ if !empty(l:warning_or_text)
+ let l:type = 'W'
+ else
+ let l:type = 'E'
+ endif
+
+ call add(l:output, {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': l:line,
+ \ 'col': 0,
+ \ 'type': l:type,
+ \ 'text': l:text,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('erlang', {
+\ 'name': 'erlc',
+\ 'executable': 'erlc',
+\ 'command_callback': 'ale_linters#erlang#erlc#GetCommand',
+\ 'callback': 'ale_linters#erlang#erlc#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/erlang/syntaxerl.vim b/vim/bundle/ale/ale_linters/erlang/syntaxerl.vim
new file mode 100644
index 0000000..46ecdcb
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/erlang/syntaxerl.vim
@@ -0,0 +1,53 @@
+" Author: Dmitri Vereshchagin
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/eruby/erubis.vim b/vim/bundle/ale/ale_linters/eruby/erubis.vim
new file mode 100644
index 0000000..be9332d
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/eruby/erubis.vim
@@ -0,0 +1,11 @@
+" Author: Jake Zimmerman
+" Description: eruby checker using `erubis`, instead of `erb`
+
+call ale#linter#Define('eruby', {
+\ 'name': 'erubis',
+\ 'executable': 'erubis',
+\ 'output_stream': 'stderr',
+\ 'command': 'erubis -x %t | ruby -c',
+\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
+\})
+
diff --git a/vim/bundle/ale/ale_linters/eruby/erubylint.vim b/vim/bundle/ale/ale_linters/eruby/erubylint.vim
new file mode 100644
index 0000000..2ff03c3
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/eruby/erubylint.vim
@@ -0,0 +1,11 @@
+" Author: Matthias Guenther - https://wikimatze.de
+" Description: erb-lint for eruby/erb files
+
+call ale#linter#Define('eruby', {
+\ 'name': 'erubylint',
+\ 'executable': 'erb',
+\ 'output_stream': 'stderr',
+\ 'command': 'erb -P -x %t | ruby -c',
+\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
+\})
+
diff --git a/vim/bundle/ale/ale_linters/fortran/gcc.vim b/vim/bundle/ale/ale_linters/fortran/gcc.vim
new file mode 100644
index 0000000..5f2ac01
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/fortran/gcc.vim
@@ -0,0 +1,86 @@
+" Author: w0rp
+" 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'
+endif
+
+function! ale_linters#fortran#gcc#Handle(buffer, lines) abort
+ " We have to match a starting line and a later ending line together,
+ " like so.
+ "
+ " :21.34:
+ " Error: Expected comma in I/O list at (1)
+ let l:line_marker_pattern = ':\(\d\+\)[.:]\=\(\d\+\)\=:\=$'
+ let l:message_pattern = '^\(Error\|Warning\): \(.\+\)$'
+ let l:looking_for_message = 0
+ let l:last_loclist_obj = {}
+
+ let l:output = []
+
+ for l:line in a:lines
+ if l:looking_for_message
+ let l:match = matchlist(l:line, l:message_pattern)
+ else
+ let l:match = matchlist(l:line, l:line_marker_pattern)
+ endif
+
+ if len(l:match) == 0
+ continue
+ endif
+
+ if l:looking_for_message
+ let l:looking_for_message = 0
+
+ " 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'
+ call add(l:output, l:last_loclist_obj)
+ else
+ let l:last_loclist_obj = {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 0,
+ \}
+
+ " Start looking for the message and error type.
+ let l:looking_for_message = 1
+ endif
+ endfor
+
+ 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',
+\ 'callback': 'ale_linters#fortran#gcc#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/fuse/fusionlint.vim b/vim/bundle/ale/ale_linters/fuse/fusionlint.vim
new file mode 100644
index 0000000..968e801
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/fuse/fusionlint.vim
@@ -0,0 +1,41 @@
+" Author: RyanSquared
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/go/gobuild.vim b/vim/bundle/ale/ale_linters/go/gobuild.vim
new file mode 100644
index 0000000..143c2fd
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/go/gobuild.vim
@@ -0,0 +1,70 @@
+" Author: Joshua Rubin , Ben Reedy
+" Description: go build for Go files
+
+" inspired by work from dzhou121
+
+function! ale_linters#go#gobuild#GoEnv(buffer) abort
+ if exists('s:go_env')
+ return ''
+ endif
+
+ return 'go env GOPATH GOROOT'
+endfunction
+
+function! ale_linters#go#gobuild#GetCommand(buffer, goenv_output) abort
+ if !exists('s:go_env')
+ let s:go_env = {
+ \ 'GOPATH': a:goenv_output[0],
+ \ 'GOROOT': a:goenv_output[1],
+ \}
+ endif
+
+ " Run go test in local directory with relative path
+ return 'GOPATH=' . s:go_env.GOPATH
+ \ . ' cd ' . fnamemodify(bufname(a:buffer), ':.:h')
+ \ . ' && go test -c -o /dev/null ./'
+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"
+
+ " 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)
+endfunction
+
+function! ale_linters#go#gobuild#Handler(buffer, lines) abort
+ let l:output = []
+
+ for l:match in ale_linters#go#gobuild#GetMatches(a:lines)
+ " Omit errors from imported go packages
+ if !ale#path#IsBufferPath(a:buffer, l:match[1])
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:match[2] + 0,
+ \ 'col': l:match[3] + 0,
+ \ 'text': l:match[4],
+ \ 'type': 'E',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('go', {
+\ 'name': 'go build',
+\ 'executable': 'go',
+\ 'command_chain': [
+\ {'callback': 'ale_linters#go#gobuild#GoEnv', 'output_stream': 'stdout'},
+\ {'callback': 'ale_linters#go#gobuild#GetCommand', 'output_stream': 'stderr'},
+\ ],
+\ 'callback': 'ale_linters#go#gobuild#Handler',
+\ 'lint_file': 1,
+\})
diff --git a/vim/bundle/ale/ale_linters/go/gofmt.vim b/vim/bundle/ale/ale_linters/go/gofmt.vim
new file mode 100644
index 0000000..337deef
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/go/gofmt.vim
@@ -0,0 +1,10 @@
+" Author: neersighted
+" Description: gofmt for Go files
+
+call ale#linter#Define('go', {
+\ 'name': 'gofmt',
+\ 'output_stream': 'stderr',
+\ 'executable': 'gofmt',
+\ 'command': 'gofmt -e %t',
+\ 'callback': 'ale#handlers#unix#HandleAsError',
+\})
diff --git a/vim/bundle/ale/ale_linters/go/golint.vim b/vim/bundle/ale/ale_linters/go/golint.vim
new file mode 100644
index 0000000..cc807fe
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/go/golint.vim
@@ -0,0 +1,9 @@
+" Author: neersighted
+" Description: golint for Go files
+
+call ale#linter#Define('go', {
+\ 'name': 'golint',
+\ 'executable': 'golint',
+\ 'command': 'golint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/go/gometalinter.vim b/vim/bundle/ale/ale_linters/go/gometalinter.vim
new file mode 100644
index 0000000..f1abfc8
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/go/gometalinter.vim
@@ -0,0 +1,49 @@
+" Author: Ben Reedy
+" Description: Adds support for the gometalinter suite for Go files
+
+call ale#Set('go_gometalinter_options', '')
+call ale#Set('go_gometalinter_executable', 'gometalinter')
+
+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)
+ let l:options = ale#Var(a:buffer, 'go_gometalinter_options')
+
+ return ale#Escape(l:executable)
+ \ . ' --include=' . ale#Escape('^' . ale#util#EscapePCRE(l:filename))
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . ' ' . ale#Escape(fnamemodify(l:filename, ':h'))
+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:output = []
+
+ for l:match in ale_linters#go#gometalinter#GetMatches(a:lines)
+ call add(l:output, {
+ \ '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,
+\})
diff --git a/vim/bundle/ale/ale_linters/go/gosimple.vim b/vim/bundle/ale/ale_linters/go/gosimple.vim
new file mode 100644
index 0000000..4b7d340
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/go/gosimple.vim
@@ -0,0 +1,9 @@
+" Author: Ben Reedy
+" Description: gosimple for Go files
+
+call ale#linter#Define('go', {
+\ 'name': 'gosimple',
+\ 'executable': 'gosimple',
+\ 'command': 'gosimple %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/go/govet.vim b/vim/bundle/ale/ale_linters/go/govet.vim
new file mode 100644
index 0000000..f5bb47a
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/go/govet.vim
@@ -0,0 +1,10 @@
+" Author: neersighted
+" Description: go vet for Go files
+
+call ale#linter#Define('go', {
+\ 'name': 'go vet',
+\ 'output_stream': 'stderr',
+\ 'executable': 'go',
+\ 'command': 'go vet %t',
+\ 'callback': 'ale#handlers#unix#HandleAsError',
+\})
diff --git a/vim/bundle/ale/ale_linters/go/staticcheck.vim b/vim/bundle/ale/ale_linters/go/staticcheck.vim
new file mode 100644
index 0000000..c78b320
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/go/staticcheck.vim
@@ -0,0 +1,9 @@
+" Author: Ben Reedy
+" Description: staticcheck for Go files
+
+call ale#linter#Define('go', {
+\ 'name': 'staticcheck',
+\ 'executable': 'staticcheck',
+\ 'command': 'staticcheck %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/graphql/gqlint.vim b/vim/bundle/ale/ale_linters/graphql/gqlint.vim
new file mode 100644
index 0000000..882cc69
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/graphql/gqlint.vim
@@ -0,0 +1,9 @@
+" Author: Michiel Westerbeek
+" Description: Linter for GraphQL Schemas
+
+call ale#linter#Define('graphql', {
+\ 'name': 'gqlint',
+\ 'executable': 'gqlint',
+\ 'command': 'gqlint --reporter=simple %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/haml/hamllint.vim b/vim/bundle/ale/ale_linters/haml/hamllint.vim
new file mode 100644
index 0000000..b1a6aa5
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/haml/hamllint.vim
@@ -0,0 +1,26 @@
+" Author: Patrick Lewis - https://github.com/patricklewis
+" Description: haml-lint for Haml files
+
+function! ale_linters#haml#hamllint#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ " :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': 'haml-lint %t',
+\ 'callback': 'ale_linters#haml#hamllint#Handle'
+\})
diff --git a/vim/bundle/ale/ale_linters/handlebars/embertemplatelint.vim b/vim/bundle/ale/ale_linters/handlebars/embertemplatelint.vim
new file mode 100644
index 0000000..963ab56
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/handlebars/embertemplatelint.vim
@@ -0,0 +1,50 @@
+" Author: Adrian Zalewski
+" Description: Ember-template-lint for checking Handlebars files
+
+call ale#Set('handlebars_embertemplatelint_executable', 'ember-template-lint')
+call ale#Set('handlebars_embertemplatelint_use_global', 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, {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': 1,
+ \ 'col': 1,
+ \ 'text': l:error.message,
+ \ 'type': l:error.severity == 1 ? 'W' : 'E',
+ \})
+ else
+ call add(l:output, {
+ \ 'bufnr': a:buffer,
+ \ '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',
+\})
diff --git a/vim/bundle/ale/ale_linters/haskell/ghc-mod.vim b/vim/bundle/ale/ale_linters/haskell/ghc-mod.vim
new file mode 100644
index 0000000..1b15d8c
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/haskell/ghc-mod.vim
@@ -0,0 +1,16 @@
+" Author: wizzup
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/haskell/ghc.vim b/vim/bundle/ale/ale_linters/haskell/ghc.vim
new file mode 100644
index 0000000..fdf22f9
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/haskell/ghc.vim
@@ -0,0 +1,10 @@
+" Author: w0rp
+" Description: ghc for Haskell files
+
+call ale#linter#Define('haskell', {
+\ 'name': 'ghc',
+\ 'output_stream': 'stderr',
+\ 'executable': 'ghc',
+\ 'command': 'ghc -fno-code -v0 %t',
+\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/haskell/hdevtools.vim b/vim/bundle/ale/ale_linters/haskell/hdevtools.vim
new file mode 100644
index 0000000..93c7ddd
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/haskell/hdevtools.vim
@@ -0,0 +1,22 @@
+" Author: rob-b, Takano Akio
+" Description: hdevtools for Haskell files
+
+call ale#Set('haskell_hdevtools_executable', 'hdevtools')
+call ale#Set('haskell_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',
+\})
diff --git a/vim/bundle/ale/ale_linters/haskell/hlint.vim b/vim/bundle/ale/ale_linters/haskell/hlint.vim
new file mode 100644
index 0000000..be40d92
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/haskell/hlint.vim
@@ -0,0 +1,34 @@
+" Author: jparoz
+" Description: hlint for Haskell files
+
+function! ale_linters#haskell#hlint#Handle(buffer, lines) abort
+ 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
+
+ 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),
+ \ 'text': l:error.severity . ': ' . l:error.hint . '. Found: ' . l:error.from . ' Why not: ' . l:error.to,
+ \ 'type': l:type,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('haskell', {
+\ 'name': 'hlint',
+\ 'executable': 'hlint',
+\ 'command': 'hlint --color=never --json -',
+\ 'callback': 'ale_linters#haskell#hlint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/haskell/stack_build.vim b/vim/bundle/ale/ale_linters/haskell/stack_build.vim
new file mode 100644
index 0000000..525fd3f
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/haskell/stack_build.vim
@@ -0,0 +1,22 @@
+" Author: Jake Zimmerman
+" Description: Like stack-ghc, but for entire projects
+"
+" Note: Ideally, this would *only* typecheck. Right now, it also does codegen.
+" See .
+
+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',
+\})
diff --git a/vim/bundle/ale/ale_linters/haskell/stack_ghc.vim b/vim/bundle/ale/ale_linters/haskell/stack_ghc.vim
new file mode 100644
index 0000000..0367dc2
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/haskell/stack_ghc.vim
@@ -0,0 +1,10 @@
+" Author: w0rp
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/help/proselint.vim b/vim/bundle/ale/ale_linters/help/proselint.vim
new file mode 100644
index 0000000..6212450
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/help/proselint.vim
@@ -0,0 +1,9 @@
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/html/htmlhint.vim b/vim/bundle/ale/ale_linters/html/htmlhint.vim
new file mode 100644
index 0000000..e142d22
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/html/htmlhint.vim
@@ -0,0 +1,25 @@
+" Author: KabbAmine , deathmaz <00maz1987@gmail.com>, diartyz
+" Description: HTMLHint for checking html files
+
+call ale#Set('html_htmlhint_options', '--format=unix')
+call ale#Set('html_htmlhint_executable', 'htmlhint')
+call ale#Set('html_htmlhint_use_global', 0)
+
+function! ale_linters#html#htmlhint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'html_htmlhint', [
+ \ 'node_modules/.bin/htmlhint',
+ \])
+endfunction
+
+function! ale_linters#html#htmlhint#GetCommand(buffer) abort
+ return ale_linters#html#htmlhint#GetExecutable(a:buffer)
+ \ . ' ' . ale#Var(a:buffer, 'html_htmlhint_options')
+ \ . ' %t'
+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',
+\})
diff --git a/vim/bundle/ale/ale_linters/html/proselint.vim b/vim/bundle/ale/ale_linters/html/proselint.vim
new file mode 100644
index 0000000..9fd7d67
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/html/proselint.vim
@@ -0,0 +1,9 @@
+" 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',
+\})
diff --git a/vim/bundle/ale/ale_linters/html/tidy.vim b/vim/bundle/ale/ale_linters/html/tidy.vim
new file mode 100644
index 0000000..4a55d62
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/html/tidy.vim
@@ -0,0 +1,69 @@
+" Author: KabbAmine
+" 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')
+" Look for the old _args variable first.
+let s:default_options = get(g:, 'ale_html_tidy_args', '-q -e -language en')
+let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', s:default_options)
+
+function! ale_linters#html#tidy#GetCommand(buffer) abort
+ " Specify file encoding in options
+ " (Idea taken from https://github.com/scrooloose/syntastic/blob/master/syntax_checkers/html/tidy.vim)
+ let l:file_encoding = get({
+ \ 'ascii': '-ascii',
+ \ 'big5': '-big5',
+ \ 'cp1252': '-win1252',
+ \ 'cp850': '-ibm858',
+ \ 'cp932': '-shiftjis',
+ \ 'iso-2022-jp': '-iso-2022',
+ \ 'latin1': '-latin1',
+ \ 'macroman': '-mac',
+ \ 'sjis': '-shiftjis',
+ \ 'utf-16le': '-utf16le',
+ \ 'utf-16': '-utf16',
+ \ 'utf-8': '-utf8',
+ \ }, &fileencoding, '-utf8')
+
+ return printf('%s %s %s -',
+ \ ale#Var(a:buffer, 'html_tidy_executable'),
+ \ ale#Var(a:buffer, 'html_tidy_options'),
+ \ 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
+ " Matches patterns lines like the following:
+ " line 7 column 5 - Warning: missing before
+
+ let l:pattern = '^line \(\d\+\) column \(\d\+\) - \(Warning\|Error\): \(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ 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:text = l:match[4]
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'col': l:col,
+ \ 'text': l:text,
+ \ 'type': l:type,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('html', {
+\ 'name': 'tidy',
+\ 'executable_callback': 'ale_linters#html#tidy#GetExecutable',
+\ 'output_stream': 'stderr',
+\ 'command_callback': 'ale_linters#html#tidy#GetCommand',
+\ 'callback': 'ale_linters#html#tidy#Handle',
+\ })
diff --git a/vim/bundle/ale/ale_linters/idris/idris.vim b/vim/bundle/ale/ale_linters/idris/idris.vim
new file mode 100644
index 0000000..115d04f
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/idris/idris.vim
@@ -0,0 +1,87 @@
+" Author: Scott Bonds
+" 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',
+\})
+
diff --git a/vim/bundle/ale/ale_linters/java/checkstyle.vim b/vim/bundle/ale/ale_linters/java/checkstyle.vim
new file mode 100644
index 0000000..d3d4884
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/java/checkstyle.vim
@@ -0,0 +1,46 @@
+" Author: Devon Meunier
+" Description: checkstyle for Java files
+
+function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
+ let l:patterns = [
+ \ '\v\[(WARN|ERROR)\] .*:(\d+):(\d+): (.*)',
+ \ '\v\[(WARN|ERROR)\] .*:(\d+): (.*)',
+ \]
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:patterns)
+ let l:args = {
+ \ 'lnum': l:match[2] + 0,
+ \ 'type': l:match[1] =~? 'WARN' ? 'W' : 'E'
+ \ }
+
+ let l:col = l:match[3] + 0
+ if l:col > 0
+ let l:args['col'] = l:col
+ let l:args['text'] = l:match[4]
+ else
+ let l:args['text'] = l:match[3]
+ endif
+
+ call add(l:output, l:args)
+ endfor
+
+ return l:output
+endfunction
+
+function! ale_linters#java#checkstyle#GetCommand(buffer) abort
+ return 'checkstyle '
+ \ . ale#Var(a:buffer, 'java_checkstyle_options')
+ \ . ' %t'
+endfunction
+
+if !exists('g:ale_java_checkstyle_options')
+ let g:ale_java_checkstyle_options = '-c /google_checks.xml'
+endif
+
+call ale#linter#Define('java', {
+\ 'name': 'checkstyle',
+\ 'executable': 'checkstyle',
+\ 'command_callback': 'ale_linters#java#checkstyle#GetCommand',
+\ 'callback': 'ale_linters#java#checkstyle#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/java/javac.vim b/vim/bundle/ale/ale_linters/java/javac.vim
new file mode 100644
index 0000000..d4566ab
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/java/javac.vim
@@ -0,0 +1,94 @@
+" Author: farenjihn , w0rp
+" Description: Lints java files using javac
+
+let s:classpath_sep = has('unix') ? ':' : ';'
+
+let g:ale_java_javac_options = get(g:, 'ale_java_javac_options', '')
+let g:ale_java_javac_classpath = get(g:, 'ale_java_javac_classpath', '')
+
+function! ale_linters#java#javac#GetImportPaths(buffer) abort
+ let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
+
+ if !empty(l:pom_path) && executable('mvn')
+ return ale#path#CdString(fnamemodify(l:pom_path, ':h'))
+ \ . 'mvn dependency:build-classpath'
+ endif
+
+ return ''
+endfunction
+
+function! s:BuildClassPathOption(buffer, import_paths) abort
+ " Filter out lines like [INFO], etc.
+ let l:class_paths = filter(a:import_paths[:], 'v:val !~# ''[''')
+ call extend(
+ \ l:class_paths,
+ \ split(ale#Var(a:buffer, 'java_javac_classpath'), s:classpath_sep),
+ \)
+
+ return !empty(l:class_paths)
+ \ ? '-cp ' . ale#Escape(join(l:class_paths, s:classpath_sep))
+ \ : ''
+endfunction
+
+function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort
+ let l:cp_option = s:BuildClassPathOption(a:buffer, a:import_paths)
+ let l:sp_option = ''
+
+ " Find the src directory, for files in this project.
+ let l:src_dir = ale#path#FindNearestDirectory(a:buffer, 'src/main/java')
+
+ if !empty(l:src_dir)
+ let l:sp_option = '-sourcepath ' . ale#Escape(l:src_dir)
+ endif
+
+ " Create .class files in a temporary directory, which we will delete later.
+ let l:class_file_directory = ale#engine#CreateDirectory(a:buffer)
+
+ return 'javac -Xlint'
+ \ . ' ' . l:cp_option
+ \ . ' ' . l:sp_option
+ \ . ' -d ' . ale#Escape(l:class_file_directory)
+ \ . ' ' . ale#Var(a:buffer, 'java_javac_options')
+ \ . ' %t'
+endfunction
+
+function! ale_linters#java#javac#Handle(buffer, lines) abort
+ " Look for lines like the following.
+ "
+ " Main.java:13: warning: [deprecation] donaught() in Testclass has been deprecated
+ " Main.java:16: error: ';' expected
+
+ let l:pattern = '\v^.*:(\d+): (.+):(.+)$'
+ let l:col_pattern = '\v^(\s*\^)$'
+ let l:symbol_pattern = '\v^ +symbol: *(class|method) +([^ ]+)'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:col_pattern, l:symbol_pattern])
+ if empty(l:match[2]) && empty(l:match[3])
+ let l:output[-1].col = len(l:match[1])
+ elseif empty(l:match[3])
+ " Add symbols to 'cannot find symbol' errors.
+ if l:output[-1].text is# 'error: cannot find symbol'
+ let l:output[-1].text .= ': ' . l:match[2]
+ endif
+ else
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'text': l:match[2] . ':' . l:match[3],
+ \ 'type': l:match[2] is# 'error' ? 'E' : 'W',
+ \})
+ endif
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('java', {
+\ 'name': 'javac',
+\ 'executable': 'javac',
+\ 'command_chain': [
+\ {'callback': 'ale_linters#java#javac#GetImportPaths', 'output_stream': 'stdout'},
+\ {'callback': 'ale_linters#java#javac#GetCommand', 'output_stream': 'stderr'},
+\ ],
+\ 'callback': 'ale_linters#java#javac#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/javascript/eslint.vim b/vim/bundle/ale/ale_linters/javascript/eslint.vim
new file mode 100644
index 0000000..785b8bb
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/javascript/eslint.vim
@@ -0,0 +1,9 @@
+" Author: w0rp
+" Description: eslint for JavaScript files
+
+call ale#linter#Define('javascript', {
+\ 'name': 'eslint',
+\ 'executable_callback': 'ale#handlers#eslint#GetExecutable',
+\ 'command_callback': 'ale#handlers#eslint#GetCommand',
+\ 'callback': 'ale#handlers#eslint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/javascript/flow.vim b/vim/bundle/ale/ale_linters/javascript/flow.vim
new file mode 100644
index 0000000..0dd6453
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/javascript/flow.vim
@@ -0,0 +1,117 @@
+" Author: Zach Perrault -- @zperrault
+" Description: FlowType checking for JavaScript files
+
+call ale#Set('javascript_flow_executable', 'flow')
+call ale#Set('javascript_flow_use_global', 0)
+
+function! ale_linters#javascript#flow#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'javascript_flow', [
+ \ 'node_modules/.bin/flow',
+ \])
+endfunction
+
+function! ale_linters#javascript#flow#VersionCheck(buffer) abort
+ return ale#Escape(ale_linters#javascript#flow#GetExecutable(a:buffer))
+ \ . ' --version'
+endfunction
+
+function! ale_linters#javascript#flow#GetCommand(buffer, version_lines) abort
+ let l:flow_config = ale#path#FindNearestFile(a:buffer, '.flowconfig')
+
+ if empty(l:flow_config)
+ " Don't run Flow if we can't find a .flowconfig file.
+ return ''
+ endif
+
+ let l:use_respect_pragma = 1
+
+ " If we can parse the version number, then only use --respect-pragma
+ " if the version is >= 0.36.0, which added the argument.
+ for l:match in ale#util#GetMatches(a:version_lines, '\v\d+\.\d+\.\d+$')
+ let l:use_respect_pragma = ale#semver#GreaterOrEqual(
+ \ ale#semver#Parse(l:match[0]),
+ \ [0, 36, 0]
+ \)
+ endfor
+
+ return ale#Escape(ale_linters#javascript#flow#GetExecutable(a:buffer))
+ \ . ' check-contents'
+ \ . (l:use_respect_pragma ? ' --respect-pragma': '')
+ \ . ' --json --from ale %s'
+endfunction
+
+" Filter lines of flow output until we find the first line where the JSON
+" output starts.
+function! s:GetJSONLines(lines) abort
+ let l:start_index = 0
+
+ for l:line in a:lines
+ if l:line[:0] is# '{'
+ break
+ endif
+
+ let l:start_index += 1
+ endfor
+
+ return a:lines[l:start_index :]
+endfunction
+
+function! ale_linters#javascript#flow#Handle(buffer, lines) abort
+ let l:str = join(s:GetJSONLines(a:lines), '')
+
+ if empty(l:str)
+ return []
+ endif
+
+ let l:flow_output = json_decode(l:str)
+ let l:output = []
+
+ for l:error in get(l:flow_output, 'errors', [])
+ " Each error is broken up into parts
+ let l:text = ''
+ let l:line = 0
+ let l:col = 0
+
+ for l:message in l:error.message
+ " Comments have no line of column information, so we skip them.
+ " In certain cases, `l:message.loc.source` points to a different path
+ " than the buffer one, thus we skip this loc information too.
+ if has_key(l:message, 'loc')
+ \&& l:line is# 0
+ \&& ale#path#IsBufferPath(a:buffer, l:message.loc.source)
+ let l:line = l:message.loc.start.line + 0
+ let l:col = l:message.loc.start.column + 0
+ endif
+
+ if l:text is# ''
+ let l:text = l:message.descr . ':'
+ else
+ let l:text = l:text . ' ' . l:message.descr
+ endif
+ endfor
+
+ if has_key(l:error, 'operation')
+ let l:text = l:text . ' See also: ' . l:error.operation.descr
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'col': l:col,
+ \ 'text': l:text,
+ \ 'type': l:error.level is# 'error' ? 'E' : 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('javascript', {
+\ 'name': 'flow',
+\ 'executable_callback': 'ale_linters#javascript#flow#GetExecutable',
+\ 'command_chain': [
+\ {'callback': 'ale_linters#javascript#flow#VersionCheck'},
+\ {'callback': 'ale_linters#javascript#flow#GetCommand'},
+\ ],
+\ 'callback': 'ale_linters#javascript#flow#Handle',
+\ 'add_newline': !has('win32'),
+\})
diff --git a/vim/bundle/ale/ale_linters/javascript/jscs.vim b/vim/bundle/ale/ale_linters/javascript/jscs.vim
new file mode 100644
index 0000000..b3f826c
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/javascript/jscs.vim
@@ -0,0 +1,63 @@
+" Author: Chris Kyrouac - https://github.com/fijshion
+" Description: jscs for JavaScript files
+
+call ale#Set('javascript_jscs_executable', 'jscs')
+call ale#Set('javascript_jscs_use_global', 0)
+
+function! ale_linters#javascript#jscs#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'javascript_jscs', [
+ \ 'node_modules/.bin/jscs',
+ \])
+endfunction
+
+function! ale_linters#javascript#jscs#GetCommand(buffer) abort
+ " Search for a local JShint config locaation, and default to a global one.
+ let l:jscs_config = ale#path#ResolveLocalPath(
+ \ a:buffer,
+ \ '.jscsrc',
+ \ get(g:, 'ale_jscs_config_loc', '')
+ \)
+
+ let l:command = ale#Escape(ale_linters#javascript#jscs#GetExecutable(a:buffer))
+ let l:command .= ' --reporter inline --no-colors'
+
+ if !empty(l:jscs_config)
+ let l:command .= ' --config ' . ale#Escape(l:jscs_config)
+ endif
+
+ let l:command .= ' -'
+
+ return l:command
+endfunction
+
+function! ale_linters#javascript#jscs#Handle(buffer, lines) abort
+ " Matches patterns looking like the following
+ "
+ " foobar.js: line 2, col 1, Expected indentation of 1 characters
+ "
+ let l:pattern = '^.*:\s\+line \(\d\+\),\s\+col\s\+\(\d\+\),\s\+\(.*\)$'
+ let l:output = []
+ let l:m = ale#util#GetMatches(a:lines, [l:pattern])
+
+ for l:match in l:m
+ let l:text = l:match[3]
+
+ let l:obj = {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 0,
+ \ 'text': l:match[3]
+ \}
+
+ call add(l:output, l:obj)
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('javascript', {
+\ 'name': 'jscs',
+\ 'executable_callback': 'ale_linters#javascript#jscs#GetExecutable',
+\ 'command_callback': 'ale_linters#javascript#jscs#GetCommand',
+\ 'callback': 'ale_linters#javascript#jscs#Handle',
+\})
+
diff --git a/vim/bundle/ale/ale_linters/javascript/jshint.vim b/vim/bundle/ale/ale_linters/javascript/jshint.vim
new file mode 100644
index 0000000..93b16a8
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/javascript/jshint.vim
@@ -0,0 +1,38 @@
+" Author: Chris Kyrouac - https://github.com/fijshion
+" Description: JSHint for Javascript files
+
+call ale#Set('javascript_jshint_executable', 'jshint')
+call ale#Set('javascript_jshint_use_global', 0)
+
+function! ale_linters#javascript#jshint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'javascript_jshint', [
+ \ 'node_modules/.bin/jshint',
+ \])
+endfunction
+
+function! ale_linters#javascript#jshint#GetCommand(buffer) abort
+ " Search for a local JShint config locaation, and default to a global one.
+ let l:jshint_config = ale#path#ResolveLocalPath(
+ \ a:buffer,
+ \ '.jshintrc',
+ \ get(g:, 'ale_jshint_config_loc', '')
+ \)
+
+ let l:command = ale#Escape(ale_linters#javascript#jshint#GetExecutable(a:buffer))
+ let l:command .= ' --reporter unix --extract auto'
+
+ if !empty(l:jshint_config)
+ let l:command .= ' --config ' . ale#Escape(l:jshint_config)
+ endif
+
+ let l:command .= ' -'
+
+ return l:command
+endfunction
+
+call ale#linter#Define('javascript', {
+\ 'name': 'jshint',
+\ 'executable_callback': 'ale_linters#javascript#jshint#GetExecutable',
+\ 'command_callback': 'ale_linters#javascript#jshint#GetCommand',
+\ 'callback': 'ale#handlers#unix#HandleAsError',
+\})
diff --git a/vim/bundle/ale/ale_linters/javascript/standard.vim b/vim/bundle/ale/ale_linters/javascript/standard.vim
new file mode 100644
index 0000000..aa6a3a7
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/javascript/standard.vim
@@ -0,0 +1,30 @@
+" Author: Ahmed El Gabri <@ahmedelgabri>
+" Description: standardjs for JavaScript files
+
+call ale#Set('javascript_standard_executable', 'standard')
+call ale#Set('javascript_standard_use_global', 0)
+call ale#Set('javascript_standard_options', '')
+
+function! ale_linters#javascript#standard#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
+ \ 'node_modules/standard/bin/cmd.js',
+ \ 'node_modules/.bin/standard',
+ \])
+endfunction
+
+function! ale_linters#javascript#standard#GetCommand(buffer) abort
+ let l:executable = ale_linters#javascript#standard#GetExecutable(a:buffer)
+ let l:options = ale#Var(a:buffer, 'javascript_standard_options')
+
+ return ale#node#Executable(a:buffer, l:executable)
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . ' --stdin %s'
+endfunction
+
+" standard uses eslint and the output format is the same
+call ale#linter#Define('javascript', {
+\ 'name': 'standard',
+\ 'executable_callback': 'ale_linters#javascript#standard#GetExecutable',
+\ 'command_callback': 'ale_linters#javascript#standard#GetCommand',
+\ 'callback': 'ale#handlers#eslint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/javascript/xo.vim b/vim/bundle/ale/ale_linters/javascript/xo.vim
new file mode 100644
index 0000000..cf305eb
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/javascript/xo.vim
@@ -0,0 +1,26 @@
+" Author: Daniel Lupu
+" Description: xo for JavaScript files
+
+call ale#Set('javascript_xo_executable', 'xo')
+call ale#Set('javascript_xo_use_global', 0)
+call ale#Set('javascript_xo_options', '')
+
+function! ale_linters#javascript#xo#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'javascript_xo', [
+ \ 'node_modules/.bin/xo',
+ \])
+endfunction
+
+function! ale_linters#javascript#xo#GetCommand(buffer) abort
+ return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer))
+ \ . ' ' . ale#Var(a:buffer, 'javascript_xo_options')
+ \ . ' --reporter unix --stdin --stdin-filename %s'
+endfunction
+
+" xo uses eslint and the output format is the same
+call ale#linter#Define('javascript', {
+\ 'name': 'xo',
+\ 'executable_callback': 'ale_linters#javascript#xo#GetExecutable',
+\ 'command_callback': 'ale_linters#javascript#xo#GetCommand',
+\ 'callback': 'ale#handlers#eslint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/json/jsonlint.vim b/vim/bundle/ale/ale_linters/json/jsonlint.vim
new file mode 100644
index 0000000..75f4708
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/json/jsonlint.vim
@@ -0,0 +1,27 @@
+" Author: KabbAmine
+
+function! ale_linters#json#jsonlint#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ " line 2, col 15, found: 'STRING' - expected: 'EOF', '}', ',', ']'.
+
+ let l:pattern = '^line \(\d\+\), col \(\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[3],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('json', {
+\ 'name': 'jsonlint',
+\ 'executable': 'jsonlint',
+\ 'output_stream': 'stderr',
+\ 'command': 'jsonlint --compact -',
+\ 'callback': 'ale_linters#json#jsonlint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/kotlin/kotlinc.vim b/vim/bundle/ale/ale_linters/kotlin/kotlinc.vim
new file mode 100644
index 0000000..00f94be
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/kotlin/kotlinc.vim
@@ -0,0 +1,170 @@
+" Author: Francis Agyapong
+" Description: A linter for the Kotlin programming language that uses kotlinc
+
+let g:ale_kotlin_kotlinc_options = get(g:, 'ale_kotlin_kotlinc_options', '')
+let g:ale_kotlin_kotlinc_enable_config = get(g:, 'ale_kotlin_kotlinc_enable_config', 0)
+let g:ale_kotlin_kotlinc_config_file = get(g:, 'ale_kotlin_kotlinc_config_file', '.ale_kotlinc_config')
+let g:ale_kotlin_kotlinc_classpath = get(g:, 'ale_kotlin_kotlinc_classpath', '')
+let g:ale_kotlin_kotlinc_sourcepath = get(g:, 'ale_kotlin_kotlinc_sourcepath', '')
+let g:ale_kotlin_kotlinc_use_module_file = get(g:, 'ale_kotlin_kotlinc_use_module_file', 0)
+let g:ale_kotlin_kotlinc_module_filename = get(g:, 'ale_kotlin_kotlinc_module_filename', 'module.xml')
+
+let s:classpath_sep = has('unix') ? ':' : ';'
+
+function! ale_linters#kotlin#kotlinc#GetImportPaths(buffer) abort
+ " exec maven/gradle only if classpath is not set
+ if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# ''
+ return ''
+ else
+ let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
+ if !empty(l:pom_path) && executable('mvn')
+ return ale#path#CdString(fnamemodify(l:pom_path, ':h'))
+ \ . 'mvn dependency:build-classpath'
+ endif
+
+ let l:classpath_command = ale#gradle#BuildClasspathCommand(a:buffer)
+ if !empty(l:classpath_command)
+ return l:classpath_command
+ endif
+
+ return ''
+ endif
+endfunction
+
+function! s:BuildClassPathOption(buffer, import_paths) abort
+ " Filter out lines like [INFO], etc.
+ let l:class_paths = filter(a:import_paths[:], 'v:val !~# ''[''')
+ call extend(
+ \ l:class_paths,
+ \ split(ale#Var(a:buffer, 'kotlin_kotlinc_classpath'), s:classpath_sep),
+ \)
+
+ return !empty(l:class_paths)
+ \ ? ' -cp ' . ale#Escape(join(l:class_paths, s:classpath_sep))
+ \ : ''
+endfunction
+
+function! ale_linters#kotlin#kotlinc#GetCommand(buffer, import_paths) abort
+ let l:kotlinc_opts = ale#Var(a:buffer, 'kotlin_kotlinc_options')
+ let l:command = 'kotlinc '
+
+ " If the config file is enabled and readable, source it
+ if ale#Var(a:buffer, 'kotlin_kotlinc_enable_config')
+ let l:conf = expand(ale#Var(a:buffer, 'kotlin_kotlinc_config_file'), 1)
+
+ if filereadable(l:conf)
+ execute 'source ' . fnameescape(l:conf)
+ endif
+ endif
+
+ " If use module and module file is readable use that and return
+ if ale#Var(a:buffer, 'kotlin_kotlinc_use_module_file')
+ let l:module_filename = ale#Escape(expand(ale#Var(a:buffer, 'kotlin_kotlinc_module_filename'), 1))
+
+ if filereadable(l:module_filename)
+ let l:kotlinc_opts .= ' -module ' . l:module_filename
+ let l:command .= 'kotlinc ' . l:kotlinc_opts
+
+ return l:command
+ endif
+ endif
+
+ " We only get here if not using module or the module file not readable
+ if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# ''
+ let l:kotlinc_opts .= ' -cp ' . ale#Var(a:buffer, 'kotlin_kotlinc_classpath')
+ else
+ " get classpath from maven/gradle
+ let l:kotlinc_opts .= s:BuildClassPathOption(a:buffer, a:import_paths)
+ endif
+
+ let l:fname = ''
+ if ale#Var(a:buffer, 'kotlin_kotlinc_sourcepath') isnot# ''
+ let l:fname .= expand(ale#Var(a:buffer, 'kotlin_kotlinc_sourcepath'), 1) . ' '
+ else
+ " Find the src directory for files in this project.
+
+ let l:project_root = ale#gradle#FindProjectRoot(a:buffer)
+ if !empty(l:project_root)
+ let l:src_dir = l:project_root
+ else
+ let l:src_dir = ale#path#FindNearestDirectory(a:buffer, 'src/main/java')
+ \ . ' ' . ale#path#FindNearestDirectory(a:buffer, 'src/main/kotlin')
+ endif
+
+ let l:fname .= expand(l:src_dir, 1) . ' '
+ endif
+ let l:fname .= ale#Escape(expand('#' . a:buffer . ':p'))
+ let l:command .= l:kotlinc_opts . ' ' . l:fname
+
+ return l:command
+endfunction
+
+function! ale_linters#kotlin#kotlinc#Handle(buffer, lines) abort
+ let l:code_pattern = '^\(.*\):\([0-9]\+\):\([0-9]\+\):\s\+\(error\|warning\):\s\+\(.*\)'
+ let l:general_pattern = '^\(warning\|error\|info\):\s*\(.*\)'
+ let l:output = []
+
+ for l:line in a:lines
+ let l:match = matchlist(l:line, l:code_pattern)
+
+ if len(l:match) == 0
+ continue
+ endif
+
+ let l:file = l:match[1]
+ let l:line = l:match[2] + 0
+ let l:column = l:match[3] + 0
+ let l:type = l:match[4]
+ let l:text = l:match[5]
+
+ let l:buf_abspath = fnamemodify(l:file, ':p')
+ let l:curbuf_abspath = expand('#' . a:buffer . ':p')
+
+ " Skip if file is not loaded
+ if l:buf_abspath isnot# l:curbuf_abspath
+ continue
+ endif
+ let l:type_marker_str = l:type is# 'warning' ? 'W' : 'E'
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'col': l:column,
+ \ 'text': l:text,
+ \ 'type': l:type_marker_str,
+ \})
+ endfor
+
+ " Non-code related messages
+ for l:line in a:lines
+ let l:match = matchlist(l:line, l:general_pattern)
+
+ if len(l:match) == 0
+ continue
+ endif
+
+ let l:type = l:match[1]
+ let l:text = l:match[2]
+
+ let l:type_marker_str = l:type is# 'warning' || l:type is# 'info' ? 'W' : 'E'
+
+ call add(l:output, {
+ \ 'lnum': 1,
+ \ 'text': l:text,
+ \ 'type': l:type_marker_str,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('kotlin', {
+\ 'name': 'kotlinc',
+\ 'executable': 'kotlinc',
+\ 'command_chain': [
+\ {'callback': 'ale_linters#kotlin#kotlinc#GetImportPaths', 'output_stream': 'stdout'},
+\ {'callback': 'ale_linters#kotlin#kotlinc#GetCommand', 'output_stream': 'stderr'},
+\ ],
+\ 'callback': 'ale_linters#kotlin#kotlinc#Handle',
+\ 'lint_file': 1,
+\})
+
diff --git a/vim/bundle/ale/ale_linters/kotlin/ktlint.vim b/vim/bundle/ale/ale_linters/kotlin/ktlint.vim
new file mode 100644
index 0000000..f474e84
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/kotlin/ktlint.vim
@@ -0,0 +1,54 @@
+" Author: Francis Agyapong
+" Description: Lint kotlin files using ktlint
+
+call ale#Set('kotlin_ktlint_executable', 'ktlint')
+call ale#Set('kotlin_ktlint_rulesets', [])
+call ale#Set('kotlin_ktlint_format', 0)
+
+
+function! ale_linters#kotlin#ktlint#GetCommand(buffer) abort
+ let l:executable = ale#Var(a:buffer, 'kotlin_ktlint_executable')
+ let l:file_path = expand('#' . a:buffer . ':p')
+ let l:options = ''
+
+ " Formmatted content written to original file, not sure how to handle
+ " if ale#Var(a:buffer, 'kotlin_ktlint_format')
+ " let l:options = l:options . ' --format'
+ " endif
+
+ for l:ruleset in ale#Var(a:buffer, 'kotlin_ktlint_rulesets')
+ let l:options = l:options . ' --ruleset ' . l:ruleset
+ endfor
+
+ return l:executable . ' ' . l:options . ' ' . l:file_path
+endfunction
+
+function! ale_linters#kotlin#ktlint#Handle(buffer, lines) abort
+ let l:message_pattern = '^\(.*\):\([0-9]\+\):\([0-9]\+\):\s\+\(.*\)'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:message_pattern)
+ let l:line = l:match[2] + 0
+ let l:column = l:match[3] + 0
+ let l:text = l:match[4]
+
+ let l:type = l:text =~? 'not a valid kotlin file' ? 'E' : 'W'
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'col': l:column,
+ \ 'text': l:text,
+ \ 'type': l:type
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('kotlin', {
+\ 'name': 'ktlint',
+\ 'executable': 'ktlint',
+\ 'command_callback': 'ale_linters#kotlin#ktlint#GetCommand',
+\ 'callback': 'ale_linters#kotlin#ktlint#Handle',
+\ 'lint_file': 1
+\})
diff --git a/vim/bundle/ale/ale_linters/lua/luacheck.vim b/vim/bundle/ale/ale_linters/lua/luacheck.vim
new file mode 100644
index 0000000..e15b730
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/lua/luacheck.vim
@@ -0,0 +1,45 @@
+" Author: Sol Bekic https://github.com/s-ol
+" Description: luacheck linter for lua files
+
+let g:ale_lua_luacheck_executable =
+\ get(g:, 'ale_lua_luacheck_executable', 'luacheck')
+
+let g:ale_lua_luacheck_options =
+\ get(g:, 'ale_lua_luacheck_options', '')
+
+function! ale_linters#lua#luacheck#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'lua_luacheck_executable')
+endfunction
+
+function! ale_linters#lua#luacheck#GetCommand(buffer) abort
+ return ale#Escape(ale_linters#lua#luacheck#GetExecutable(a:buffer))
+ \ . ' ' . ale#Var(a:buffer, 'lua_luacheck_options')
+ \ . ' --formatter plain --codes --filename %s -'
+endfunction
+
+function! ale_linters#lua#luacheck#Handle(buffer, lines) abort
+ " Matches patterns line the following:
+ "
+ " artal.lua:159:17: (W111) shadowing definition of loop variable 'i' on line 106
+ " artal.lua:182:7: (W213) unused loop variable 'i'
+ 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[3] . l:match[4] . ': ' . l:match[5],
+ \ 'type': l:match[3],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('lua', {
+\ 'name': 'luacheck',
+\ 'executable_callback': 'ale_linters#lua#luacheck#GetExecutable',
+\ 'command_callback': 'ale_linters#lua#luacheck#GetCommand',
+\ 'callback': 'ale_linters#lua#luacheck#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/markdown/mdl.vim b/vim/bundle/ale/ale_linters/markdown/mdl.vim
new file mode 100644
index 0000000..f239025
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/markdown/mdl.vim
@@ -0,0 +1,25 @@
+" Author: Steve Dignam
+" Description: Support for mdl, a markdown linter
+
+function! ale_linters#markdown#mdl#Handle(buffer, lines) abort
+ " matches: '(stdin):173: MD004 Unordered list style'
+ let l:pattern = ':\(\d*\): \(.*\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'text': l:match[2],
+ \ 'type': 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('markdown', {
+\ 'name': 'mdl',
+\ 'executable': 'mdl',
+\ 'command': 'mdl',
+\ 'callback': 'ale_linters#markdown#mdl#Handle'
+\})
diff --git a/vim/bundle/ale/ale_linters/markdown/proselint.vim b/vim/bundle/ale/ale_linters/markdown/proselint.vim
new file mode 100644
index 0000000..289d881
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/markdown/proselint.vim
@@ -0,0 +1,9 @@
+" Author: poohzrn https://github.com/poohzrn
+" Description: proselint for Markdown files
+
+call ale#linter#Define('markdown', {
+\ 'name': 'proselint',
+\ 'executable': 'proselint',
+\ 'command': 'proselint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/markdown/vale.vim b/vim/bundle/ale/ale_linters/markdown/vale.vim
new file mode 100644
index 0000000..43b3d34
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/markdown/vale.vim
@@ -0,0 +1,9 @@
+" Author: chew-z https://github.com/chew-z
+" Description: vale for Markdown files
+
+call ale#linter#Define('markdown', {
+\ 'name': 'vale',
+\ 'executable': 'vale',
+\ 'command': 'vale --output=line %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/matlab/mlint.vim b/vim/bundle/ale/ale_linters/matlab/mlint.vim
new file mode 100644
index 0000000..3276633
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/matlab/mlint.vim
@@ -0,0 +1,55 @@
+" Author: awlayton
+" Description: mlint for MATLAB files
+
+let g:ale_matlab_mlint_executable =
+\ get(g:, 'ale_matlab_mlint_executable', 'mlint')
+
+function! ale_linters#matlab#mlint#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'matlab_mlint_executable')
+endfunction
+
+function! ale_linters#matlab#mlint#GetCommand(buffer) abort
+ let l:executable = ale_linters#matlab#mlint#GetExecutable(a:buffer)
+
+ return l:executable . ' -id %t'
+endfunction
+
+function! ale_linters#matlab#mlint#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ "
+ " L 27 (C 1): FNDEF: Terminate statement with semicolon to suppress output.
+ " L 30 (C 13-15): FNDEF: A quoted string is unterminated.
+ let l:pattern = '^L \(\d\+\) (C \([0-9-]\+\)): \([A-Z]\+\): \(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:lnum = l:match[1] + 0
+ let l:col = l:match[2] + 0
+ let l:code = l:match[3]
+ let l:text = l:match[4]
+
+ " Suppress erroneous waring about filename
+ " TODO: Enable this error when copying filename is supported
+ if l:code is# 'FNDEF'
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': l:lnum,
+ \ 'col': l:col,
+ \ 'text': l:text,
+ \ 'type': 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('matlab', {
+\ 'name': 'mlint',
+\ 'executable_callback': 'ale_linters#matlab#mlint#GetExecutable',
+\ 'command_callback': 'ale_linters#matlab#mlint#GetCommand',
+\ 'output_stream': 'stderr',
+\ 'callback': 'ale_linters#matlab#mlint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/nim/nimcheck.vim b/vim/bundle/ale/ale_linters/nim/nimcheck.vim
new file mode 100644
index 0000000..cdd8c56
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/nim/nimcheck.vim
@@ -0,0 +1,58 @@
+" Author: Baabelfish
+" Description: Typechecking for nim files
+
+function! ale_linters#nim#nimcheck#Handle(buffer, lines) abort
+ let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p:t')
+ let l:pattern = '^\(.\+\.nim\)(\(\d\+\), \(\d\+\)) \(.\+\)'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ " Only show errors of the current buffer
+ " NOTE: Checking filename only is OK because nim enforces unique
+ " module names.
+
+ let l:temp_buffer_filename = fnamemodify(l:match[1], ':p:t')
+ if l:buffer_filename isnot# '' && l:temp_buffer_filename isnot# l:buffer_filename
+ continue
+ endif
+
+ let l:line = l:match[2] + 0
+ let l:column = l:match[3] + 0
+ let l:text = l:match[4]
+ let l:type = 'W'
+
+ " Extract error type from message of type 'Error: Some error message'
+ let l:textmatch = matchlist(l:match[4], '^\(.\{-}\): .\+$')
+
+ if len(l:textmatch) > 0
+ let l:errortype = l:textmatch[1]
+ if l:errortype is# 'Error'
+ let l:type = 'E'
+ endif
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'col': l:column,
+ \ 'text': l:text,
+ \ 'type': l:type,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+
+function! ale_linters#nim#nimcheck#GetCommand(buffer) abort
+ return 'nim check --verbosity:0 --colors:off --listFullPaths %s'
+endfunction
+
+
+call ale#linter#Define('nim', {
+\ 'name': 'nimcheck',
+\ 'executable': 'nim',
+\ 'output_stream': 'both',
+\ 'command_callback': 'ale_linters#nim#nimcheck#GetCommand',
+\ 'callback': 'ale_linters#nim#nimcheck#Handle',
+\ 'lint_file': 1,
+\})
diff --git a/vim/bundle/ale/ale_linters/nix/nix.vim b/vim/bundle/ale/ale_linters/nix/nix.vim
new file mode 100644
index 0000000..0a0c5c3
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/nix/nix.vim
@@ -0,0 +1,26 @@
+" Author: Alistair Bill <@alibabzo>
+" Description: nix-instantiate linter for nix files
+
+function! ale_linters#nix#nix#Handle(buffer, lines) abort
+ let l:pattern = '^\(.\+\): \(.\+\), at .*:\(\d\+\):\(\d\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[3] + 0,
+ \ 'col': l:match[4] + 0,
+ \ 'text': l:match[1] . ': ' . l:match[2],
+ \ 'type': l:match[1] =~# '^error' ? 'E' : 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('nix', {
+\ 'name': 'nix',
+\ 'output_stream': 'stderr',
+\ 'executable': 'nix-instantiate',
+\ 'command': 'nix-instantiate --parse -',
+\ 'callback': 'ale_linters#nix#nix#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/nroff/proselint.vim b/vim/bundle/ale/ale_linters/nroff/proselint.vim
new file mode 100644
index 0000000..a23e56b
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/nroff/proselint.vim
@@ -0,0 +1,9 @@
+" Author: Daniel M. Capella https://github.com/polyzen
+" Description: proselint for nroff files
+
+call ale#linter#Define('nroff', {
+\ 'name': 'proselint',
+\ 'executable': 'proselint',
+\ 'command': 'proselint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/objc/clang.vim b/vim/bundle/ale/ale_linters/objc/clang.vim
new file mode 100644
index 0000000..f4725a0
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/objc/clang.vim
@@ -0,0 +1,23 @@
+" Author: Bang Lee
+" Description: clang linter for objc files
+
+" Set this option to change the Clang options for warnings for ObjC.
+if !exists('g:ale_objc_clang_options')
+ let g:ale_objc_clang_options = '-std=c11 -Wall'
+endif
+
+function! ale_linters#objc#clang#GetCommand(buffer) abort
+ " -iquote with the directory the file is in makes #include work for
+ " headers in the same directory.
+ return 'clang -S -x objective-c -fsyntax-only '
+ \ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
+ \ . ' ' . ale#Var(a:buffer, 'objc_clang_options') . ' -'
+endfunction
+
+call ale#linter#Define('objc', {
+\ 'name': 'clang',
+\ 'output_stream': 'stderr',
+\ 'executable': 'clang',
+\ 'command_callback': 'ale_linters#objc#clang#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/objcpp/clang.vim b/vim/bundle/ale/ale_linters/objcpp/clang.vim
new file mode 100644
index 0000000..0e9cefe
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/objcpp/clang.vim
@@ -0,0 +1,23 @@
+" Author: Bang Lee
+" Description: clang linter for objcpp files
+
+" Set this option to change the Clang options for warnings for ObjCPP.
+if !exists('g:ale_objcpp_clang_options')
+ let g:ale_objcpp_clang_options = '-std=c++14 -Wall'
+endif
+
+function! ale_linters#objcpp#clang#GetCommand(buffer) abort
+ " -iquote with the directory the file is in makes #include work for
+ " headers in the same directory.
+ return 'clang++ -S -x objective-c++ -fsyntax-only '
+ \ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
+ \ . ' ' . ale#Var(a:buffer, 'objcpp_clang_options') . ' -'
+endfunction
+
+call ale#linter#Define('objcpp', {
+\ 'name': 'clang',
+\ 'output_stream': 'stderr',
+\ 'executable': 'clang++',
+\ 'command_callback': 'ale_linters#objcpp#clang#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/ocaml/merlin.vim b/vim/bundle/ale/ale_linters/ocaml/merlin.vim
new file mode 100644
index 0000000..cfec996
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/ocaml/merlin.vim
@@ -0,0 +1,17 @@
+" Author: Andrey Popp -- @andreypopp
+" Description: Report errors in OCaml code with Merlin
+
+if !exists('g:merlin')
+ finish
+endif
+
+function! ale_linters#ocaml#merlin#Handle(buffer, lines) abort
+ return merlin#ErrorLocList()
+endfunction
+
+call ale#linter#Define('ocaml', {
+\ 'name': 'merlin',
+\ 'executable': 'ocamlmerlin',
+\ 'command': 'true',
+\ 'callback': 'ale_linters#ocaml#merlin#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/perl/perl.vim b/vim/bundle/ale/ale_linters/perl/perl.vim
new file mode 100644
index 0000000..3328806
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/perl/perl.vim
@@ -0,0 +1,58 @@
+" Author: Vincent Lequertier
+" Description: This file adds support for checking perl syntax
+
+let g:ale_perl_perl_executable =
+\ get(g:, 'ale_perl_perl_executable', 'perl')
+
+let g:ale_perl_perl_options =
+\ get(g:, 'ale_perl_perl_options', '-c -Mwarnings -Ilib')
+
+function! ale_linters#perl#perl#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'perl_perl_executable')
+endfunction
+
+function! ale_linters#perl#perl#GetCommand(buffer) abort
+ return ale_linters#perl#perl#GetExecutable(a:buffer)
+ \ . ' ' . ale#Var(a:buffer, 'perl_perl_options')
+ \ . ' %t'
+endfunction
+
+let s:begin_failed_skip_pattern = '\v' . join([
+\ '^Compilation failed in require',
+\ '^Can''t locate',
+\], '|')
+
+function! ale_linters#perl#perl#Handle(buffer, lines) abort
+ let l:pattern = '\(.\+\) at \(.\+\) line \(\d\+\)'
+ let l:output = []
+ let l:basename = expand('#' . a:buffer . ':t')
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:line = l:match[3]
+ let l:text = l:match[1]
+ let l:type = 'E'
+
+ if ale#path#IsBufferPath(a:buffer, l:match[2])
+ \ && (
+ \ l:text isnot# 'BEGIN failed--compilation aborted'
+ \ || empty(l:output)
+ \ || match(l:output[-1].text, s:begin_failed_skip_pattern) < 0
+ \ )
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'text': l:text,
+ \ 'type': l:type,
+ \})
+ endif
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('perl', {
+\ 'name': 'perl',
+\ 'executable_callback': 'ale_linters#perl#perl#GetExecutable',
+\ 'output_stream': 'both',
+\ 'command_callback': 'ale_linters#perl#perl#GetCommand',
+\ 'callback': 'ale_linters#perl#perl#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/perl/perlcritic.vim b/vim/bundle/ale/ale_linters/perl/perlcritic.vim
new file mode 100644
index 0000000..df2f8b2
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/perl/perlcritic.vim
@@ -0,0 +1,76 @@
+" Author: Vincent Lequertier , Chris Weyl
+" Description: This file adds support for checking perl with perl critic
+
+let g:ale_perl_perlcritic_executable =
+\ get(g:, 'ale_perl_perlcritic_executable', 'perlcritic')
+
+let g:ale_perl_perlcritic_profile =
+\ get(g:, 'ale_perl_perlcritic_profile', '.perlcriticrc')
+
+let g:ale_perl_perlcritic_options =
+\ get(g:, 'ale_perl_perlcritic_options', '')
+
+let g:ale_perl_perlcritic_showrules =
+\ get(g:, 'ale_perl_perlcritic_showrules', 0)
+
+function! ale_linters#perl#perlcritic#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'perl_perlcritic_executable')
+endfunction
+
+function! ale_linters#perl#perlcritic#GetProfile(buffer) abort
+
+ " first see if we've been overridden
+ let l:profile = ale#Var(a:buffer, 'perl_perlcritic_profile')
+ if l:profile is? ''
+ return ''
+ endif
+
+ " otherwise, iterate upwards to find it
+ return ale#path#FindNearestFile(a:buffer, l:profile)
+endfunction
+
+function! ale_linters#perl#perlcritic#GetCommand(buffer) abort
+ let l:critic_verbosity = '%l:%c %m\n'
+ if ale#Var(a:buffer, 'perl_perlcritic_showrules')
+ let l:critic_verbosity = '%l:%c %m [%p]\n'
+ endif
+
+ let l:profile = ale_linters#perl#perlcritic#GetProfile(a:buffer)
+ let l:options = ale#Var(a:buffer, 'perl_perlcritic_options')
+
+ let l:command = ale#Escape(ale_linters#perl#perlcritic#GetExecutable(a:buffer))
+ \ . " --verbose '". l:critic_verbosity . "' --nocolor"
+
+ if l:profile isnot? ''
+ let l:command .= ' --profile ' . ale#Escape(l:profile)
+ endif
+ if l:options isnot? ''
+ let l:command .= ' ' . l:options
+ endif
+
+ return l:command
+endfunction
+
+
+function! ale_linters#perl#perlcritic#Handle(buffer, lines) abort
+ let l:pattern = '\(\d\+\):\(\d\+\) \(.\+\)'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[1],
+ \ 'col': l:match[2],
+ \ 'text': l:match[3],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('perl', {
+\ 'name': 'perlcritic',
+\ 'output_stream': 'stdout',
+\ 'executable_callback': 'ale_linters#perl#perlcritic#GetExecutable',
+\ 'command_callback': 'ale_linters#perl#perlcritic#GetCommand',
+\ 'callback': 'ale_linters#perl#perlcritic#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/php/hack.vim b/vim/bundle/ale/ale_linters/php/hack.vim
new file mode 100644
index 0000000..77d3a58
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/php/hack.vim
@@ -0,0 +1,28 @@
+" Author: Zefei Xuan
+" Description: Hack type checking (http://hacklang.org/)
+
+function! ale_linters#php#hack#Handle(buffer, lines) abort
+ let l:pattern = '^\(.*\):\(\d\+\):\(\d\+\),\(\d\+\): \(.\+])\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ if a:buffer != bufnr(l:match[1])
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:match[2] + 0,
+ \ 'col': l:match[3] + 0,
+ \ 'text': l:match[5],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('php', {
+\ 'name': 'hack',
+\ 'executable': 'hh_client',
+\ 'command': 'hh_client --retries 0 --retry-if-init false',
+\ 'callback': 'ale_linters#php#hack#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/php/langserver.vim b/vim/bundle/ale/ale_linters/php/langserver.vim
new file mode 100644
index 0000000..be2d6ef
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/php/langserver.vim
@@ -0,0 +1,34 @@
+" Author: Eric Stern
+" Description: PHP Language server integration for ALE
+
+call ale#Set('php_langserver_executable', 'php-language-server.php')
+call ale#Set('php_langserver_use_global', 0)
+
+function! ale_linters#php#langserver#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'php_langserver', [
+ \ 'vendor/bin/php-language-server.php',
+ \])
+endfunction
+
+function! ale_linters#php#langserver#GetCommand(buffer) abort
+ return 'php ' . ale#Escape(ale_linters#php#langserver#GetExecutable(a:buffer))
+endfunction
+
+function! ale_linters#php#langserver#GetLanguage(buffer) abort
+ return 'php'
+endfunction
+
+function! ale_linters#php#langserver#GetProjectRoot(buffer) abort
+ let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
+
+ return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
+endfunction
+
+call ale#linter#Define('php', {
+\ 'name': 'langserver',
+\ 'lsp': 'stdio',
+\ 'executable_callback': 'ale_linters#php#langserver#GetExecutable',
+\ 'command_callback': 'ale_linters#php#langserver#GetCommand',
+\ 'language_callback': 'ale_linters#php#langserver#GetLanguage',
+\ 'project_root_callback': 'ale_linters#php#langserver#GetProjectRoot',
+\})
diff --git a/vim/bundle/ale/ale_linters/php/php.vim b/vim/bundle/ale/ale_linters/php/php.vim
new file mode 100644
index 0000000..7158c95
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/php/php.vim
@@ -0,0 +1,35 @@
+" Author: Spencer Wood , Adriaan Zonnenberg
+" Description: This file adds support for checking PHP with php-cli
+
+function! ale_linters#php#php#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ "
+ " Parse error: syntax error, unexpected ';', expecting ']' in - on line 15
+ let l:pattern = '\v^%(Fatal|Parse) error:\s+(.+unexpected ''(.+)%(expecting.+)@, Eric Stern
+" Description: phpcs for PHP files
+
+let g:ale_php_phpcs_standard = get(g:, 'ale_php_phpcs_standard', '')
+
+call ale#Set('php_phpcs_executable', 'phpcs')
+call ale#Set('php_phpcs_use_global', 0)
+
+function! ale_linters#php#phpcs#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'php_phpcs', [
+ \ 'vendor/bin/phpcs',
+ \ 'phpcs'
+ \])
+endfunction
+
+function! ale_linters#php#phpcs#GetCommand(buffer) abort
+ let l:executable = ale_linters#php#phpcs#GetExecutable(a:buffer)
+
+ let l:standard = ale#Var(a:buffer, 'php_phpcs_standard')
+ let l:standard_option = !empty(l:standard)
+ \ ? '--standard=' . l:standard
+ \ : ''
+
+ return ale#Escape(l:executable)
+ \ . ' -s --report=emacs --stdin-path=%s ' . l:standard_option
+endfunction
+
+function! ale_linters#php#phpcs#Handle(buffer, lines) abort
+ " Matches against lines like the following:
+ "
+ " /path/to/some-filename.php:18:3: error - Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)
+ let l:pattern = '^.*:\(\d\+\):\(\d\+\): \(.\+\) - \(.\+\) \(\(.\+\)\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:text = l:match[4]
+ let l:type = l:match[3]
+
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 0,
+ \ 'text': l:text,
+ \ 'type': l:type is# 'error' ? 'E' : 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('php', {
+\ 'name': 'phpcs',
+\ 'executable_callback': 'ale_linters#php#phpcs#GetExecutable',
+\ 'command_callback': 'ale_linters#php#phpcs#GetCommand',
+\ 'callback': 'ale_linters#php#phpcs#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/php/phpmd.vim b/vim/bundle/ale/ale_linters/php/phpmd.vim
new file mode 100644
index 0000000..29d8103
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/php/phpmd.vim
@@ -0,0 +1,36 @@
+" Author: medains
+" Description: phpmd for PHP files
+
+" Set to change the ruleset
+let g:ale_php_phpmd_ruleset = get(g:, 'ale_php_phpmd_ruleset', 'cleancode,codesize,controversial,design,naming,unusedcode')
+
+function! ale_linters#php#phpmd#GetCommand(buffer) abort
+ return 'phpmd %s text '
+ \ . ale#Var(a:buffer, 'php_phpmd_ruleset')
+ \ . ' --ignore-violations-on-exit %t'
+endfunction
+
+function! ale_linters#php#phpmd#Handle(buffer, lines) abort
+ " Matches against lines like the following:
+ "
+ " /path/to/some-filename.php:18 message
+ let l:pattern = '^.*:\(\d\+\)\t\(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'text': l:match[2],
+ \ 'type': 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('php', {
+\ 'name': 'phpmd',
+\ 'executable': 'phpmd',
+\ 'command_callback': 'ale_linters#php#phpmd#GetCommand',
+\ 'callback': 'ale_linters#php#phpmd#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/php/phpstan.vim b/vim/bundle/ale/ale_linters/php/phpstan.vim
new file mode 100644
index 0000000..b99e4f5
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/php/phpstan.vim
@@ -0,0 +1,46 @@
+" Author: medains , ardis
+" Description: phpstan for PHP files
+
+" Set to change the ruleset
+let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan')
+let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4')
+
+function! ale_linters#php#phpstan#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'php_phpstan_executable')
+endfunction
+
+function! ale_linters#php#phpstan#GetCommand(buffer) abort
+ let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer)
+
+ return ale#Escape(l:executable)
+ \ . ' analyze -l'
+ \ . ale#Var(a:buffer, 'php_phpstan_level')
+ \ . ' --errorFormat raw'
+ \ . ' %s'
+endfunction
+
+function! ale_linters#php#phpstan#Handle(buffer, lines) abort
+ " Matches against lines like the following:
+ "
+ " filename.php:15:message
+ " C:\folder\filename.php:15:message
+ let l:pattern = '^\([a-zA-Z]:\)\?[^:]\+:\(\d\+\):\(.*\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[2] + 0,
+ \ 'text': l:match[3],
+ \ 'type': 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('php', {
+\ 'name': 'phpstan',
+\ 'executable_callback': 'ale_linters#php#phpstan#GetExecutable',
+\ 'command_callback': 'ale_linters#php#phpstan#GetCommand',
+\ 'callback': 'ale_linters#php#phpstan#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/pod/proselint.vim b/vim/bundle/ale/ale_linters/pod/proselint.vim
new file mode 100644
index 0000000..2eb83f5
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/pod/proselint.vim
@@ -0,0 +1,9 @@
+" Author: Daniel M. Capella https://github.com/polyzen
+" Description: proselint for Pod files
+
+call ale#linter#Define('pod', {
+\ 'name': 'proselint',
+\ 'executable': 'proselint',
+\ 'command': 'proselint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/pug/puglint.vim b/vim/bundle/ale/ale_linters/pug/puglint.vim
new file mode 100644
index 0000000..6c29efe
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/pug/puglint.vim
@@ -0,0 +1,48 @@
+" Author: w0rp -
+" Description: pug-lint for checking Pug/Jade files.
+
+call ale#Set('pug_puglint_options', '')
+call ale#Set('pug_puglint_executable', 'pug-lint')
+call ale#Set('pug_puglint_use_global', 0)
+
+function! ale_linters#pug#puglint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'pug_puglint', [
+ \ 'node_modules/.bin/pug-lint',
+ \])
+endfunction
+
+function! s:FindConfig(buffer) abort
+ for l:filename in [
+ \ '.pug-lintrc',
+ \ '.pug-lintrc.js',
+ \ '.pug-lintrc.json',
+ \ 'package.json',
+ \]
+ let l:config = ale#path#FindNearestFile(a:buffer, l:filename)
+
+ if !empty(l:config)
+ return l:config
+ endif
+ endfor
+
+ return ''
+endfunction
+
+function! ale_linters#pug#puglint#GetCommand(buffer) abort
+ let l:executable = ale_linters#pug#puglint#GetExecutable(a:buffer)
+ let l:options = ale#Var(a:buffer, 'pug_puglint_options')
+ let l:config = s:FindConfig(a:buffer)
+
+ return ale#Escape(l:executable)
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
+ \ . ' -r inline %t'
+endfunction
+
+call ale#linter#Define('pug', {
+\ 'name': 'puglint',
+\ 'executable_callback': 'ale_linters#pug#puglint#GetExecutable',
+\ 'output_stream': 'stderr',
+\ 'command_callback': 'ale_linters#pug#puglint#GetCommand',
+\ 'callback': 'ale#handlers#unix#HandleAsError',
+\})
diff --git a/vim/bundle/ale/ale_linters/puppet/puppet.vim b/vim/bundle/ale/ale_linters/puppet/puppet.vim
new file mode 100644
index 0000000..47e89d3
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/puppet/puppet.vim
@@ -0,0 +1,27 @@
+" Author: Alexander Olofsson
+
+function! ale_linters#puppet#puppet#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ " Error: Could not parse for environment production: Syntax error at ':' at /root/puppetcode/modules/nginx/manifests/init.pp:43:12
+
+ let l:pattern = '^Error: .*: \(.\+\) at .\+:\(\d\+\):\(\d\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[2] + 0,
+ \ 'col': l:match[3] + 0,
+ \ 'text': l:match[1],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('puppet', {
+\ 'name': 'puppet',
+\ 'executable': 'puppet',
+\ 'output_stream': 'stderr',
+\ 'command': 'puppet parser validate --color=false %t',
+\ 'callback': 'ale_linters#puppet#puppet#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/puppet/puppetlint.vim b/vim/bundle/ale/ale_linters/puppet/puppetlint.vim
new file mode 100644
index 0000000..13da511
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/puppet/puppetlint.vim
@@ -0,0 +1,26 @@
+" Author: Alexander Olofsson , Robert Flechtner
+" Description: puppet-lint for puppet files
+
+let g:ale_puppet_puppetlint_executable =
+\ get(g:, 'ale_puppet_puppetlint_executable', 'puppet-lint')
+
+let g:ale_puppet_puppetlint_options =
+\ get(g:, 'ale_puppet_puppetlint_options', '--no-autoloader_layout-check')
+
+function! ale_linters#puppet#puppetlint#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'puppet_puppetlint_executable')
+endfunction
+
+function! ale_linters#puppet#puppetlint#GetCommand(buffer) abort
+ return ale_linters#puppet#puppetlint#GetExecutable(a:buffer)
+ \ . ' ' . ale#Var(a:buffer, 'puppet_puppetlint_options')
+ \ . ' --log-format "-:%{line}:%{column}: %{kind}: [%{check}] %{message}"'
+ \ . ' %t'
+endfunction
+
+call ale#linter#Define('puppet', {
+\ 'name': 'puppetlint',
+\ 'executable_callback': 'ale_linters#puppet#puppetlint#GetExecutable',
+\ 'command_callback': 'ale_linters#puppet#puppetlint#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/pyrex/cython.vim b/vim/bundle/ale/ale_linters/pyrex/cython.vim
new file mode 100644
index 0000000..bd5a447
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/pyrex/cython.vim
@@ -0,0 +1,10 @@
+" Author: w0rp
+" Description: cython syntax checking for cython files.
+
+call ale#linter#Define('pyrex', {
+\ 'name': 'cython',
+\ 'output_stream': 'stderr',
+\ 'executable': 'cython',
+\ 'command': 'cython --warning-extra -o ' . g:ale#util#nul_file . ' %t',
+\ 'callback': 'ale#handlers#unix#HandleAsError',
+\})
diff --git a/vim/bundle/ale/ale_linters/python/flake8.vim b/vim/bundle/ale/ale_linters/python/flake8.vim
new file mode 100644
index 0000000..8aa4c4d
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/python/flake8.vim
@@ -0,0 +1,165 @@
+" Author: w0rp
+" Description: flake8 for python files
+
+let g:ale_python_flake8_executable =
+\ get(g:, 'ale_python_flake8_executable', 'flake8')
+
+" Support an old setting as a fallback.
+let s:default_options = get(g:, 'ale_python_flake8_args', '')
+let g:ale_python_flake8_options =
+\ get(g:, 'ale_python_flake8_options', s:default_options)
+let g:ale_python_flake8_use_global = get(g:, 'ale_python_flake8_use_global', 0)
+
+" A map from Python executable paths to semver strings parsed for those
+" executables, so we don't have to look up the version number constantly.
+let s:version_cache = {}
+
+function! s:UsingModule(buffer) abort
+ return ale#Var(a:buffer, 'python_flake8_options') =~# ' *-m flake8'
+endfunction
+
+function! ale_linters#python#flake8#GetExecutable(buffer) abort
+ if !s:UsingModule(a:buffer)
+ return ale#python#FindExecutable(a:buffer, 'python_flake8', ['flake8'])
+ endif
+
+ return ale#Var(a:buffer, 'python_flake8_executable')
+endfunction
+
+function! ale_linters#python#flake8#ClearVersionCache() abort
+ let s:version_cache = {}
+endfunction
+
+function! ale_linters#python#flake8#VersionCheck(buffer) abort
+ let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
+
+ " If we have previously stored the version number in a cache, then
+ " don't look it up again.
+ if has_key(s:version_cache, l:executable)
+ " Returning an empty string skips this command.
+ return ''
+ endif
+
+ let l:executable = ale#Escape(ale_linters#python#flake8#GetExecutable(a:buffer))
+ let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : ''
+
+ return l:executable . l:module_string . ' --version'
+endfunction
+
+" Get the flake8 version from the output, or the cache.
+function! s:GetVersion(buffer, version_output) abort
+ let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
+ let l:version = []
+
+ " Get the version from the cache.
+ if has_key(s:version_cache, l:executable)
+ return s:version_cache[l:executable]
+ endif
+
+ if !empty(a:version_output)
+ " Parse the version string, and store it in the cache.
+ let l:version = ale#semver#Parse(a:version_output[0])
+ let s:version_cache[l:executable] = l:version
+ endif
+
+ return l:version
+endfunction
+
+" flake8 versions 3 and up support the --stdin-display-name argument.
+function! s:SupportsDisplayName(version) abort
+ return !empty(a:version) && ale#semver#GreaterOrEqual(a:version, [3, 0, 0])
+endfunction
+
+function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
+ let l:version = s:GetVersion(a:buffer, a:version_output)
+
+ " Only include the --stdin-display-name argument if we can parse the
+ " flake8 version, and it is recent enough to support it.
+ let l:display_name_args = s:SupportsDisplayName(l:version)
+ \ ? ' --stdin-display-name %s'
+ \ : ''
+
+ let l:options = ale#Var(a:buffer, 'python_flake8_options')
+
+ return ale#Escape(ale_linters#python#flake8#GetExecutable(a:buffer))
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . ' --format=default'
+ \ . l:display_name_args . ' -'
+endfunction
+
+let s:end_col_pattern_map = {
+\ 'F405': '\(.\+\) may be undefined',
+\ 'F821': 'undefined name ''\([^'']\+\)''',
+\ 'F999': '^''\([^'']\+\)''',
+\ 'F841': 'local variable ''\([^'']\+\)''',
+\}
+
+function! ale_linters#python#flake8#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:
+ "
+ " Matches patterns line the following:
+ "
+ " stdin:6:6: E111 indentation is not a multiple of four
+ 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[3]
+
+ if (l:code is# 'W291' || l:code is# 'W293')
+ \ && !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
+ " Skip warnings for trailing whitespace if the option is off.
+ continue
+ endif
+
+ let l:item = {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 0,
+ \ 'text': l:code . ': ' . l:match[4],
+ \ 'type': 'W',
+ \}
+
+ if l:code[:0] is# 'F' || l:code is# 'E999'
+ let l:item.type = 'E'
+ elseif l:code[:0] is# 'E'
+ let l:item.type = 'E'
+ let l:item.sub_type = 'style'
+ elseif l:code[:0] is# 'W'
+ let l:item.sub_type = 'style'
+ endif
+
+ let l:end_col_pattern = get(s:end_col_pattern_map, l:code, '')
+
+ if !empty(l:end_col_pattern)
+ let l:end_col_match = matchlist(l:match[4], l:end_col_pattern)
+
+ if !empty(l:end_col_match)
+ let l:item.end_col = l:item.col + len(l:end_col_match[1]) - 1
+ endif
+ endif
+
+ call add(l:output, l:item)
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('python', {
+\ 'name': 'flake8',
+\ 'executable_callback': 'ale_linters#python#flake8#GetExecutable',
+\ 'command_chain': [
+\ {'callback': 'ale_linters#python#flake8#VersionCheck'},
+\ {'callback': 'ale_linters#python#flake8#GetCommand', 'output_stream': 'both'},
+\ ],
+\ 'callback': 'ale_linters#python#flake8#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/python/mypy.vim b/vim/bundle/ale/ale_linters/python/mypy.vim
new file mode 100644
index 0000000..6884a9a
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/python/mypy.vim
@@ -0,0 +1,65 @@
+" Author: Keith Smiley , w0rp
+" Description: mypy support for optional python typechecking
+
+let g:ale_python_mypy_executable =
+\ get(g:, 'ale_python_mypy_executable', 'mypy')
+let g:ale_python_mypy_options = get(g:, 'ale_python_mypy_options', '')
+let g:ale_python_mypy_use_global = get(g:, 'ale_python_mypy_use_global', 0)
+
+function! ale_linters#python#mypy#GetExecutable(buffer) abort
+ return ale#python#FindExecutable(a:buffer, 'python_mypy', ['mypy'])
+endfunction
+
+" The directory to change to before running mypy
+function! s:GetDir(buffer) abort
+ let l:project_root = ale#python#FindProjectRoot(a:buffer)
+
+ return !empty(l:project_root)
+ \ ? l:project_root
+ \ : expand('#' . a:buffer . ':p:h')
+endfunction
+
+function! ale_linters#python#mypy#GetCommand(buffer) abort
+ let l:dir = s:GetDir(a:buffer)
+ let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer)
+
+ " We have to always switch to an explicit directory for a command so
+ " we can know with certainty the base path for the 'filename' keys below.
+ return ale#path#CdString(l:dir)
+ \ . ale#Escape(l:executable)
+ \ . ' --show-column-numbers '
+ \ . ale#Var(a:buffer, 'python_mypy_options')
+ \ . ' --shadow-file %s %t %s'
+endfunction
+
+function! ale_linters#python#mypy#Handle(buffer, lines) abort
+ let l:dir = s:GetDir(a:buffer)
+ " Look for lines like the following:
+ "
+ " file.py:4: error: No library stub file for module 'django.db'
+ "
+ " Lines like these should be ignored below:
+ "
+ " file.py:4: note: (Stub files are from https://github.com/python/typeshed)
+ let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: (error|warning): (.+)$'
+ let l:output = []
+
+ 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',
+ \ 'text': l:match[5],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('python', {
+\ 'name': 'mypy',
+\ 'executable_callback': 'ale_linters#python#mypy#GetExecutable',
+\ 'command_callback': 'ale_linters#python#mypy#GetCommand',
+\ 'callback': 'ale_linters#python#mypy#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/python/pycodestyle.vim b/vim/bundle/ale/ale_linters/python/pycodestyle.vim
new file mode 100644
index 0000000..ad89599
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/python/pycodestyle.vim
@@ -0,0 +1,42 @@
+" Author: Michael Thiesen
+" Description: pycodestyle linting for python files
+
+call ale#Set('python_pycodestyle_executable', 'pycodestyle')
+call ale#Set('python_pycodestyle_options', '')
+call ale#Set('python_pycodestyle_use_global', 0)
+
+function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort
+ return ale#python#FindExecutable(a:buffer, 'python_pycodestyle', ['pycodestyle'])
+endfunction
+
+function! ale_linters#python#pycodestyle#GetCommand(buffer) abort
+ return ale#Escape(ale_linters#python#pycodestyle#GetExecutable(a:buffer))
+ \ . ' '
+ \ . ale#Var(a:buffer, 'python_pycodestyle_options')
+ \ . ' -'
+endfunction
+
+function! ale_linters#python#pycodestyle#Handle(buffer, lines) abort
+ let l:pattern = '\v^(\S*):(\d*):(\d*): ((([EW])\d+) .*)$'
+ let l:output = []
+
+ " lines are formatted as follows:
+ " file.py:21:26: W291 trailing whitespace
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[2] + 0,
+ \ 'col': l:match[3] + 0,
+ \ 'type': l:match[6],
+ \ 'text': l:match[4],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('python', {
+\ 'name': 'pycodestyle',
+\ 'executable_callback': 'ale_linters#python#pycodestyle#GetExecutable',
+\ 'command_callback': 'ale_linters#python#pycodestyle#GetCommand',
+\ 'callback': 'ale_linters#python#pycodestyle#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/python/pylint.vim b/vim/bundle/ale/ale_linters/python/pylint.vim
new file mode 100644
index 0000000..befc51a
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/python/pylint.vim
@@ -0,0 +1,62 @@
+" Author: keith
+" Description: pylint for python files
+
+let g:ale_python_pylint_executable =
+\ get(g:, 'ale_python_pylint_executable', 'pylint')
+
+let g:ale_python_pylint_options =
+\ get(g:, 'ale_python_pylint_options', '')
+
+let g:ale_python_pylint_use_global = get(g:, 'ale_python_pylint_use_global', 0)
+
+function! ale_linters#python#pylint#GetExecutable(buffer) abort
+ return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint'])
+endfunction
+
+function! ale_linters#python#pylint#GetCommand(buffer) abort
+ return ale#Escape(ale_linters#python#pylint#GetExecutable(a:buffer))
+ \ . ' ' . ale#Var(a:buffer, 'python_pylint_options')
+ \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n'
+ \ . ' %s'
+endfunction
+
+function! ale_linters#python#pylint#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ "
+ " test.py:4:4: W0101 (unreachable) Unreachable code
+ let l:pattern = '\v^[^:]+:(\d+):(\d+): ([[:alnum:]]+) \(([^(]*)\) (.*)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ "let l:failed = append(0, l:match)
+ let l:code = l:match[3]
+
+ if (l:code is# 'C0303')
+ \ && !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
+ " Skip warnings for trailing whitespace if the option is off.
+ continue
+ endif
+
+ if l:code is# 'I0011'
+ " Skip 'Locally disabling' message
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 1,
+ \ 'text': l:code . ': ' . l:match[5] . ' (' . l:match[4] . ')',
+ \ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('python', {
+\ 'name': 'pylint',
+\ 'executable_callback': 'ale_linters#python#pylint#GetExecutable',
+\ 'command_callback': 'ale_linters#python#pylint#GetCommand',
+\ 'callback': 'ale_linters#python#pylint#Handle',
+\ 'lint_file': 1,
+\})
diff --git a/vim/bundle/ale/ale_linters/r/lintr.vim b/vim/bundle/ale/ale_linters/r/lintr.vim
new file mode 100644
index 0000000..9375b8a
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/r/lintr.vim
@@ -0,0 +1,15 @@
+" Author: Michel Lang , w0rp
+" Description: This file adds support for checking R code with lintr.
+
+function! ale_linters#r#lintr#GetCommand(buffer) abort
+ return ale#path#BufferCdString(a:buffer)
+ \ . 'Rscript -e ' . ale#Escape('lintr::lint(commandArgs(TRUE))') . ' %t'
+endfunction
+
+call ale#linter#Define('r', {
+\ 'name': 'lintr',
+\ 'executable': 'Rscript',
+\ 'command_callback': 'ale_linters#r#lintr#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\ 'output_stream': 'both',
+\})
diff --git a/vim/bundle/ale/ale_linters/reason/merlin.vim b/vim/bundle/ale/ale_linters/reason/merlin.vim
new file mode 100644
index 0000000..7bef7df
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/reason/merlin.vim
@@ -0,0 +1,17 @@
+" Author: Andrey Popp -- @andreypopp
+" Description: Report errors in ReasonML code with Merlin
+
+if !exists('g:merlin')
+ finish
+endif
+
+function! ale_linters#reason#merlin#Handle(buffer, lines) abort
+ return merlin#ErrorLocList()
+endfunction
+
+call ale#linter#Define('reason', {
+\ 'name': 'merlin',
+\ 'executable': 'ocamlmerlin',
+\ 'command': 'true',
+\ 'callback': 'ale_linters#reason#merlin#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/rst/proselint.vim b/vim/bundle/ale/ale_linters/rst/proselint.vim
new file mode 100644
index 0000000..018347a
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/rst/proselint.vim
@@ -0,0 +1,9 @@
+" Author: Daniel M. Capella https://github.com/polyzen
+" Description: proselint for reStructuredText files
+
+call ale#linter#Define('rst', {
+\ 'name': 'proselint',
+\ 'executable': 'proselint',
+\ 'command': 'proselint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/ruby/brakeman.vim b/vim/bundle/ale/ale_linters/ruby/brakeman.vim
new file mode 100644
index 0000000..790eb56
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/ruby/brakeman.vim
@@ -0,0 +1,51 @@
+" Author: Eddie Lebow https://github.com/elebow
+" Description: Brakeman, a static analyzer for Rails security
+
+let g:ale_ruby_brakeman_options =
+\ get(g:, 'ale_ruby_brakeman_options', '')
+
+function! ale_linters#ruby#brakeman#Handle(buffer, lines) abort
+ let l:output = []
+ let l:json = ale#util#FuzzyJSONDecode(a:lines, {})
+
+ for l:warning in get(l:json, 'warnings', [])
+ " Brakeman always outputs paths relative to the Rails app root
+ let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
+ let l:warning_file = l:rails_root . '/' . l:warning.file
+
+ if !ale#path#IsBufferPath(a:buffer, l:warning_file)
+ continue
+ endif
+
+ let l:text = l:warning.warning_type . ' ' . l:warning.message . ' (' . l:warning.confidence . ')'
+ let l:line = l:warning.line != v:null ? l:warning.line : 1
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'type': 'W',
+ \ 'text': l:text,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+function! ale_linters#ruby#brakeman#GetCommand(buffer) abort
+ let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
+
+ if l:rails_root is? ''
+ return ''
+ endif
+
+ return 'brakeman -f json -q '
+ \ . ale#Var(a:buffer, 'ruby_brakeman_options')
+ \ . ' -p ' . ale#Escape(l:rails_root)
+endfunction
+
+call ale#linter#Define('ruby', {
+\ 'name': 'brakeman',
+\ 'executable': 'brakeman',
+\ 'command_callback': 'ale_linters#ruby#brakeman#GetCommand',
+\ 'callback': 'ale_linters#ruby#brakeman#Handle',
+\ 'lint_file': 1,
+\})
diff --git a/vim/bundle/ale/ale_linters/ruby/rails_best_practices.vim b/vim/bundle/ale/ale_linters/ruby/rails_best_practices.vim
new file mode 100644
index 0000000..107753c
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/ruby/rails_best_practices.vim
@@ -0,0 +1,53 @@
+" Author: Eddie Lebow https://github.com/elebow
+" Description: rails_best_practices, a code metric tool for rails projects
+
+let g:ale_ruby_rails_best_practices_options =
+\ get(g:, 'ale_ruby_rails_best_practices_options', '')
+
+function! ale_linters#ruby#rails_best_practices#Handle(buffer, lines) abort
+ let l:output = []
+
+ for l:warning in ale#util#FuzzyJSONDecode(a:lines, [])
+ if !ale#path#IsBufferPath(a:buffer, l:warning.filename)
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:warning.line_number + 0,
+ \ 'type': 'W',
+ \ 'text': l:warning.message,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort
+ let l:executable = ale#handlers#rails_best_practices#GetExecutable(a:buffer)
+ let l:exec_args = l:executable =~? 'bundle$'
+ \ ? ' exec rails_best_practices'
+ \ : ''
+
+ let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
+
+ if l:rails_root is? ''
+ return ''
+ endif
+
+ let l:output_file = ale#Has('win32') ? '%t ' : '/dev/stdout '
+ let l:cat_file = ale#Has('win32') ? '; type %t' : ''
+
+ return ale#Escape(l:executable) . l:exec_args
+ \ . ' --silent -f json --output-file ' . l:output_file
+ \ . ale#Var(a:buffer, 'ruby_rails_best_practices_options')
+ \ . ale#Escape(l:rails_root)
+ \ . l:cat_file
+endfunction
+
+call ale#linter#Define('ruby', {
+\ 'name': 'rails_best_practices',
+\ 'executable_callback': 'ale#handlers#rails_best_practices#GetExecutable',
+\ 'command_callback': 'ale_linters#ruby#rails_best_practices#GetCommand',
+\ 'callback': 'ale_linters#ruby#rails_best_practices#Handle',
+\ 'lint_file': 1,
+\})
diff --git a/vim/bundle/ale/ale_linters/ruby/reek.vim b/vim/bundle/ale/ale_linters/ruby/reek.vim
new file mode 100644
index 0000000..10bc9a8
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/ruby/reek.vim
@@ -0,0 +1,44 @@
+" Author: Eddie Lebow https://github.com/elebow
+" Description: Reek, a code smell detector for Ruby files
+
+call ale#Set('ruby_reek_show_context', 0)
+call ale#Set('ruby_reek_show_wiki_link', 0)
+
+function! ale_linters#ruby#reek#Handle(buffer, lines) abort
+ let l:output = []
+
+ for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
+ for l:location in l:error.lines
+ call add(l:output, {
+ \ 'lnum': l:location,
+ \ 'type': 'W',
+ \ 'text': s:BuildText(a:buffer, l:error),
+ \})
+ endfor
+ endfor
+
+ return l:output
+endfunction
+
+function! s:BuildText(buffer, error) abort
+ let l:text = a:error.smell_type . ':'
+
+ if ale#Var(a:buffer, 'ruby_reek_show_context')
+ let l:text .= ' ' . a:error.context
+ endif
+
+ let l:text .= ' ' . a:error.message
+
+ if ale#Var(a:buffer, 'ruby_reek_show_wiki_link')
+ let l:text .= ' [' . a:error.wiki_link . ']'
+ endif
+
+ return l:text
+endfunction
+
+call ale#linter#Define('ruby', {
+\ 'name': 'reek',
+\ 'executable': 'reek',
+\ 'command': 'reek -f json --no-progress --no-color',
+\ 'callback': 'ale_linters#ruby#reek#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/ruby/rubocop.vim b/vim/bundle/ale/ale_linters/ruby/rubocop.vim
new file mode 100644
index 0000000..2a4388f
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/ruby/rubocop.vim
@@ -0,0 +1,60 @@
+" Author: ynonp - https://github.com/ynonp, Eddie Lebow https://github.com/elebow
+" Description: RuboCop, a code style analyzer for Ruby files
+
+function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
+ let l:executable = ale#handlers#rubocop#GetExecutable(a:buffer)
+ let l:exec_args = l:executable =~? 'bundle$'
+ \ ? ' exec rubocop'
+ \ : ''
+
+ return ale#Escape(l:executable) . l:exec_args
+ \ . ' --format json --force-exclusion '
+ \ . ale#Var(a:buffer, 'ruby_rubocop_options')
+ \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
+endfunction
+
+function! ale_linters#ruby#rubocop#Handle(buffer, lines) abort
+ try
+ let l:errors = json_decode(a:lines[0])
+ catch
+ return []
+ endtry
+
+ if !has_key(l:errors, 'summary')
+ \|| l:errors['summary']['offense_count'] == 0
+ \|| empty(l:errors['files'])
+ return []
+ endif
+
+ let l:output = []
+
+ for l:error in l:errors['files'][0]['offenses']
+ let l:start_col = l:error['location']['column'] + 0
+ call add(l:output, {
+ \ 'lnum': l:error['location']['line'] + 0,
+ \ 'col': l:start_col,
+ \ 'end_col': l:start_col + l:error['location']['length'] - 1,
+ \ 'text': printf('%s [%s]', l:error['message'], l:error['cop_name']),
+ \ 'type': ale_linters#ruby#rubocop#GetType(l:error['severity']),
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+function! ale_linters#ruby#rubocop#GetType(severity) abort
+ if a:severity is? 'convention'
+ \|| a:severity is? 'warning'
+ \|| a:severity is? 'refactor'
+ return 'W'
+ endif
+
+ return 'E'
+endfunction
+
+call ale#linter#Define('ruby', {
+\ 'name': 'rubocop',
+\ 'executable_callback': 'ale#handlers#rubocop#GetExecutable',
+\ 'command_callback': 'ale_linters#ruby#rubocop#GetCommand',
+\ 'callback': 'ale_linters#ruby#rubocop#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/ruby/ruby.vim b/vim/bundle/ale/ale_linters/ruby/ruby.vim
new file mode 100644
index 0000000..a9f7b51
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/ruby/ruby.vim
@@ -0,0 +1,10 @@
+" Author: Brandon Roehl - https://github.com/BrandonRoehl
+" Description: Ruby MRI for Ruby files
+
+call ale#linter#Define('ruby', {
+\ 'name': 'ruby',
+\ 'executable': 'ruby',
+\ 'output_stream': 'stderr',
+\ 'command': 'ruby -w -c -T1 %t',
+\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
+\})
diff --git a/vim/bundle/ale/ale_linters/rust/cargo.vim b/vim/bundle/ale/ale_linters/rust/cargo.vim
new file mode 100644
index 0000000..f19061a
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/rust/cargo.vim
@@ -0,0 +1,31 @@
+" Author: Daniel Schemala
+" Description: rustc invoked by cargo for rust files
+
+let g:ale_rust_cargo_use_check = get(g:, 'ale_rust_cargo_use_check', 0)
+
+function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
+ if ale#path#FindNearestFile(a:bufnr, 'Cargo.toml') isnot# ''
+ return 'cargo'
+ else
+ " if there is no Cargo.toml file, we don't use cargo even if it exists,
+ " so we return '', because executable('') apparently always fails
+ return ''
+ endif
+endfunction
+
+function! ale_linters#rust#cargo#GetCommand(buffer) abort
+ let l:command = ale#Var(a:buffer, 'rust_cargo_use_check')
+ \ ? 'check'
+ \ : 'build'
+
+ return 'cargo ' . l:command . ' --frozen --message-format=json -q'
+endfunction
+
+call ale#linter#Define('rust', {
+\ 'name': 'cargo',
+\ 'executable_callback': 'ale_linters#rust#cargo#GetCargoExecutable',
+\ 'command_callback': 'ale_linters#rust#cargo#GetCommand',
+\ 'callback': 'ale#handlers#rust#HandleRustErrors',
+\ 'output_stream': 'stdout',
+\ 'lint_file': 1,
+\})
diff --git a/vim/bundle/ale/ale_linters/rust/rls.vim b/vim/bundle/ale/ale_linters/rust/rls.vim
new file mode 100644
index 0000000..c49d268
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/rust/rls.vim
@@ -0,0 +1,33 @@
+" Author: w0rp
+" Description: A language server for Rust
+
+call ale#Set('rust_rls_executable', 'rls')
+
+function! ale_linters#rust#rls#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'rust_rls_executable')
+endfunction
+
+function! ale_linters#rust#rls#GetCommand(buffer) abort
+ let l:executable = ale_linters#rust#rls#GetExecutable(a:buffer)
+
+ return ale#Escape(l:executable) . ' +nightly'
+endfunction
+
+function! ale_linters#rust#rls#GetLanguage(buffer) abort
+ return 'rust'
+endfunction
+
+function! ale_linters#rust#rls#GetProjectRoot(buffer) abort
+ let l:cargo_file = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
+
+ return !empty(l:cargo_file) ? fnamemodify(l:cargo_file, ':h') : ''
+endfunction
+
+call ale#linter#Define('rust', {
+\ 'name': 'rls',
+\ 'lsp': 'stdio',
+\ 'executable_callback': 'ale_linters#rust#rls#GetExecutable',
+\ 'command_callback': 'ale_linters#rust#rls#GetCommand',
+\ 'language_callback': 'ale_linters#rust#rls#GetLanguage',
+\ 'project_root_callback': 'ale_linters#rust#rls#GetProjectRoot',
+\})
diff --git a/vim/bundle/ale/ale_linters/rust/rustc.vim b/vim/bundle/ale/ale_linters/rust/rustc.vim
new file mode 100644
index 0000000..e792faa
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/rust/rustc.vim
@@ -0,0 +1,27 @@
+" Author: Daniel Schemala
+" Description: rustc for rust files
+
+function! ale_linters#rust#rustc#RustcCommand(buffer_number) abort
+ " Try to guess the library search path. If the project is managed by cargo,
+ " it's usually /target/debug/deps/ or
+ " /target/release/deps/
+ let l:cargo_file = ale#path#FindNearestFile(a:buffer_number, 'Cargo.toml')
+
+ if l:cargo_file isnot# ''
+ let l:project_root = fnamemodify(l:cargo_file, ':h')
+ let l:dependencies = '-L ' . l:project_root . '/target/debug/deps -L ' .
+ \ l:project_root . '/target/release/deps'
+ else
+ let l:dependencies = ''
+ endif
+
+ return 'rustc --error-format=json -Z no-trans ' . l:dependencies . ' -'
+endfunction
+
+call ale#linter#Define('rust', {
+\ 'name': 'rustc',
+\ 'executable': 'rustc',
+\ 'command_callback': 'ale_linters#rust#rustc#RustcCommand',
+\ 'callback': 'ale#handlers#rust#HandleRustErrors',
+\ 'output_stream': 'stderr',
+\})
diff --git a/vim/bundle/ale/ale_linters/sass/sasslint.vim b/vim/bundle/ale/ale_linters/sass/sasslint.vim
new file mode 100644
index 0000000..bbe7125
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/sass/sasslint.vim
@@ -0,0 +1,8 @@
+" Author: KabbAmine - https://github.com/KabbAmine
+
+call ale#linter#Define('sass', {
+\ 'name': 'sasslint',
+\ 'executable': 'sass-lint',
+\ 'command': 'sass-lint -v -q -f compact %t',
+\ 'callback': 'ale#handlers#css#HandleCSSLintFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/sass/stylelint.vim b/vim/bundle/ale/ale_linters/sass/stylelint.vim
new file mode 100644
index 0000000..98c3725
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/sass/stylelint.vim
@@ -0,0 +1,22 @@
+" Author: diartyz
+
+call ale#Set('sass_stylelint_executable', 'stylelint')
+call ale#Set('sass_stylelint_use_global', 0)
+
+function! ale_linters#sass#stylelint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'sass_stylelint', [
+ \ 'node_modules/.bin/stylelint',
+ \])
+endfunction
+
+function! ale_linters#sass#stylelint#GetCommand(buffer) abort
+ return ale_linters#sass#stylelint#GetExecutable(a:buffer)
+ \ . ' --stdin-filename %s'
+endfunction
+
+call ale#linter#Define('sass', {
+\ 'name': 'stylelint',
+\ 'executable_callback': 'ale_linters#sass#stylelint#GetExecutable',
+\ 'command_callback': 'ale_linters#sass#stylelint#GetCommand',
+\ 'callback': 'ale#handlers#css#HandleStyleLintFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/scala/scalac.vim b/vim/bundle/ale/ale_linters/scala/scalac.vim
new file mode 100644
index 0000000..584aee7
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/scala/scalac.vim
@@ -0,0 +1,65 @@
+" Author: Zoltan Kalmar - https://github.com/kalmiz,
+" w0rp
+" Description: Basic scala support using scalac
+
+function! ale_linters#scala#scalac#GetExecutable(buffer) abort
+ if index(split(getbufvar(a:buffer, '&filetype'), '\.'), 'sbt') >= 0
+ " Don't check sbt files with scalac.
+ return ''
+ endif
+
+ return 'scalac'
+endfunction
+
+function! ale_linters#scala#scalac#GetCommand(buffer) abort
+ let l:executable = ale_linters#scala#scalac#GetExecutable(a:buffer)
+
+ if empty(l:executable)
+ return ''
+ endif
+
+ return ale#Escape(l:executable) . ' -Ystop-after:parser %t'
+endfunction
+
+function! ale_linters#scala#scalac#Handle(buffer, lines) abort
+ " Matches patterns line the following:
+ "
+ " /var/folders/5q/20rgxx3x1s34g3m14n5bq0x80000gn/T/vv6pSsy/0:26: error: expected class or object definition
+ let l:pattern = '^.\+:\(\d\+\): \(\w\+\): \(.\+\)'
+ let l:output = []
+ let l:ln = 0
+
+ for l:line in a:lines
+ let l:ln = l:ln + 1
+ let l:match = matchlist(l:line, l:pattern)
+
+ if len(l:match) == 0
+ continue
+ endif
+
+ let l:text = l:match[3]
+ let l:type = l:match[2] is# 'error' ? 'E' : 'W'
+ let l:col = 0
+
+ if l:ln + 1 < len(a:lines)
+ let l:col = stridx(a:lines[l:ln + 1], '^')
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:col + 1,
+ \ 'text': l:text,
+ \ 'type': l:type,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('scala', {
+\ 'name': 'scalac',
+\ 'executable_callback': 'ale_linters#scala#scalac#GetExecutable',
+\ 'command_callback': 'ale_linters#scala#scalac#GetCommand',
+\ 'callback': 'ale_linters#scala#scalac#Handle',
+\ 'output_stream': 'stderr',
+\})
diff --git a/vim/bundle/ale/ale_linters/scala/scalastyle.vim b/vim/bundle/ale/ale_linters/scala/scalastyle.vim
new file mode 100644
index 0000000..ea56c0e
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/scala/scalastyle.vim
@@ -0,0 +1,83 @@
+" Author: Kevin Kays - https://github.com/okkays
+" Description: Support for the scalastyle checker.
+
+let g:ale_scala_scalastyle_options =
+\ get(g:, 'ale_scala_scalastyle_options', '')
+
+let g:ale_scalastyle_config_loc =
+\ get(g:, 'ale_scalastyle_config_loc', '')
+
+function! ale_linters#scala#scalastyle#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ "
+ " warning file=/home/blurble/Doop.scala message=Missing or badly formed ScalaDoc: Extra @param foobles line=190
+
+ let l:patterns = [
+ \ '^\(.\+\) .\+ message=\(.\+\) line=\(\d\+\)$',
+ \ '^\(.\+\) .\+ message=\(.\+\) line=\(\d\+\) column=\(\d\+\)$',
+ \]
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:patterns)
+ let l:args = {
+ \ 'lnum': l:match[3] + 0,
+ \ 'type': l:match[1] =~? 'error' ? 'E' : 'W',
+ \ 'text': l:match[2]
+ \}
+
+ if !empty(l:match[4])
+ let l:args['col'] = l:match[4] + 1
+ endif
+
+ call add(l:output, l:args)
+ endfor
+
+ return l:output
+endfunction
+
+function! ale_linters#scala#scalastyle#GetCommand(buffer) abort
+ " Search for scalastyle config in parent directories.
+ let l:scalastyle_config = ''
+ let l:potential_configs = [
+ \ 'scalastyle_config.xml',
+ \ 'scalastyle-config.xml'
+ \]
+ for l:config in l:potential_configs
+ let l:scalastyle_config = ale#path#ResolveLocalPath(
+ \ a:buffer,
+ \ l:config,
+ \ ''
+ \)
+ if !empty(l:scalastyle_config)
+ break
+ endif
+ endfor
+
+ " If all else fails, try the global config.
+ if empty(l:scalastyle_config)
+ let l:scalastyle_config = get(g:, 'ale_scalastyle_config_loc', '')
+ endif
+
+ " Build the command using the config file and additional options.
+ let l:command = 'scalastyle'
+
+ if !empty(l:scalastyle_config)
+ let l:command .= ' --config ' . ale#Escape(l:scalastyle_config)
+ endif
+
+ if !empty(g:ale_scala_scalastyle_options)
+ let l:command .= ' ' . g:ale_scala_scalastyle_options
+ endif
+
+ let l:command .= ' %t'
+
+ return l:command
+endfunction
+
+call ale#linter#Define('scala', {
+\ 'name': 'scalastyle',
+\ 'executable': 'scalastyle',
+\ 'output_stream': 'stdout',
+\ 'command_callback': 'ale_linters#scala#scalastyle#GetCommand',
+\ 'callback': 'ale_linters#scala#scalastyle#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/scss/sasslint.vim b/vim/bundle/ale/ale_linters/scss/sasslint.vim
new file mode 100644
index 0000000..bd01646
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/scss/sasslint.vim
@@ -0,0 +1,8 @@
+" Author: KabbAmine - https://github.com/KabbAmine
+
+call ale#linter#Define('scss', {
+\ 'name': 'sasslint',
+\ 'executable': 'sass-lint',
+\ 'command': 'sass-lint -v -q -f compact %t',
+\ 'callback': 'ale#handlers#css#HandleCSSLintFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/scss/scsslint.vim b/vim/bundle/ale/ale_linters/scss/scsslint.vim
new file mode 100644
index 0000000..7ce5724
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/scss/scsslint.vim
@@ -0,0 +1,34 @@
+" Author: w0rp
+" Description: This file add scsslint support for SCSS support
+
+function! ale_linters#scss#scsslint#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ "
+ " test.scss:2:1 [W] Indentation: Line should be indented 2 spaces, but was indented 4 spaces
+ let l:pattern = '^.*:\(\d\+\):\(\d*\) \[\([^\]]\+\)\] \(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ if !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
+ \&& l:match[4] =~# '^TrailingWhitespace'
+ " Skip trailing whitespace warnings if that option is off.
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 0,
+ \ 'text': l:match[4],
+ \ 'type': l:match[3] is# 'E' ? 'E' : 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('scss', {
+\ 'name': 'scsslint',
+\ 'executable': 'scss-lint',
+\ 'command': 'scss-lint --stdin-file-path=%s',
+\ 'callback': 'ale_linters#scss#scsslint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/scss/stylelint.vim b/vim/bundle/ale/ale_linters/scss/stylelint.vim
new file mode 100644
index 0000000..00189a8
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/scss/stylelint.vim
@@ -0,0 +1,22 @@
+" Author: diartyz
+
+call ale#Set('scss_stylelint_executable', 'stylelint')
+call ale#Set('scss_stylelint_use_global', 0)
+
+function! ale_linters#scss#stylelint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'scss_stylelint', [
+ \ 'node_modules/.bin/stylelint',
+ \])
+endfunction
+
+function! ale_linters#scss#stylelint#GetCommand(buffer) abort
+ return ale_linters#scss#stylelint#GetExecutable(a:buffer)
+ \ . ' --stdin-filename %s'
+endfunction
+
+call ale#linter#Define('scss', {
+\ 'name': 'stylelint',
+\ 'executable_callback': 'ale_linters#scss#stylelint#GetExecutable',
+\ 'command_callback': 'ale_linters#scss#stylelint#GetCommand',
+\ 'callback': 'ale#handlers#css#HandleStyleLintFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/sh/shell.vim b/vim/bundle/ale/ale_linters/sh/shell.vim
new file mode 100644
index 0000000..cf5e4e6
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/sh/shell.vim
@@ -0,0 +1,57 @@
+" Author: w0rp
+" Description: Lints sh files using bash -n
+
+" Backwards compatibility
+if exists('g:ale_linters_sh_shell_default_shell')
+ let g:ale_sh_shell_default_shell = g:ale_linters_sh_shell_default_shell
+endif
+
+" This option can be changed to change the default shell when the shell
+" cannot be taken from the hashbang line.
+if !exists('g:ale_sh_shell_default_shell')
+ let g:ale_sh_shell_default_shell = fnamemodify($SHELL, ':t')
+
+ if g:ale_sh_shell_default_shell is# '' || g:ale_sh_shell_default_shell is# 'fish'
+ let g:ale_sh_shell_default_shell = 'bash'
+ endif
+endif
+
+function! ale_linters#sh#shell#GetExecutable(buffer) abort
+ let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
+
+ if !empty(l:shell_type)
+ return l:shell_type
+ endif
+
+ return ale#Var(a:buffer, 'sh_shell_default_shell')
+endfunction
+
+function! ale_linters#sh#shell#GetCommand(buffer) abort
+ return ale_linters#sh#shell#GetExecutable(a:buffer) . ' -n %t'
+endfunction
+
+function! ale_linters#sh#shell#Handle(buffer, lines) abort
+ " Matches patterns line the following:
+ "
+ " bash: line 13: syntax error near unexpected token `d'
+ " sh: 11: Syntax error: "(" unexpected
+ let l:pattern = '\v(line |: ?)(\d+): (.+)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': str2nr(l:match[2]),
+ \ 'text': l:match[3],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('sh', {
+\ 'name': 'shell',
+\ 'output_stream': 'stderr',
+\ 'executable_callback': 'ale_linters#sh#shell#GetExecutable',
+\ 'command_callback': 'ale_linters#sh#shell#GetCommand',
+\ 'callback': 'ale_linters#sh#shell#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/sh/shellcheck.vim b/vim/bundle/ale/ale_linters/sh/shellcheck.vim
new file mode 100644
index 0000000..3a2d33f
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/sh/shellcheck.vim
@@ -0,0 +1,58 @@
+" Author: w0rp
+" Description: This file adds support for using the shellcheck linter with
+" shell scripts.
+
+" This global variable can be set with a string of comma-seperated error
+" codes to exclude from shellcheck. For example:
+"
+" let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004'
+let g:ale_sh_shellcheck_exclusions =
+\ get(g:, 'ale_sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_exclusions', ''))
+
+let g:ale_sh_shellcheck_executable =
+\ get(g:, 'ale_sh_shellcheck_executable', 'shellcheck')
+
+let g:ale_sh_shellcheck_options =
+\ get(g:, 'ale_sh_shellcheck_options', '')
+
+function! ale_linters#sh#shellcheck#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'sh_shellcheck_executable')
+endfunction
+
+function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
+ let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
+
+ if !empty(l:shell_type)
+ return l:shell_type
+ endif
+
+ " If there's no hashbang, try using Vim's buffer variables.
+ if get(b:, 'is_bash')
+ return 'bash'
+ elseif get(b:, 'is_sh')
+ return 'sh'
+ elseif get(b:, 'is_kornshell')
+ return 'ksh'
+ endif
+
+ return ''
+endfunction
+
+function! ale_linters#sh#shellcheck#GetCommand(buffer) abort
+ let l:options = ale#Var(a:buffer, 'sh_shellcheck_options')
+ let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
+ let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
+
+ return ale_linters#sh#shellcheck#GetExecutable(a:buffer)
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
+ \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
+ \ . ' -f gcc -'
+endfunction
+
+call ale#linter#Define('sh', {
+\ 'name': 'shellcheck',
+\ 'executable_callback': 'ale_linters#sh#shellcheck#GetExecutable',
+\ 'command_callback': 'ale_linters#sh#shellcheck#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/slim/slimlint.vim b/vim/bundle/ale/ale_linters/slim/slimlint.vim
new file mode 100644
index 0000000..74796b2
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/slim/slimlint.vim
@@ -0,0 +1,26 @@
+" Author: Markus Doits - https://github.com/doits
+" Description: slim-lint for Slim files, based on hamllint.vim
+
+function! ale_linters#slim#slimlint#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ " :5 [W] LineLength: Line is too long. [150/120]
+ 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('slim', {
+\ 'name': 'slimlint',
+\ 'executable': 'slim-lint',
+\ 'command': 'slim-lint %t',
+\ 'callback': 'ale_linters#slim#slimlint#Handle'
+\})
diff --git a/vim/bundle/ale/ale_linters/sml/smlnj.vim b/vim/bundle/ale/ale_linters/sml/smlnj.vim
new file mode 100644
index 0000000..4acfc9e
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/sml/smlnj.vim
@@ -0,0 +1,47 @@
+" Author: Paulo Alem
+" Description: Rudimentary SML checking with smlnj compiler
+
+function! ale_linters#sml#smlnj#Handle(buffer, lines) abort
+ " Try to match basic sml errors
+
+ let l:out = []
+ let l:pattern = '^.*\:\([0-9\.]\+\)\ \(\w\+\)\:\ \(.*\)'
+ let l:pattern2 = '^.*\:\([0-9]\+\)\.\?\([0-9]\+\).* \(\(Warning\|Error\): .*\)'
+
+ for l:line in a:lines
+ let l:match2 = matchlist(l:line, l:pattern2)
+
+ if len(l:match2) != 0
+ call add(l:out, {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': l:match2[1] + 0,
+ \ 'col' : l:match2[2] - 1,
+ \ 'text': l:match2[3],
+ \ 'type': l:match2[3] =~# '^Warning' ? 'W' : 'E',
+ \})
+ continue
+ endif
+
+ let l:match = matchlist(l:line, l:pattern)
+
+ if len(l:match) != 0
+ call add(l:out, {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': l:match[1] + 0,
+ \ 'text': l:match[2] . ': ' . l:match[3],
+ \ 'type': l:match[2] is# 'error' ? 'E' : 'W',
+ \})
+ continue
+ endif
+
+ endfor
+
+ return l:out
+endfunction
+
+call ale#linter#Define('sml', {
+\ 'name': 'smlnj',
+\ 'executable': 'sml',
+\ 'command': 'sml',
+\ 'callback': 'ale_linters#sml#smlnj#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/spec/rpmlint.vim b/vim/bundle/ale/ale_linters/spec/rpmlint.vim
new file mode 100644
index 0000000..f5308af
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/spec/rpmlint.vim
@@ -0,0 +1,85 @@
+" Author: Jason Tibbitts
+" Description: Adds support for checking RPM spec files with rpmlint
+
+" rpmlint will produce varions types of output:
+"
+" Lines like the following are output when the file is simply not able to be
+" parsed by rpmspec -P:
+" apcupsd.spec: E: specfile-error warning: bogus date in %changelog: Mon Oct 1 2005 - Foo
+" apcupsd.spec: E: specfile-error error: %changelog not in descending chronological order
+" They do not contain a line number, and there's not a whole lot that can be
+" done to locate them besides grep for them. rpmlint is just passing the
+" output from rpm along with the filename, an error indicator, and an error
+" type.
+"
+" Lines like the following:
+" cyrus-imapd.spec:23: W: macro-in-comment %version
+" cyrus-imapd.spec:18: E: hardcoded-library-path in %_prefix/lib/%name
+" indicate warnings and errors, respectively. No column numbers are provided
+"
+" Lines like:
+" apcupsd.spec: I: checking
+" apcupsd.spec: I: checking-url https://downloads.sourceforge.net/apcupsd/apcupsd-3.14.14.tar.gz (timeout 10 seconds)
+" are merely informational and are only output when -v is passed. But they
+" may be useful in a log to know why things are taking so long.
+"
+" And this is always output at the end and should just be ignored:
+" 0 packages and 1 specfiles checked; 4 errors, 0 warnings.
+
+let g:ale_spec_rpmlint_executable =
+\ get(g:, 'ale_spec_rpmlint_executable', 'rpmlint')
+
+let g:ale_spec_rpmlint_options =
+\ get(g:, 'ale_spec_rpmlint_options', '')
+
+function! ale_linters#spec#rpmlint#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'spec_rpmlint_executable')
+endfunction
+
+function! ale_linters#spec#rpmlint#GetCommand(buffer) abort
+ return ale_linters#spec#rpmlint#GetExecutable(a:buffer)
+ \ . ' ' . ale#Var(a:buffer, 'spec_rpmlint_options')
+ \ . ' -o "NetworkEnabled False"'
+ \ . ' -v'
+ \ . ' %t'
+endfunction
+
+function! ale_linters#spec#rpmlint#Handle(buffer, lines) abort
+ " let l:pat_inform = '^.\+: I: \(.+\)'
+ let l:pat_errwarn = '^.\+:\(\d\+\): \([EW]\): \(.\+\)'
+ let l:pat_baderr = '^.\+: E: \(.\+\)'
+ let l:output = []
+
+ for l:line in a:lines
+ let l:match_errwarn = matchlist(l:line, l:pat_errwarn)
+ let l:match_baderr = matchlist(l:line, l:pat_baderr)
+
+ if len(l:match_errwarn) > 0
+ let l:text = l:match_errwarn[3]
+ let l:type = l:match_errwarn[2]
+ let l:lnum = l:match_errwarn[1] + 0
+ elseif len(l:match_baderr) > 0
+ let l:text = l:match_baderr[1]
+ let l:type = 'E'
+ let l:lnum = 1
+ else
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': l:lnum,
+ \ 'text': l:text,
+ \ 'type': l:type,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('spec', {
+\ 'name': 'rpmlint',
+\ 'executable_callback': 'ale_linters#spec#rpmlint#GetExecutable',
+\ 'command_callback': 'ale_linters#spec#rpmlint#GetCommand',
+\ 'callback': 'ale_linters#spec#rpmlint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/sql/sqlint.vim b/vim/bundle/ale/ale_linters/sql/sqlint.vim
new file mode 100644
index 0000000..ca89372
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/sql/sqlint.vim
@@ -0,0 +1,28 @@
+" Author: Adriaan Zonnenberg
+" Description: sqlint for SQL files
+
+function! ale_linters#sql#sqlint#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ "
+ " stdin:3:1:ERROR syntax error at or near "WIBBLE"
+ let l:pattern = '\v^[^:]+:(\d+):(\d+):(\u+) (.*)'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 0,
+ \ 'type': l:match[3][0],
+ \ 'text': l:match[4],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('sql', {
+\ 'name': 'sqlint',
+\ 'executable': 'sqlint',
+\ 'command': 'sqlint',
+\ 'callback': 'ale_linters#sql#sqlint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/stylus/stylelint.vim b/vim/bundle/ale/ale_linters/stylus/stylelint.vim
new file mode 100644
index 0000000..2721529
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/stylus/stylelint.vim
@@ -0,0 +1,24 @@
+" Author: diartyz , w0rp
+
+call ale#Set('stylus_stylelint_executable', 'stylelint')
+call ale#Set('stylus_stylelint_options', '')
+call ale#Set('stylus_stylelint_use_global', 0)
+
+function! ale_linters#stylus#stylelint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'stylus_stylelint', [
+ \ 'node_modules/.bin/stylelint',
+ \])
+endfunction
+
+function! ale_linters#stylus#stylelint#GetCommand(buffer) abort
+ return ale_linters#stylus#stylelint#GetExecutable(a:buffer)
+ \ . ' ' . ale#Var(a:buffer, 'stylus_stylelint_options')
+ \ . ' --stdin-filename %s'
+endfunction
+
+call ale#linter#Define('stylus', {
+\ 'name': 'stylelint',
+\ 'executable_callback': 'ale_linters#stylus#stylelint#GetExecutable',
+\ 'command_callback': 'ale_linters#stylus#stylelint#GetCommand',
+\ 'callback': 'ale#handlers#css#HandleStyleLintFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/swift/swiftlint.vim b/vim/bundle/ale/ale_linters/swift/swiftlint.vim
new file mode 100644
index 0000000..b7dcf93
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/swift/swiftlint.vim
@@ -0,0 +1,9 @@
+" Author: David Mohundro
+" Description: swiftlint for swift files
+
+call ale#linter#Define('swift', {
+\ 'name': 'swiftlint',
+\ 'executable': 'swiftlint',
+\ 'command': 'swiftlint lint --use-stdin',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
+\})
diff --git a/vim/bundle/ale/ale_linters/tcl/nagelfar.vim b/vim/bundle/ale/ale_linters/tcl/nagelfar.vim
new file mode 100644
index 0000000..13b7a54
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/tcl/nagelfar.vim
@@ -0,0 +1,46 @@
+" Author: Nick James
+" Description: nagelfar linter for tcl files
+
+call ale#Set('tcl_nagelfar_executable', 'nagelfar.tcl')
+call ale#Set('tcl_nagelfar_options', '')
+
+function! ale_linters#tcl#nagelfar#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'tcl_nagelfar_executable')
+endfunction
+
+function! ale_linters#tcl#nagelfar#GetCommand(buffer) abort
+ let l:options = ale#Var(a:buffer, 'tcl_nagelfar_options')
+
+ return ale#Escape(ale_linters#tcl#nagelfar#GetExecutable(a:buffer))
+ \ . (!empty(l:options) ? ' ' . l:options : '')
+ \ . ' %s'
+endfunction
+
+function! ale_linters#tcl#nagelfar#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ " Line 5: W Found constant "bepa" which is also a variable.
+ " Line 13: E Wrong number of arguments (3) to "set"
+ " Line 93: N Close brace not aligned with line 90 (4 0)
+
+ let l:pattern = '^Line\s\+\([0-9]\+\): \([NEW]\) \(.*\)$'
+ 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] is# 'N' ? 'W' : l:match[2],
+ \ 'text': l:match[3],
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('tcl', {
+\ 'name': 'nagelfar',
+\ 'output_stream': 'stdout',
+\ 'executable_callback': 'ale_linters#tcl#nagelfar#GetExecutable',
+\ 'command_callback': 'ale_linters#tcl#nagelfar#GetCommand',
+\ 'callback': 'ale_linters#tcl#nagelfar#Handle',
+\ 'lint_file': 1,
+\})
diff --git a/vim/bundle/ale/ale_linters/testft/testlinter.vim b/vim/bundle/ale/ale_linters/testft/testlinter.vim
new file mode 100644
index 0000000..65e0b20
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/testft/testlinter.vim
@@ -0,0 +1,10 @@
+" Author: neersighted
+" Description: dummy linter to use in tests
+
+call ale#linter#Define('testft', {
+\ 'name': 'testlinter',
+\ 'output_stream': 'stdout',
+\ 'executable': 'testlinter',
+\ 'command': 'testlinter',
+\ 'callback': 'testCB',
+\})
diff --git a/vim/bundle/ale/ale_linters/tex/chktex.vim b/vim/bundle/ale/ale_linters/tex/chktex.vim
new file mode 100644
index 0000000..7f1b0c7
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/tex/chktex.vim
@@ -0,0 +1,54 @@
+" Author: Andrew Balmos -
+" Description: chktex for LaTeX files
+
+let g:ale_tex_chktex_executable =
+\ get(g:, 'ale_tex_chktex_executable', 'chktex')
+
+let g:ale_tex_chktex_options =
+\ get(g:, 'ale_tex_chktex_options', '-I')
+
+function! ale_linters#tex#chktex#GetCommand(buffer) abort
+ " Check for optional .chktexrc
+ let l:chktex_config = ale#path#FindNearestFile(
+ \ a:buffer,
+ \ '.chktexrc')
+
+ let l:command = ale#Var(a:buffer, 'tex_chktex_executable')
+ " Avoid bug when used without -p (last warning has gibberish for a filename)
+ let l:command .= ' -v0 -p stdin -q'
+
+ if !empty(l:chktex_config)
+ let l:command .= ' -l ' . ale#Escape(l:chktex_config)
+ endif
+
+ let l:command .= ' ' . ale#Var(a:buffer, 'tex_chktex_options')
+
+ return l:command
+endfunction
+
+function! ale_linters#tex#chktex#Handle(buffer, lines) abort
+ " Mattes lines like:
+ "
+ " stdin:499:2:24:Delete this space to maintain correct pagereferences.
+ " stdin:507:81:3:You should enclose the previous parenthesis with `{}'.
+ let l:pattern = '^stdin:\(\d\+\):\(\d\+\):\(\d\+\):\(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'col': l:match[2] + 0,
+ \ 'text': l:match[4] . ' (' . (l:match[3]+0) . ')',
+ \ 'type': 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('tex', {
+\ 'name': 'chktex',
+\ 'executable': 'chktex',
+\ 'command_callback': 'ale_linters#tex#chktex#GetCommand',
+\ 'callback': 'ale_linters#tex#chktex#Handle'
+\})
diff --git a/vim/bundle/ale/ale_linters/tex/lacheck.vim b/vim/bundle/ale/ale_linters/tex/lacheck.vim
new file mode 100644
index 0000000..e5a9632
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/tex/lacheck.vim
@@ -0,0 +1,47 @@
+" Author: Andrew Balmos -
+" Description: lacheck for LaTeX files
+
+let g:ale_tex_lacheck_executable =
+\ get(g:, 'ale_tex_lacheck_executable', 'lacheck')
+
+function! ale_linters#tex#lacheck#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'tex_lacheck_executable')
+endfunction
+
+function! ale_linters#tex#lacheck#GetCommand(buffer) abort
+ return ale#Var(a:buffer, 'tex_lacheck_executable') . ' %t'
+endfunction
+
+function! ale_linters#tex#lacheck#Handle(buffer, lines) abort
+ " Mattes lines like:
+ "
+ " "book.tex", line 37: possible unwanted space at "{"
+ " "book.tex", line 38: missing `\ ' after "etc."
+
+ let l:pattern = '^".\+", line \(\d\+\): \(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ " lacheck follows `\input{}` commands. If the cwd is not the same as the
+ " file in the buffer then it will fail to find the inputed items. We do not
+ " want warnings from those items anyway
+ if !empty(matchstr(l:match[2], '^Could not open ".\+"$'))
+ continue
+ endif
+
+ call add(l:output, {
+ \ 'lnum': l:match[1] + 0,
+ \ 'text': l:match[2],
+ \ 'type': 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('tex', {
+\ 'name': 'lacheck',
+\ 'executable_callback': 'ale_linters#tex#lacheck#GetExecutable',
+\ 'command_callback': 'ale_linters#tex#lacheck#GetCommand',
+\ 'callback': 'ale_linters#tex#lacheck#Handle'
+\})
diff --git a/vim/bundle/ale/ale_linters/tex/proselint.vim b/vim/bundle/ale/ale_linters/tex/proselint.vim
new file mode 100644
index 0000000..35e764e
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/tex/proselint.vim
@@ -0,0 +1,9 @@
+" Author: poohzrn https://github.com/poohzrn
+" Description: proselint for TeX files
+
+call ale#linter#Define('tex', {
+\ 'name': 'proselint',
+\ 'executable': 'proselint',
+\ 'command': 'proselint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/texinfo/proselint.vim b/vim/bundle/ale/ale_linters/texinfo/proselint.vim
new file mode 100644
index 0000000..003e3a0
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/texinfo/proselint.vim
@@ -0,0 +1,9 @@
+" Author: Daniel M. Capella https://github.com/polyzen
+" Description: proselint for Texinfo files
+
+call ale#linter#Define('texinfo', {
+\ 'name': 'proselint',
+\ 'executable': 'proselint',
+\ 'command': 'proselint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/text/proselint.vim b/vim/bundle/ale/ale_linters/text/proselint.vim
new file mode 100644
index 0000000..281b4ff
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/text/proselint.vim
@@ -0,0 +1,9 @@
+" Author: poohzrn https://github.com/poohzrn
+" Description: proselint for text files
+
+call ale#linter#Define('text', {
+\ 'name': 'proselint',
+\ 'executable': 'proselint',
+\ 'command': 'proselint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/text/vale.vim b/vim/bundle/ale/ale_linters/text/vale.vim
new file mode 100644
index 0000000..60bd799
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/text/vale.vim
@@ -0,0 +1,9 @@
+" Author: chew-z https://github.com/chew-z
+" Description: vale for text files
+
+call ale#linter#Define('text', {
+\ 'name': 'vale',
+\ 'executable': 'vale',
+\ 'command': 'vale --output=line %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/typescript/eslint.vim b/vim/bundle/ale/ale_linters/typescript/eslint.vim
new file mode 100644
index 0000000..f1ae54e
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/typescript/eslint.vim
@@ -0,0 +1,9 @@
+" Author: w0rp
+" Description: eslint for JavaScript files
+
+call ale#linter#Define('typescript', {
+\ 'name': 'eslint',
+\ 'executable_callback': 'ale#handlers#eslint#GetExecutable',
+\ 'command_callback': 'ale#handlers#eslint#GetCommand',
+\ 'callback': 'ale#handlers#eslint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/typescript/tslint.vim b/vim/bundle/ale/ale_linters/typescript/tslint.vim
new file mode 100644
index 0000000..26d26c8
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/typescript/tslint.vim
@@ -0,0 +1,58 @@
+" Author: Prashanth Chandra https://github.com/prashcr
+" Description: tslint for TypeScript files
+
+call ale#Set('typescript_tslint_executable', 'tslint')
+call ale#Set('typescript_tslint_config_path', '')
+call ale#Set('typescript_tslint_use_global', 0)
+
+function! ale_linters#typescript#tslint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'typescript_tslint', [
+ \ 'node_modules/.bin/tslint',
+ \])
+endfunction
+
+function! ale_linters#typescript#tslint#Handle(buffer, lines) abort
+ let l:dir = expand('#' . a:buffer . ':p:h')
+ let l:output = []
+
+ for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
+ call add(l:output, {
+ \ 'filename': ale#path#GetAbsPath(l:dir, l:error.name),
+ \ 'type': (get(l:error, 'ruleSeverity', '') is# 'WARNING' ? 'W' : 'E'),
+ \ 'text': has_key(l:error, 'ruleName')
+ \ ? l:error.ruleName . ': ' . l:error.failure
+ \ : l:error.failure,
+ \ 'lnum': l:error.startPosition.line + 1,
+ \ 'col': l:error.startPosition.character + 1,
+ \ 'end_lnum': l:error.endPosition.line + 1,
+ \ 'end_col': l:error.endPosition.character + 1,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+function! ale_linters#typescript#tslint#GetCommand(buffer) abort
+ let l:tslint_config_path = ale#path#ResolveLocalPath(
+ \ a:buffer,
+ \ 'tslint.json',
+ \ ale#Var(a:buffer, 'typescript_tslint_config_path')
+ \)
+
+ let l:tslint_config_option = !empty(l:tslint_config_path)
+ \ ? ' -c ' . ale#Escape(l:tslint_config_path)
+ \ : ''
+
+ return ale#path#BufferCdString(a:buffer)
+ \ . ale_linters#typescript#tslint#GetExecutable(a:buffer)
+ \ . ' --format json'
+ \ . l:tslint_config_option
+ \ . ' %t'
+endfunction
+
+call ale#linter#Define('typescript', {
+\ 'name': 'tslint',
+\ 'executable_callback': 'ale_linters#typescript#tslint#GetExecutable',
+\ 'command_callback': 'ale_linters#typescript#tslint#GetCommand',
+\ 'callback': 'ale_linters#typescript#tslint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/typescript/tsserver.vim b/vim/bundle/ale/ale_linters/typescript/tsserver.vim
new file mode 100644
index 0000000..7a155bd
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/typescript/tsserver.vim
@@ -0,0 +1,30 @@
+" Author: w0rp
+" Description: tsserver integration for ALE
+
+call ale#Set('typescript_tsserver_executable', 'tsserver')
+call ale#Set('typescript_tsserver_config_path', '')
+call ale#Set('typescript_tsserver_use_global', 0)
+
+" These functions need to be defined just to comply with the API for LSP.
+function! ale_linters#typescript#tsserver#GetProjectRoot(buffer) abort
+ return ''
+endfunction
+
+function! ale_linters#typescript#tsserver#GetLanguage(buffer) abort
+ return ''
+endfunction
+
+function! ale_linters#typescript#tsserver#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'typescript_tsserver', [
+ \ 'node_modules/.bin/tsserver',
+ \])
+endfunction
+
+call ale#linter#Define('typescript', {
+\ 'name': 'tsserver',
+\ 'lsp': 'tsserver',
+\ 'executable_callback': 'ale_linters#typescript#tsserver#GetExecutable',
+\ 'command_callback': 'ale_linters#typescript#tsserver#GetExecutable',
+\ 'project_root_callback': 'ale_linters#typescript#tsserver#GetProjectRoot',
+\ 'language_callback': 'ale_linters#typescript#tsserver#GetLanguage',
+\})
diff --git a/vim/bundle/ale/ale_linters/typescript/typecheck.vim b/vim/bundle/ale/ale_linters/typescript/typecheck.vim
new file mode 100644
index 0000000..2f18691
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/typescript/typecheck.vim
@@ -0,0 +1,33 @@
+" Author: Prashanth Chandra https://github.com/prashcr, Aleh Kashnikau https://github.com/mkusher
+" Description: type checker for TypeScript files
+
+function! ale_linters#typescript#typecheck#Handle(buffer, lines) abort
+ " Matches patterns like the following:
+ "
+ " hello.ts[7, 41]: Property 'a' does not exist on type 'A'
+ " hello.ts[16, 7]: Type 'A' is not assignable to type 'B'
+ "
+ let l:pattern = '.\+\.ts\[\(\d\+\), \(\d\+\)\]: \(.\+\)'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:line = l:match[1] + 0
+ let l:column = l:match[2] + 0
+ let l:text = l:match[3]
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'col': l:column,
+ \ 'text': l:text,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('typescript', {
+\ 'name': 'typecheck',
+\ 'executable': 'typecheck',
+\ 'command': 'typecheck %s',
+\ 'callback': 'ale_linters#typescript#typecheck#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/verilog/iverilog.vim b/vim/bundle/ale/ale_linters/verilog/iverilog.vim
new file mode 100644
index 0000000..18769d5
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/verilog/iverilog.vim
@@ -0,0 +1,35 @@
+" Author: Masahiro H https://github.com/mshr-h
+" Description: iverilog for verilog files
+
+function! ale_linters#verilog#iverilog#Handle(buffer, lines) abort
+ " Look for lines like the following.
+ "
+ " tb_me_top.v:37: warning: Instantiating module me_top with dangling input port 1 (rst_n) floating.
+ " tb_me_top.v:17: syntax error
+ " memory_single_port.v:2: syntax error
+ " tb_me_top.v:17: error: Invalid module instantiation
+ let l:pattern = '^[^:]\+:\(\d\+\): \(warning\|error\|syntax error\)\(: \(.\+\)\)\?'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:line = l:match[1] + 0
+ let l:type = l:match[2] =~# 'error' ? 'E' : 'W'
+ let l:text = l:match[2] is# 'syntax error' ? 'syntax error' : l:match[4]
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'text': l:text,
+ \ 'type': l:type,
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('verilog', {
+\ 'name': 'iverilog',
+\ 'output_stream': 'stderr',
+\ 'executable': 'iverilog',
+\ 'command': 'iverilog -t null -Wall %t',
+\ 'callback': 'ale_linters#verilog#iverilog#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/verilog/verilator.vim b/vim/bundle/ale/ale_linters/verilog/verilator.vim
new file mode 100644
index 0000000..6053da0
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/verilog/verilator.vim
@@ -0,0 +1,59 @@
+" Author: Masahiro H https://github.com/mshr-h
+" Description: verilator for verilog files
+
+" Set this option to change Verilator lint options
+if !exists('g:ale_verilog_verilator_options')
+ let g:ale_verilog_verilator_options = ''
+endif
+
+function! ale_linters#verilog#verilator#GetCommand(buffer) abort
+ let l:filename = tempname() . '_verilator_linted.v'
+
+ " Create a special filename, so we can detect it in the handler.
+ call ale#engine#ManageFile(a:buffer, l:filename)
+ let l:lines = getbufline(a:buffer, 1, '$')
+ call ale#util#Writefile(a:buffer, l:lines, l:filename)
+
+ return 'verilator --lint-only -Wall -Wno-DECLFILENAME '
+ \ . ale#Var(a:buffer, 'verilog_verilator_options') .' '
+ \ . ale#Escape(l:filename)
+endfunction
+
+function! ale_linters#verilog#verilator#Handle(buffer, lines) abort
+ " Look for lines like the following.
+ "
+ " %Error: addr_gen.v:3: syntax error, unexpected IDENTIFIER
+ " %Warning-WIDTH: addr_gen.v:26: Operator ASSIGNDLY expects 12 bits on the Assign RHS, but Assign RHS's CONST '20'h0' generates 20 bits.
+ " %Warning-UNUSED: test.v:3: Signal is not used: a
+ " %Warning-UNDRIVEN: test.v:3: Signal is not driven: clk
+ " %Warning-UNUSED: test.v:4: Signal is not used: dout
+ " %Warning-BLKSEQ: test.v:10: Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).
+ let l:pattern = '^%\(Warning\|Error\)[^:]*:\([^:]\+\):\(\d\+\): \(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:line = l:match[3] + 0
+ let l:type = l:match[1] is# 'Error' ? 'E' : 'W'
+ let l:text = l:match[4]
+ let l:file = l:match[2]
+
+ if l:file =~# '_verilator_linted.v'
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'text': l:text,
+ \ 'type': l:type,
+ \})
+ endif
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('verilog', {
+\ 'name': 'verilator',
+\ 'output_stream': 'stderr',
+\ 'executable': 'verilator',
+\ 'command_callback': 'ale_linters#verilog#verilator#GetCommand',
+\ 'callback': 'ale_linters#verilog#verilator#Handle',
+\ 'read_buffer': 0,
+\})
diff --git a/vim/bundle/ale/ale_linters/vim/vint.vim b/vim/bundle/ale/ale_linters/vim/vint.vim
new file mode 100644
index 0000000..adf2b4a
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/vim/vint.vim
@@ -0,0 +1,73 @@
+" Author: w0rp , KabbAmine
+" Description: This file adds support for checking Vim code with Vint.
+
+" This flag can be used to change enable/disable style issues.
+let g:ale_vim_vint_show_style_issues =
+\ get(g:, 'ale_vim_vint_show_style_issues', 1)
+let s:enable_neovim = has('nvim') ? ' --enable-neovim ' : ''
+let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})"'
+let s:vint_version = []
+
+function! ale_linters#vim#vint#VersionCommand(buffer) abort
+ if empty(s:vint_version)
+ " Check the Vint version if we haven't checked it already.
+ return 'vint --version'
+ endif
+
+ return ''
+endfunction
+
+function! ale_linters#vim#vint#GetCommand(buffer, version_output) abort
+ if empty(s:vint_version) && !empty(a:version_output)
+ " Parse the version out of the --version output.
+ let s:vint_version = ale#semver#Parse(join(a:version_output, "\n"))
+ endif
+
+ let l:can_use_no_color_flag = empty(s:vint_version)
+ \ || ale#semver#GreaterOrEqual(s:vint_version, [0, 3, 7])
+
+ let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w'
+
+ return 'vint '
+ \ . l:warning_flag . ' '
+ \ . (l:can_use_no_color_flag ? '--no-color ' : '')
+ \ . s:enable_neovim
+ \ . s:format
+ \ . ' %t'
+endfunction
+
+let s:word_regex_list = [
+\ '\v^Undefined variable: ([^ ]+)',
+\ '\v^Make the scope explicit like ...([^ ]+). ',
+\ '\v^.*start with a capital or contain a colon: ([^ ]+)',
+\ '\v.*instead of .(\=[=~]).',
+\]
+
+function! ale_linters#vim#vint#Handle(buffer, lines) abort
+ let l:loclist = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines)
+
+ for l:item in l:loclist
+ let l:match = []
+
+ for l:regex in s:word_regex_list
+ let l:match = matchlist(l:item.text, l:regex)
+
+ if !empty(l:match)
+ let l:item.end_col = l:item.col + len(l:match[1]) - 1
+ break
+ endif
+ endfor
+ endfor
+
+ return l:loclist
+endfunction
+
+call ale#linter#Define('vim', {
+\ 'name': 'vint',
+\ 'executable': 'vint',
+\ 'command_chain': [
+\ {'callback': 'ale_linters#vim#vint#VersionCommand', 'output_stream': 'stderr'},
+\ {'callback': 'ale_linters#vim#vint#GetCommand', 'output_stream': 'stdout'},
+\ ],
+\ 'callback': 'ale_linters#vim#vint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/xhtml/proselint.vim b/vim/bundle/ale/ale_linters/xhtml/proselint.vim
new file mode 100644
index 0000000..dfad921
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/xhtml/proselint.vim
@@ -0,0 +1,9 @@
+" Author: Daniel M. Capella https://github.com/polyzen
+" Description: proselint for XHTML files
+
+call ale#linter#Define('xhtml', {
+\ 'name': 'proselint',
+\ 'executable': 'proselint',
+\ 'command': 'proselint %t',
+\ 'callback': 'ale#handlers#unix#HandleAsWarning',
+\})
diff --git a/vim/bundle/ale/ale_linters/xml/xmllint.vim b/vim/bundle/ale/ale_linters/xml/xmllint.vim
new file mode 100644
index 0000000..63d7f76
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/xml/xmllint.vim
@@ -0,0 +1,69 @@
+" Author: q12321q
+" Description: This file adds support for checking XML code with xmllint.
+
+" CLI options
+let g:ale_xml_xmllint_executable = get(g:, 'ale_xml_xmllint_executable', 'xmllint')
+let g:ale_xml_xmllint_options = get(g:, 'ale_xml_xmllint_options', '')
+
+function! ale_linters#xml#xmllint#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'xml_xmllint_executable')
+endfunction
+
+function! ale_linters#xml#xmllint#GetCommand(buffer) abort
+ return ale#Escape(ale_linters#xml#xmllint#GetExecutable(a:buffer))
+ \ . ' ' . ale#Var(a:buffer, 'xml_xmllint_options')
+ \ . ' --noout -'
+endfunction
+
+function! ale_linters#xml#xmllint#Handle(buffer, lines) abort
+ " Matches patterns lines like the following:
+ " file/path:123: error level : error message
+ let l:pattern_message = '\v^([^:]+):(\d+):\s*(([^:]+)\s*:\s+.*)$'
+
+ " parse column token line like that:
+ " file/path:123: parser error : Opening and ending tag mismatch: foo line 1 and bar
+ "
+ " ^
+ let l:pattern_column_token = '\v^\s*\^$'
+
+ let l:output = []
+
+ for l:line in a:lines
+
+ " Parse error/warning lines
+ let l:match_message = matchlist(l:line, l:pattern_message)
+ if !empty(l:match_message)
+ let l:line = l:match_message[2] + 0
+ let l:type = l:match_message[4] =~? 'warning' ? 'W' : 'E'
+ let l:text = l:match_message[3]
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'text': l:text,
+ \ 'type': l:type,
+ \})
+
+ continue
+ endif
+
+ " Parse column position
+ let l:match_column_token = matchlist(l:line, l:pattern_column_token)
+ if !empty(l:output) && !empty(l:match_column_token)
+ let l:previous = l:output[len(l:output) - 1]
+ let l:previous['col'] = len(l:match_column_token[0])
+
+ continue
+ endif
+
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('xml', {
+\ 'name': 'xmllint',
+\ 'output_stream': 'stderr',
+\ 'executable_callback': 'ale_linters#xml#xmllint#GetExecutable',
+\ 'command_callback': 'ale_linters#xml#xmllint#GetCommand',
+\ 'callback': 'ale_linters#xml#xmllint#Handle',
+\ })
diff --git a/vim/bundle/ale/ale_linters/yaml/swaglint.vim b/vim/bundle/ale/ale_linters/yaml/swaglint.vim
new file mode 100644
index 0000000..454cad0
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/yaml/swaglint.vim
@@ -0,0 +1,41 @@
+" Author: Matthew Turland
+" Description: This file adds support for linting Swagger / OpenAPI documents using swaglint
+
+call ale#Set('yaml_swaglint_executable', 'swaglint')
+call ale#Set('yaml_swaglint_use_global', 0)
+
+function! ale_linters#yaml#swaglint#GetExecutable(buffer) abort
+ return ale#node#FindExecutable(a:buffer, 'yaml_swaglint', [
+ \ 'node_modules/.bin/swaglint',
+ \])
+endfunction
+
+function! ale_linters#yaml#swaglint#GetCommand(buffer) abort
+ return ale_linters#yaml#swaglint#GetExecutable(a:buffer)
+ \ . ' -r compact --stdin'
+endfunction
+
+function! ale_linters#yaml#swaglint#Handle(buffer, lines) abort
+ let l:pattern = ': \([^\s]\+\) @ \(\d\+\):\(\d\+\) - \(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:obj = {
+ \ 'type': l:match[1] is# 'error' ? 'E' : 'W',
+ \ 'lnum': l:match[2] + 0,
+ \ 'col': l:match[3] + 0,
+ \ 'text': l:match[4],
+ \}
+
+ call add(l:output, l:obj)
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('yaml', {
+\ 'name': 'swaglint',
+\ 'executable_callback': 'ale_linters#yaml#swaglint#GetExecutable',
+\ 'command_callback': 'ale_linters#yaml#swaglint#GetCommand',
+\ 'callback': 'ale_linters#yaml#swaglint#Handle',
+\})
diff --git a/vim/bundle/ale/ale_linters/yaml/yamllint.vim b/vim/bundle/ale/ale_linters/yaml/yamllint.vim
new file mode 100644
index 0000000..731f801
--- /dev/null
+++ b/vim/bundle/ale/ale_linters/yaml/yamllint.vim
@@ -0,0 +1,48 @@
+" Author: KabbAmine
+
+let g:ale_yaml_yamllint_executable =
+\ get(g:, 'ale_yaml_yamllint_executable', 'yamllint')
+
+let g:ale_yaml_yamllint_options =
+\ get(g:, 'ale_yaml_yamllint_options', '')
+
+function! ale_linters#yaml#yamllint#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'yaml_yamllint_executable')
+endfunction
+
+function! ale_linters#yaml#yamllint#GetCommand(buffer) abort
+ return ale_linters#yaml#yamllint#GetExecutable(a:buffer)
+ \ . ' ' . ale#Var(a:buffer, 'yaml_yamllint_options')
+ \ . ' -f parsable %t'
+endfunction
+
+function! ale_linters#yaml#yamllint#Handle(buffer, lines) abort
+ " Matches patterns line the following:
+ " something.yaml:1:1: [warning] missing document start "---" (document-start)
+ " something.yml:2:1: [error] syntax error: expected the node content, but found ''
+ let l:pattern = '^.*:\(\d\+\):\(\d\+\): \[\(error\|warning\)\] \(.\+\)$'
+ let l:output = []
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ let l:line = l:match[1] + 0
+ let l:col = l:match[2] + 0
+ let l:type = l:match[3]
+ let l:text = l:match[4]
+
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'col': l:col,
+ \ 'text': l:text,
+ \ 'type': l:type is# 'error' ? 'E' : 'W',
+ \})
+ endfor
+
+ return l:output
+endfunction
+
+call ale#linter#Define('yaml', {
+\ 'name': 'yamllint',
+\ 'executable_callback': 'ale_linters#yaml#yamllint#GetExecutable',
+\ 'command_callback': 'ale_linters#yaml#yamllint#GetCommand',
+\ 'callback': 'ale_linters#yaml#yamllint#Handle',
+\})
diff --git a/vim/bundle/ale/autoload/ale.vim b/vim/bundle/ale/autoload/ale.vim
new file mode 100644
index 0000000..6941a9a
--- /dev/null
+++ b/vim/bundle/ale/autoload/ale.vim
@@ -0,0 +1,219 @@
+" Author: w0rp , David Alexander
+" Description: Primary code path for the plugin
+" Manages execution of linters when requested by autocommands
+
+let s:lint_timer = -1
+let s:queued_buffer_number = -1
+let s:should_lint_file_for_buffer = {}
+let s:error_delay_ms = 1000 * 60 * 2
+
+let s:timestamp_map = {}
+
+" Given a key for a script variable for tracking the time to wait until
+" a given function should be called, a funcref for a function to call, and
+" a List of arguments, call the function and return whatever value it returns.
+"
+" If the function throws an exception, then the function will not be called
+" for a while, and 0 will be returned instead.
+function! ale#CallWithCooldown(timestamp_key, func, arglist) abort
+ let l:now = ale#util#ClockMilliseconds()
+
+ if l:now < get(s:timestamp_map, a:timestamp_key, -1)
+ return 0
+ endif
+
+ let s:timestamp_map[a:timestamp_key] = l:now + s:error_delay_ms
+
+ let l:return_value = call(a:func, a:arglist)
+
+ let s:timestamp_map[a:timestamp_key] = -1
+
+ return l:return_value
+endfunction
+
+" Return 1 if a file is too large for ALE to handle.
+function! ale#FileTooLarge() abort
+ let l:max = ale#Var(bufnr(''), 'maximum_file_size')
+
+ return l:max > 0 ? (line2byte(line('$') + 1) > l:max) : 0
+endfunction
+
+" A function for checking various conditions whereby ALE just shouldn't
+" attempt to do anything, say if particular buffer types are open in Vim.
+function! ale#ShouldDoNothing(buffer) abort
+ " Do nothing for blacklisted files
+ " OR if ALE is running in the sandbox
+ return index(g:ale_filetype_blacklist, &filetype) >= 0
+ \ || (exists('*getcmdwintype') && !empty(getcmdwintype()))
+ \ || ale#util#InSandbox()
+ \ || !ale#Var(a:buffer, 'enabled')
+ \ || ale#FileTooLarge()
+ \ || getbufvar(a:buffer, '&l:statusline') =~# 'CtrlPMode.*funky'
+endfunction
+
+" (delay, [linting_flag, buffer_number])
+function! ale#Queue(delay, ...) abort
+ if a:0 > 2
+ throw 'too many arguments!'
+ endif
+
+ " Default linting_flag to ''
+ let l:linting_flag = get(a:000, 0, '')
+ let l:buffer = get(a:000, 1, bufnr(''))
+
+ return ale#CallWithCooldown(
+ \ 'dont_queue_until',
+ \ function('s:ALEQueueImpl'),
+ \ [a:delay, l:linting_flag, l:buffer],
+ \)
+endfunction
+
+function! s:ALEQueueImpl(delay, linting_flag, buffer) abort
+ if a:linting_flag isnot# '' && a:linting_flag isnot# 'lint_file'
+ throw "linting_flag must be either '' or 'lint_file'"
+ endif
+
+ if type(a:buffer) != type(0)
+ throw 'buffer_number must be a Number'
+ endif
+
+ if ale#ShouldDoNothing(a:buffer)
+ return
+ endif
+
+ " Remember that we want to check files for this buffer.
+ " We will remember this until we finally run the linters, via any event.
+ if a:linting_flag is# 'lint_file'
+ let s:should_lint_file_for_buffer[bufnr('%')] = 1
+ endif
+
+ if s:lint_timer != -1
+ call timer_stop(s:lint_timer)
+ let s:lint_timer = -1
+ endif
+
+ let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
+
+ " Don't set up buffer data and so on if there are no linters to run.
+ if empty(l:linters)
+ " If we have some previous buffer data, then stop any jobs currently
+ " running and clear everything.
+ if has_key(g:ale_buffer_info, a:buffer)
+ call ale#engine#RunLinters(a:buffer, [], 1)
+ endif
+
+ return
+ endif
+
+ if a:delay > 0
+ let s:queued_buffer_number = a:buffer
+ let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
+ else
+ call ale#Lint(-1, a:buffer)
+ endif
+endfunction
+
+function! ale#Lint(...) abort
+ if a:0 > 1
+ " Use the buffer number given as the optional second argument.
+ let l:buffer = a:2
+ elseif a:0 > 0 && a:1 == s:lint_timer
+ " Use the buffer number for the buffer linting was queued for.
+ let l:buffer = s:queued_buffer_number
+ else
+ " Use the current buffer number.
+ let l:buffer = bufnr('')
+ endif
+
+ return ale#CallWithCooldown(
+ \ 'dont_lint_until',
+ \ function('s:ALELintImpl'),
+ \ [l:buffer],
+ \)
+endfunction
+
+function! s:ALELintImpl(buffer) abort
+ if ale#ShouldDoNothing(a:buffer)
+ return
+ endif
+
+ " Use the filetype from the buffer
+ let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
+ let l:should_lint_file = 0
+
+ " Check if we previously requested checking the file.
+ if has_key(s:should_lint_file_for_buffer, a:buffer)
+ unlet s:should_lint_file_for_buffer[a:buffer]
+ " Lint files if they exist.
+ let l:should_lint_file = filereadable(expand('#' . a:buffer . ':p'))
+ endif
+
+ call ale#engine#RunLinters(a:buffer, l:linters, l:should_lint_file)
+endfunction
+
+" Reset flags indicating that files should be checked for all buffers.
+function! ale#ResetLintFileMarkers() abort
+ let s:should_lint_file_for_buffer = {}
+endfunction
+
+function! ale#ResetErrorDelays() abort
+ let s:timestamp_map = {}
+endfunction
+
+let g:ale_has_override = get(g:, 'ale_has_override', {})
+
+" Call has(), but check a global Dictionary so we can force flags on or off
+" for testing purposes.
+function! ale#Has(feature) abort
+ return get(g:ale_has_override, a:feature, has(a:feature))
+endfunction
+
+" Given a buffer number and a variable name, look for that variable in the
+" buffer scope, then in global scope. If the name does not exist in the global
+" scope, an exception will be thrown.
+"
+" Every variable name will be prefixed with 'ale_'.
+function! ale#Var(buffer, variable_name) abort
+ let l:nr = str2nr(a:buffer)
+ let l:full_name = 'ale_' . a:variable_name
+
+ if bufexists(l:nr)
+ let l:vars = getbufvar(l:nr, '')
+ elseif has_key(g:, 'ale_fix_buffer_data')
+ let l:vars = get(g:ale_fix_buffer_data, l:nr, {'vars': {}}).vars
+ else
+ let l:vars = {}
+ endif
+
+ return get(l:vars, l:full_name, g:[l:full_name])
+endfunction
+
+" Initialize a variable with a default value, if it isn't already set.
+"
+" Every variable name will be prefixed with 'ale_'.
+function! ale#Set(variable_name, default) abort
+ let l:full_name = 'ale_' . a:variable_name
+ let l:value = get(g:, l:full_name, a:default)
+ let g:[l:full_name] = l:value
+
+ return l:value
+endfunction
+
+" Escape a string suitably for each platform.
+" shellescape does not work on Windows.
+function! ale#Escape(str) abort
+ if fnamemodify(&shell, ':t') is? 'cmd.exe'
+ " If the string contains spaces, it will be surrounded by quotes.
+ " Otherwise, special characters will be escaped with carets (^).
+ return substitute(
+ \ a:str =~# ' '
+ \ ? '"' . substitute(a:str, '"', '""', 'g') . '"'
+ \ : substitute(a:str, '\v([&|<>^])', '^\1', 'g'),
+ \ '%',
+ \ '%%',
+ \ 'g',
+ \)
+ endif
+
+ return shellescape (a:str)
+endfunction
diff --git a/vim/bundle/ale/autoload/ale/balloon.vim b/vim/bundle/ale/autoload/ale/balloon.vim
new file mode 100644
index 0000000..41fa95f
--- /dev/null
+++ b/vim/bundle/ale/autoload/ale/balloon.vim
@@ -0,0 +1,21 @@
+" Author: w0rp
+" Description: balloonexpr support for ALE.
+
+function! ale#balloon#MessageForPos(bufnr, lnum, col) abort
+ let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist
+ let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col)
+
+ return l:index >= 0 ? l:loclist[l:index].text : ''
+endfunction
+
+function! ale#balloon#Expr() abort
+ return ale#balloon#MessageForPos(v:beval_bufnr, v:beval_lnum, v:beval_col)
+endfunction
+
+function! ale#balloon#Disable() abort
+ set noballooneval
+endfunction
+
+function! ale#balloon#Enable() abort
+ set ballooneval balloonexpr=ale#balloon#Expr()
+endfunction
diff --git a/vim/bundle/ale/autoload/ale/c.vim b/vim/bundle/ale/autoload/ale/c.vim
new file mode 100644
index 0000000..b9f9439
--- /dev/null
+++ b/vim/bundle/ale/autoload/ale/c.vim
@@ -0,0 +1,91 @@
+" Author: gagbo , w0rp
+" Description: Functions for integrating with C-family linters.
+
+function! ale#c#FindProjectRoot(buffer) abort
+ for l:project_filename in ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt']
+ let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
+
+ if !empty(l:full_path)
+ let l:path = fnamemodify(l:full_path, ':h')
+
+ " Correct .git path detection.
+ if fnamemodify(l:path, ':t') is# '.git'
+ let l:path = fnamemodify(l:path, ':h')
+ endif
+
+ return l:path
+ endif
+ endfor
+
+ return ''
+endfunction
+
+" Given a buffer number, search for a project root, and output a List
+" of directories to include based on some heuristics.
+"
+" For projects with headers in the project root, the project root will
+" be returned.
+"
+" For projects with an 'include' directory, that directory will be returned.
+function! ale#c#FindLocalHeaderPaths(buffer) abort
+ let l:project_root = ale#c#FindProjectRoot(a:buffer)
+
+ if empty(l:project_root)
+ return []
+ endif
+
+ " See if we can find .h files directory in the project root.
+ " If we can, that's our include directory.
+ if !empty(globpath(l:project_root, '*.h', 0))
+ return [l:project_root]
+ endif
+
+ " Look for .hpp files too.
+ if !empty(globpath(l:project_root, '*.hpp', 0))
+ return [l:project_root]
+ endif
+
+ " If we find an 'include' directory in the project root, then use that.
+ if isdirectory(l:project_root . '/include')
+ return [ale#path#Simplify(l:project_root . '/include')]
+ endif
+
+ return []
+endfunction
+
+" Given a List of include paths, create a string containing the -I include
+" options for those paths, with the paths escaped for use in the shell.
+function! ale#c#IncludeOptions(include_paths) abort
+ let l:option_list = []
+
+ for l:path in a:include_paths
+ call add(l:option_list, '-I' . ale#Escape(l:path))
+ endfor
+
+ if empty(l:option_list)
+ return ''
+ endif
+
+ return ' ' . join(l:option_list) . ' '
+endfunction
+
+let g:ale_c_build_dir_names = get(g:, 'ale_c_build_dir_names', [
+\ 'build',
+\ 'bin',
+\])
+
+" Given a buffer number, find the build subdirectory with compile commands
+" The subdirectory is returned without the trailing /
+function! ale#c#FindCompileCommands(buffer) abort
+ for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
+ for l:dirname in ale#Var(a:buffer, 'c_build_dir_names')
+ let l:c_build_dir = l:path . '/' . l:dirname
+
+ if filereadable(l:c_build_dir . '/compile_commands.json')
+ return l:c_build_dir
+ endif
+ endfor
+ endfor
+
+ return ''
+endfunction
diff --git a/vim/bundle/ale/autoload/ale/command.vim b/vim/bundle/ale/autoload/ale/command.vim
new file mode 100644
index 0000000..f8d04ff
--- /dev/null
+++ b/vim/bundle/ale/autoload/ale/command.vim
@@ -0,0 +1,57 @@
+" Author: w0rp
+" Description: Special command formatting for creating temporary files and
+" passing buffer filenames easily.
+
+function! s:TemporaryFilename(buffer) abort
+ let l:filename = fnamemodify(bufname(a:buffer), ':t')
+
+ if empty(l:filename)
+ " If the buffer's filename is empty, create a dummy filename.
+ let l:ft = getbufvar(a:buffer, '&filetype')
+ let l:filename = 'file' . ale#filetypes#GuessExtension(l:ft)
+ endif
+
+ " Create a temporary filename, /
+ " The file itself will not be created by this function.
+ return tempname() . (has('win32') ? '\' : '/') . l:filename
+endfunction
+
+" Given a command string, replace every...
+" %s -> with the current filename
+" %t -> with the name of an unused file in a temporary directory
+" %% -> with a literal %
+function! ale#command#FormatCommand(buffer, command, pipe_file_if_needed) abort
+ let l:temporary_file = ''
+ let l:command = a:command
+
+ " First replace all uses of %%, used for literal percent characters,
+ " with an ugly string.
+ let l:command = substitute(l:command, '%%', '<>', 'g')
+
+ " Replace all %s occurences in the string with the name of the current
+ " file.
+ if l:command =~# '%s'
+ let l:filename = fnamemodify(bufname(a:buffer), ':p')
+ let l:command = substitute(l:command, '%s', '\=ale#Escape(l:filename)', 'g')
+ endif
+
+ if l:command =~# '%t'
+ " Create a temporary filename, /
+ " The file itself will not be created by this function.
+ let l:temporary_file = s:TemporaryFilename(a:buffer)
+ let l:command = substitute(l:command, '%t', '\=ale#Escape(l:temporary_file)', 'g')
+ endif
+
+ " Finish formatting so %% becomes %.
+ let l:command = substitute(l:command, '<>', '%', 'g')
+
+ if a:pipe_file_if_needed && empty(l:temporary_file)
+ " If we are to send the Vim buffer to a command, we'll do it
+ " in the shell. We'll write out the file to a temporary file,
+ " and then read it back in, in the shell.
+ let l:temporary_file = s:TemporaryFilename(a:buffer)
+ let l:command = l:command . ' < ' . ale#Escape(l:temporary_file)
+ endif
+
+ return [l:temporary_file, l:command]
+endfunction
diff --git a/vim/bundle/ale/autoload/ale/completion.vim b/vim/bundle/ale/autoload/ale/completion.vim
new file mode 100644
index 0000000..9f4e3c2
--- /dev/null
+++ b/vim/bundle/ale/autoload/ale/completion.vim
@@ -0,0 +1,339 @@
+" Author: w0rp
+" Description: Completion support for LSP linters
+
+let s:timer_id = -1
+
+function! s:GetRegex(map, filetype) abort
+ for l:part in reverse(split(a:filetype, '\.'))
+ let l:regex = get(a:map, l:part, [])
+
+ if !empty(l:regex)
+ return l:regex
+ endif
+ endfor
+
+ return ''
+endfunction
+
+" Regular expressions for checking the characters in the line before where
+" the insert cursor is. If one of these matches, we'll check for completions.
+let s:should_complete_map = {
+\ 'javascript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$',
+\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$',
+\}
+
+" Check if we should look for completions for a language.
+function! ale#completion#GetPrefix(filetype, line, column) abort
+ let l:regex = s:GetRegex(s:should_complete_map, a:filetype)
+ " The column we're using completions for is where we are inserting text,
+ " like so:
+ " abc
+ " ^
+ " So we need check the text in the column before that position.
+ return matchstr(getline(a:line)[: a:column - 2], l:regex)
+endfunction
+
+" Regular expressions for finding the start column to replace with completion.
+let s:omni_start_map = {
+\ 'javascript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$',
+\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$',
+\}
+
+function! ale#completion#Filter(suggestions, prefix) abort
+ " For completing...
+ " foo.
+ " ^
+ " We need to include all of the given suggestions.
+ if a:prefix is# '.'
+ return a:suggestions
+ endif
+
+ let l:filtered_suggestions = []
+
+ " Filter suggestions down to those starting with the prefix we used for
+ " finding suggestions in the first place.
+ "
+ " Some completion tools will include suggestions which don't even start
+ " with the characters we have already typed.
+ for l:item in a:suggestions
+ " A List of String values or a List of completion item Dictionaries
+ " is accepted here.
+ let l:word = type(l:item) == type('') ? l:item : l:item.word
+
+ " Add suggestions if the suggestion starts with a case-insensitive
+ " match for the prefix.
+ if l:word[: len(a:prefix) - 1] is? a:prefix
+ call add(l:filtered_suggestions, l:item)
+ endif
+ endfor
+
+ return l:filtered_suggestions
+endfunction
+
+function! s:ReplaceCompleteopt() abort
+ if !exists('b:ale_old_completopt')
+ let b:ale_old_completopt = &l:completeopt
+ endif
+
+ let &l:completeopt = 'menu,menuone,preview,noselect,noinsert'
+endfunction
+
+function! ale#completion#OmniFunc(findstart, base) abort
+ if a:findstart
+ let l:line = b:ale_completion_info.line
+ let l:column = b:ale_completion_info.column
+ let l:regex = s:GetRegex(s:omni_start_map, &filetype)
+ let l:up_to_column = getline(l:line)[: l:column - 2]
+ let l:match = matchstr(l:up_to_column, l:regex)
+
+ return l:column - len(l:match) - 1
+ else
+ " Parse a new response if there is one.
+ if exists('b:ale_completion_response')
+ \&& exists('b:ale_completion_parser')
+ let l:response = b:ale_completion_response
+ let l:parser = b:ale_completion_parser
+
+ unlet b:ale_completion_response
+ unlet b:ale_completion_parser
+
+ let b:ale_completion_result = function(l:parser)(l:response)
+ endif
+
+ call s:ReplaceCompleteopt()
+
+ return get(b:, 'ale_completion_result', [])
+ endif
+endfunction
+
+function! ale#completion#Show(response, completion_parser) abort
+ " Remember the old omnifunc value, if there is one.
+ " If we don't store an old one, we'll just never reset the option.
+ " This will stop some random exceptions from appearing.
+ if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
+ let b:ale_old_omnifunc = &l:omnifunc
+ endif
+
+ " Set the list in the buffer, temporarily replace omnifunc with our
+ " function, and then start omni-completion.
+ let b:ale_completion_response = a:response
+ let b:ale_completion_parser = a:completion_parser
+ let &l:omnifunc = 'ale#completion#OmniFunc'
+ call s:ReplaceCompleteopt()
+ call ale#util#FeedKeys("\\", 'n')
+endfunction
+
+function! s:CompletionStillValid(request_id) abort
+ let [l:line, l:column] = getcurpos()[1:2]
+
+ return has_key(b:, 'ale_completion_info')
+ \&& b:ale_completion_info.request_id == a:request_id
+ \&& b:ale_completion_info.line == l:line
+ \&& b:ale_completion_info.column == l:column
+endfunction
+
+function! ale#completion#ParseTSServerCompletions(response) abort
+ let l:names = []
+
+ for l:suggestion in a:response.body
+ call add(l:names, l:suggestion.name)
+ endfor
+
+ return l:names
+endfunction
+
+function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
+ let l:results = []
+
+ for l:suggestion in a:response.body
+ let l:displayParts = []
+
+ for l:part in l:suggestion.displayParts
+ call add(l:displayParts, l:part.text)
+ endfor
+
+ " Each one of these parts has 'kind' properties
+ let l:documentationParts = []
+
+ for l:part in get(l:suggestion, 'documentation', [])
+ call add(l:documentationParts, l:part.text)
+ endfor
+
+ if l:suggestion.kind is# 'clasName'
+ let l:kind = 'f'
+ elseif l:suggestion.kind is# 'parameterName'
+ let l:kind = 'f'
+ else
+ let l:kind = 'v'
+ endif
+
+ " See :help complete-items
+ call add(l:results, {
+ \ 'word': l:suggestion.name,
+ \ 'kind': l:kind,
+ \ 'icase': 1,
+ \ 'menu': join(l:displayParts, ''),
+ \ 'info': join(l:documentationParts, ''),
+ \})
+ endfor
+
+ return l:results
+endfunction
+
+function! ale#completion#HandleTSServerLSPResponse(conn_id, response) abort
+ if !s:CompletionStillValid(get(a:response, 'request_seq'))
+ return
+ endif
+
+ if !has_key(a:response, 'body')
+ return
+ endif
+
+ let l:command = get(a:response, 'command', '')
+
+ if l:command is# 'completions'
+ let l:names = ale#completion#Filter(
+ \ ale#completion#ParseTSServerCompletions(a:response),
+ \ b:ale_completion_info.prefix,
+ \)[: g:ale_completion_max_suggestions - 1]
+
+ if !empty(l:names)
+ let b:ale_completion_info.request_id = ale#lsp#Send(
+ \ b:ale_completion_info.conn_id,
+ \ ale#lsp#tsserver_message#CompletionEntryDetails(
+ \ bufnr(''),
+ \ b:ale_completion_info.line,
+ \ b:ale_completion_info.column,
+ \ l:names,
+ \ ),
+ \)
+ endif
+ elseif l:command is# 'completionEntryDetails'
+ call ale#completion#Show(
+ \ a:response,
+ \ 'ale#completion#ParseTSServerCompletionEntryDetails',
+ \)
+ endif
+endfunction
+
+function! s:GetLSPCompletions(linter) abort
+ let l:buffer = bufnr('')
+ let l:lsp_details = ale#linter#StartLSP(
+ \ l:buffer,
+ \ a:linter,
+ \ function('ale#completion#HandleTSServerLSPResponse'),
+ \)
+
+ if empty(l:lsp_details)
+ return 0
+ endif
+
+ let l:id = l:lsp_details.connection_id
+ let l:command = l:lsp_details.command
+ let l:root = l:lsp_details.project_root
+
+ let l:message = ale#lsp#tsserver_message#Completions(
+ \ l:buffer,
+ \ b:ale_completion_info.line,
+ \ b:ale_completion_info.column,
+ \ b:ale_completion_info.prefix,
+ \)
+ let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
+
+ if l:request_id
+ let b:ale_completion_info.conn_id = l:id
+ let b:ale_completion_info.request_id = l:request_id
+ endif
+endfunction
+
+function! ale#completion#GetCompletions() abort
+ let [l:line, l:column] = getcurpos()[1:2]
+
+ let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
+
+ if empty(l:prefix)
+ return
+ endif
+
+ let b:ale_completion_info = {
+ \ 'line': l:line,
+ \ 'column': l:column,
+ \ 'prefix': l:prefix,
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \}
+
+ for l:linter in ale#linter#Get(&filetype)
+ if l:linter.lsp is# 'tsserver'
+ call s:GetLSPCompletions(l:linter)
+ endif
+ endfor
+endfunction
+
+function! s:TimerHandler(...) abort
+ let s:timer_id = -1
+
+ let [l:line, l:column] = getcurpos()[1:2]
+
+ " When running the timer callback, we have to be sure that the cursor
+ " hasn't moved from where it was when we requested completions by typing.
+ if s:timer_pos == [l:line, l:column]
+ call ale#completion#GetCompletions()
+ endif
+endfunction
+
+function! ale#completion#Queue() abort
+ let s:timer_pos = getcurpos()[1:2]
+
+ " If we changed the text again while we're still waiting for a response,
+ " then invalidate the requests before the timer ticks again.
+ if exists('b:ale_completion_info')
+ let b:ale_completion_info.request_id = 0
+ endif
+
+ if s:timer_id != -1
+ call timer_stop(s:timer_id)
+ endif
+
+ let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler'))
+endfunction
+
+function! ale#completion#Done() abort
+ silent! pclose
+
+ " Reset settings when completion is done.
+ if exists('b:ale_old_omnifunc')
+ let &l:omnifunc = b:ale_old_omnifunc
+ unlet b:ale_old_omnifunc
+ endif
+
+ if exists('b:ale_old_completopt')
+ let &l:completeopt = b:ale_old_completopt
+ unlet b:ale_old_completopt
+ endif
+endfunction
+
+function! s:Setup(enabled) abort
+ augroup ALECompletionGroup
+ autocmd!
+
+ if a:enabled
+ autocmd TextChangedI * call ale#completion#Queue()
+ autocmd CompleteDone * call ale#completion#Done()
+ endif
+ augroup END
+
+ if !a:enabled
+ augroup! ALECompletionGroup
+ endif
+endfunction
+
+function! ale#completion#Enable() abort
+ let g:ale_completion_enabled = 1
+ call s:Setup(1)
+endfunction
+
+function! ale#completion#Disable() abort
+ let g:ale_completion_enabled = 0
+ call s:Setup(0)
+endfunction
diff --git a/vim/bundle/ale/autoload/ale/cursor.vim b/vim/bundle/ale/autoload/ale/cursor.vim
new file mode 100644
index 0000000..340432f
--- /dev/null
+++ b/vim/bundle/ale/autoload/ale/cursor.vim
@@ -0,0 +1,159 @@
+" Author: w0rp
+" Description: Echoes lint message for the current line, if any
+
+let s:cursor_timer = -1
+let s:last_pos = [0, 0, 0]
+let s:error_delay_ms = 1000 * 60 * 2
+
+if !exists('s:dont_queue_until')
+ let s:dont_queue_until = -1
+endif
+
+if !exists('s:dont_echo_until')
+ let s:dont_echo_until = -1
+endif
+
+" Return a formatted message according to g:ale_echo_msg_format variable
+function! s:GetMessage(linter, type, text) abort
+ let l:msg = g:ale_echo_msg_format
+ let l:type = a:type is# 'E'
+ \ ? g:ale_echo_msg_error_str
+ \ : g:ale_echo_msg_warning_str
+
+ " Replace handlers if they exist
+ for [l:k, l:v] in items({'linter': a:linter, 'severity': l:type})
+ let l:msg = substitute(l:msg, '\V%' . l:k . '%', l:v, '')
+ endfor
+
+ return printf(l:msg, a:text)
+endfunction
+
+function! s:EchoWithShortMess(setting, message) abort
+ " We need to remember the setting for shormess and reset it again.
+ let l:shortmess_options = getbufvar('%', '&shortmess')
+
+ try
+ " Turn shortmess on or off.
+ if a:setting is# 'on'
+ setlocal shortmess+=T
+ " echomsg is needed for the message to get truncated and appear in
+ " the message history.
+ exec "norm! :echomsg a:message\n"
+ elseif a:setting is# 'off'
+ setlocal shortmess-=T
+ " Regular echo is needed for printing newline characters.
+ echo a:message
+ else
+ throw 'Invalid setting: ' . string(a:setting)
+ endif
+ finally
+ call setbufvar('%', '&shortmess', l:shortmess_options)
+ endtry
+endfunction
+
+function! ale#cursor#TruncatedEcho(message) abort
+ let l:message = a:message
+ " Change tabs to spaces.
+ let l:message = substitute(l:message, "\t", ' ', 'g')
+ " Remove any newlines in the message.
+ let l:message = substitute(l:message, "\n", '', 'g')
+
+ call s:EchoWithShortMess('on', l:message)
+endfunction
+
+function! s:FindItemAtCursor() abort
+ let l:buf = bufnr('')
+ let l:info = get(g:ale_buffer_info, l:buf, {})
+ let l:loclist = get(l:info, 'loclist', [])
+ let l:pos = getcurpos()
+ let l:index = ale#util#BinarySearch(l:loclist, l:buf, l:pos[1], l:pos[2])
+ let l:loc = l:index >= 0 ? l:loclist[l:index] : {}
+
+ return [l:info, l:loc]
+endfunction
+
+function! s:StopCursorTimer() abort
+ if s:cursor_timer != -1
+ call timer_stop(s:cursor_timer)
+ let s:cursor_timer = -1
+ endif
+endfunction
+
+function! ale#cursor#EchoCursorWarning(...) abort
+ return ale#CallWithCooldown('dont_echo_until', function('s:EchoImpl'), [])
+endfunction
+
+function! s:EchoImpl() abort
+ if ale#ShouldDoNothing(bufnr(''))
+ return
+ endif
+
+ " Only echo the warnings in normal mode, otherwise we will get problems.
+ if mode() isnot# 'n'
+ return
+ endif
+
+ let [l:info, l:loc] = s:FindItemAtCursor()
+
+ if !empty(l:loc)
+ let l:msg = s:GetMessage(l:loc.linter_name, l:loc.type, l:loc.text)
+ call ale#cursor#TruncatedEcho(l:msg)
+ let l:info.echoed = 1
+ elseif get(l:info, 'echoed')
+ " We'll only clear the echoed message when moving off errors once,
+ " so we don't continually clear the echo line.
+ echo
+ let l:info.echoed = 0
+ endif
+endfunction
+
+function! ale#cursor#EchoCursorWarningWithDelay() abort
+ return ale#CallWithCooldown(
+ \ 'dont_echo_with_delay_until',
+ \ function('s:EchoWithDelayImpl'),
+ \ [],
+ \)
+endfunction
+
+function! s:EchoWithDelayImpl() abort
+ if ale#ShouldDoNothing(bufnr(''))
+ return
+ endif
+
+ call s:StopCursorTimer()
+
+ let l:pos = getcurpos()[0:2]
+
+ " Check the current buffer, line, and column number against the last
+ " recorded position. If the position has actually changed, *then*
+ " we should echo something. Otherwise we can end up doing processing
+ " the echo message far too frequently.
+ if l:pos != s:last_pos
+ let s:last_pos = l:pos
+ let s:cursor_timer = timer_start(10, function('ale#cursor#EchoCursorWarning'))
+ endif
+endfunction
+
+function! ale#cursor#ShowCursorDetail() abort
+ if ale#ShouldDoNothing(bufnr(''))
+ return
+ endif
+
+ " Only echo the warnings in normal mode, otherwise we will get problems.
+ if mode() isnot# 'n'
+ return
+ endif
+
+ call s:StopCursorTimer()
+
+ let [l:info, l:loc] = s:FindItemAtCursor()
+
+ if !empty(l:loc)
+ let l:message = get(l:loc, 'detail', l:loc.text)
+
+ call s:EchoWithShortMess('off', l:message)
+
+ " Set the echo marker, so we can clear it by moving the cursor.
+ let l:info.echoed = 1
+ endif
+endfunction
diff --git a/vim/bundle/ale/autoload/ale/debugging.vim b/vim/bundle/ale/autoload/ale/debugging.vim
new file mode 100644
index 0000000..7454bb1
--- /dev/null
+++ b/vim/bundle/ale/autoload/ale/debugging.vim
@@ -0,0 +1,183 @@
+" Author: w0rp
+" Description: This file implements debugging information for ALE
+
+let s:global_variable_list = [
+\ 'ale_echo_cursor',
+\ 'ale_echo_msg_error_str',
+\ 'ale_echo_msg_format',
+\ 'ale_echo_msg_warning_str',
+\ 'ale_enabled',
+\ 'ale_fix_on_save',
+\ 'ale_fixers',
+\ 'ale_keep_list_window_open',
+\ 'ale_lint_delay',
+\ 'ale_lint_on_enter',
+\ 'ale_lint_on_save',
+\ 'ale_lint_on_text_changed',
+\ 'ale_linter_aliases',
+\ 'ale_linters',
+\ 'ale_open_list',
+\ 'ale_set_highlights',
+\ 'ale_set_loclist',
+\ 'ale_set_quickfix',
+\ 'ale_set_signs',
+\ 'ale_sign_column_always',
+\ 'ale_sign_error',
+\ 'ale_sign_offset',
+\ 'ale_sign_warning',
+\ 'ale_statusline_format',
+\ 'ale_warn_about_trailing_whitespace',
+\]
+
+function! s:GetLinterVariables(filetype, linter_names) abort
+ let l:variable_list = []
+ let l:filetype_parts = split(a:filetype, '\.')
+
+ for l:key in keys(g:)
+ " Extract variable names like: 'ale_python_flake8_executable'
+ let l:match = matchlist(l:key, '\v^ale_([^_]+)_([^_]+)_.+$')
+
+ " Include matching variables.
+ if !empty(l:match)
+ \&& index(l:filetype_parts, l:match[1]) >= 0
+ \&& index(a:linter_names, l:match[2]) >= 0
+ call add(l:variable_list, l:key)
+ endif
+ endfor
+
+ call sort(l:variable_list)
+
+ return l:variable_list
+endfunction
+
+function! s:EchoLinterVariables(variable_list) abort
+ for l:key in a:variable_list
+ echom 'let g:' . l:key . ' = ' . string(g:[l:key])
+
+ if has_key(b:, l:key)
+ echom 'let b:' . l:key . ' = ' . string(b:[l:key])
+ endif
+ endfor
+endfunction
+
+function! s:EchoGlobalVariables() abort
+ for l:key in s:global_variable_list
+ echom 'let g:' . l:key . ' = ' . string(get(g:, l:key, v:null))
+
+ if has_key(b:, l:key)
+ echom 'let b:' . l:key . ' = ' . string(b:[l:key])
+ endif
+ endfor
+endfunction
+
+" Echo a command that was run.
+function! s:EchoCommand(item) abort
+ let l:status_message = a:item.status
+
+ " Include the exit code in output if we have it.
+ if a:item.status is# 'finished'
+ let l:status_message .= ' - exit code ' . a:item.exit_code
+ endif
+
+ echom '(' . l:status_message . ') ' . string(a:item.command)
+
+ if g:ale_history_log_output && has_key(a:item, 'output')
+ if empty(a:item.output)
+ echom ''
+ echom '<<>>'
+ echom ''
+ else
+ echom ''
+ echom '<<