From 08f01ec16490dca0a2bbe035e0c1aac0ec3e206f Mon Sep 17 00:00:00 2001 From: Anthony Perkins Date: Mon, 16 Sep 2019 09:51:09 +0100 Subject: [PATCH] Add ALE Language Server Protocol client --- pack/acp/start/ale/LICENSE | 22 + pack/acp/start/ale/ale_linters/ada/gcc.vim | 54 + .../ale/ale_linters/ansible/ansible_lint.vim | 56 + .../ale/ale_linters/apiblueprint/drafter.vim | 38 + .../start/ale/ale_linters/asciidoc/alex.vim | 4 + .../ale/ale_linters/asciidoc/proselint.vim | 9 + .../start/ale/ale_linters/asciidoc/redpen.vim | 9 + .../ale/ale_linters/asciidoc/textlint.vim | 9 + .../start/ale/ale_linters/asciidoc/vale.vim | 9 + .../ale/ale_linters/asciidoc/writegood.vim | 4 + pack/acp/start/ale/ale_linters/asm/gcc.vim | 37 + pack/acp/start/ale/ale_linters/awk/gawk.vim | 22 + .../start/ale/ale_linters/bib/bibclean.vim | 75 + pack/acp/start/ale/ale_linters/c/ccls.vim | 14 + pack/acp/start/ale/ale_linters/c/clang.vim | 24 + pack/acp/start/ale/ale_linters/c/clangd.vim | 17 + .../acp/start/ale/ale_linters/c/clangtidy.vim | 49 + pack/acp/start/ale/ale_linters/c/cppcheck.vim | 28 + pack/acp/start/ale/ale_linters/c/cquery.vim | 30 + .../start/ale/ale_linters/c/flawfinder.vim | 25 + pack/acp/start/ale/ale_linters/c/gcc.vim | 28 + .../start/ale/ale_linters/chef/cookstyle.vim | 54 + .../start/ale/ale_linters/chef/foodcritic.vim | 41 + .../ale/ale_linters/clojure/clj_kondo.vim | 34 + .../start/ale/ale_linters/clojure/joker.vim | 34 + .../cloudformation/cfn_python_lint.vim | 35 + .../start/ale/ale_linters/cmake/cmakelint.vim | 24 + .../start/ale/ale_linters/coffee/coffee.vim | 23 + .../ale/ale_linters/coffee/coffeelint.vim | 43 + pack/acp/start/ale/ale_linters/cpp/ccls.vim | 14 + pack/acp/start/ale/ale_linters/cpp/clang.vim | 24 + .../start/ale/ale_linters/cpp/clangcheck.vim | 35 + pack/acp/start/ale/ale_linters/cpp/clangd.vim | 17 + .../start/ale/ale_linters/cpp/clangtidy.vim | 43 + pack/acp/start/ale/ale_linters/cpp/clazy.vim | 32 + .../start/ale/ale_linters/cpp/cppcheck.vim | 28 + .../acp/start/ale/ale_linters/cpp/cpplint.vim | 20 + pack/acp/start/ale/ale_linters/cpp/cquery.vim | 30 + .../start/ale/ale_linters/cpp/flawfinder.vim | 25 + pack/acp/start/ale/ale_linters/cpp/gcc.vim | 29 + .../start/ale/ale_linters/crystal/ameba.vim | 57 + .../start/ale/ale_linters/crystal/crystal.vim | 31 + pack/acp/start/ale/ale_linters/cs/mcs.vim | 37 + pack/acp/start/ale/ale_linters/cs/mcsc.vim | 81 + .../acp/start/ale/ale_linters/css/csslint.vim | 18 + pack/acp/start/ale/ale_linters/css/fecs.vim | 9 + .../start/ale/ale_linters/css/stylelint.vim | 19 + .../ale/ale_linters/cucumber/cucumber.vim | 46 + pack/acp/start/ale/ale_linters/cuda/nvcc.vim | 49 + .../ale/ale_linters/cypher/cypher_lint.vim | 26 + pack/acp/start/ale/ale_linters/d/dls.vim | 22 + pack/acp/start/ale/ale_linters/d/dmd.vim | 74 + .../acp/start/ale/ale_linters/dafny/dafny.vim | 26 + .../ale/ale_linters/dart/dartanalyzer.vim | 36 + .../ale/ale_linters/dart/language_server.vim | 20 + .../dockerfile/dockerfile_lint.vim | 61 + .../ale/ale_linters/dockerfile/hadolint.vim | 99 + .../start/ale/ale_linters/elixir/credo.vim | 63 + .../start/ale/ale_linters/elixir/dialyxir.vim | 41 + .../start/ale/ale_linters/elixir/dogma.vim | 45 + .../ale/ale_linters/elixir/elixir_ls.vim | 21 + pack/acp/start/ale/ale_linters/elixir/mix.vim | 52 + .../acp/start/ale/ale_linters/elm/elm_lsp.vim | 22 + pack/acp/start/ale/ale_linters/elm/make.vim | 240 ++ .../start/ale/ale_linters/erlang/dialyzer.vim | 93 + .../acp/start/ale/ale_linters/erlang/erlc.vim | 96 + .../ale/ale_linters/erlang/syntaxerl.vim | 42 + pack/acp/start/ale/ale_linters/eruby/erb.vim | 25 + .../acp/start/ale/ale_linters/eruby/erubi.vim | 32 + .../start/ale/ale_linters/eruby/erubis.vim | 23 + .../start/ale/ale_linters/eruby/ruumba.vim | 62 + pack/acp/start/ale/ale_linters/fish/fish.vim | 67 + .../acp/start/ale/ale_linters/fortran/gcc.vim | 72 + .../ale_linters/fortran/language_server.vim | 19 + .../ale/ale_linters/fountain/proselint.vim | 9 + .../start/ale/ale_linters/fuse/fusionlint.vim | 33 + .../ale/ale_linters/gitcommit/gitlint.vim | 51 + .../start/ale/ale_linters/glsl/glslang.vim | 40 + .../acp/start/ale/ale_linters/glsl/glslls.vim | 30 + pack/acp/start/ale/ale_linters/go/bingo.vim | 29 + pack/acp/start/ale/ale_linters/go/gobuild.vim | 56 + pack/acp/start/ale/ale_linters/go/gofmt.vim | 10 + .../ale/ale_linters/go/golangci_lint.vim | 56 + pack/acp/start/ale/ale_linters/go/golint.vim | 21 + .../start/ale/ale_linters/go/gometalinter.vim | 57 + pack/acp/start/ale/ale_linters/go/gopls.vim | 30 + .../acp/start/ale/ale_linters/go/gosimple.vim | 15 + pack/acp/start/ale/ale_linters/go/gotype.vim | 19 + pack/acp/start/ale/ale_linters/go/govet.vim | 27 + .../start/ale/ale_linters/go/langserver.vim | 28 + .../start/ale/ale_linters/go/staticcheck.vim | 33 + .../start/ale/ale_linters/graphql/eslint.vim | 9 + .../start/ale/ale_linters/graphql/gqlint.vim | 15 + pack/acp/start/ale/ale_linters/hack/hack.vim | 22 + pack/acp/start/ale/ale_linters/hack/hhast.vim | 40 + .../start/ale/ale_linters/haml/hamllint.vim | 57 + .../handlebars/embertemplatelint.vim | 39 + .../ale/ale_linters/haskell/cabal_ghc.vim | 20 + .../acp/start/ale/ale_linters/haskell/ghc.vim | 18 + .../start/ale/ale_linters/haskell/ghc_mod.vim | 19 + .../ale/ale_linters/haskell/hdevtools.vim | 20 + .../acp/start/ale/ale_linters/haskell/hie.vim | 41 + .../start/ale/ale_linters/haskell/hlint.vim | 46 + .../ale/ale_linters/haskell/stack_build.vim | 23 + .../ale/ale_linters/haskell/stack_ghc.vim | 21 + pack/acp/start/ale/ale_linters/help/alex.vim | 4 + .../start/ale/ale_linters/help/proselint.vim | 9 + .../start/ale/ale_linters/help/writegood.vim | 4 + pack/acp/start/ale/ale_linters/html/alex.vim | 4 + pack/acp/start/ale/ale_linters/html/fecs.vim | 9 + .../start/ale/ale_linters/html/htmlhint.vim | 32 + .../start/ale/ale_linters/html/proselint.vim | 9 + .../start/ale/ale_linters/html/stylelint.vim | 27 + pack/acp/start/ale/ale_linters/html/tidy.vim | 70 + .../start/ale/ale_linters/html/writegood.vim | 4 + .../acp/start/ale/ale_linters/idris/idris.vim | 81 + pack/acp/start/ale/ale_linters/ispc/ispc.vim | 45 + .../start/ale/ale_linters/java/checkstyle.vim | 61 + .../start/ale/ale_linters/java/eclipselsp.vim | 161 + pack/acp/start/ale/ale_linters/java/javac.vim | 139 + .../start/ale/ale_linters/java/javalsp.vim | 41 + pack/acp/start/ale/ale_linters/java/pmd.vim | 36 + .../ale/ale_linters/javascript/eslint.vim | 10 + .../start/ale/ale_linters/javascript/fecs.vim | 10 + .../start/ale/ale_linters/javascript/flow.vim | 160 + .../ale/ale_linters/javascript/flow_ls.vim | 28 + .../start/ale/ale_linters/javascript/jscs.vim | 61 + .../ale/ale_linters/javascript/jshint.vim | 33 + .../ale/ale_linters/javascript/standard.vim | 30 + .../ale/ale_linters/javascript/tsserver.vim | 17 + .../start/ale/ale_linters/javascript/xo.vim | 26 + .../start/ale/ale_linters/json/jsonlint.vim | 43 + .../ale/ale_linters/julia/languageserver.vim | 21 + .../start/ale/ale_linters/kotlin/kotlinc.vim | 180 + .../start/ale/ale_linters/kotlin/ktlint.vim | 10 + .../ale/ale_linters/kotlin/languageserver.vim | 29 + pack/acp/start/ale/ale_linters/less/lessc.vim | 47 + .../start/ale/ale_linters/less/stylelint.vim | 20 + pack/acp/start/ale/ale_linters/llvm/llc.vim | 24 + pack/acp/start/ale/ale_linters/lua/luac.vim | 31 + .../start/ale/ale_linters/lua/luacheck.vim | 44 + pack/acp/start/ale/ale_linters/mail/alex.vim | 4 + .../ale/ale_linters/mail/languagetool.vim | 5 + .../start/ale/ale_linters/mail/proselint.vim | 9 + pack/acp/start/ale/ale_linters/mail/vale.vim | 9 + .../start/ale/ale_linters/make/checkmake.vim | 25 + .../start/ale/ale_linters/markdown/alex.vim | 4 + .../ale/ale_linters/markdown/languagetool.vim | 5 + .../ale/ale_linters/markdown/markdownlint.vim | 11 + .../start/ale/ale_linters/markdown/mdl.vim | 44 + .../ale/ale_linters/markdown/proselint.vim | 9 + .../start/ale/ale_linters/markdown/redpen.vim | 9 + .../ale/ale_linters/markdown/remark_lint.vim | 48 + .../ale/ale_linters/markdown/textlint.vim | 9 + .../start/ale/ale_linters/markdown/vale.vim | 9 + .../ale/ale_linters/markdown/writegood.vim | 4 + .../start/ale/ale_linters/matlab/mlint.vim | 44 + .../acp/start/ale/ale_linters/mercury/mmc.vim | 40 + pack/acp/start/ale/ale_linters/nasm/nasm.vim | 42 + .../start/ale/ale_linters/nim/nimcheck.vim | 65 + pack/acp/start/ale/ale_linters/nix/nix.vim | 26 + pack/acp/start/ale/ale_linters/nroff/alex.vim | 4 + .../start/ale/ale_linters/nroff/proselint.vim | 9 + .../start/ale/ale_linters/nroff/writegood.vim | 4 + pack/acp/start/ale/ale_linters/objc/ccls.vim | 14 + pack/acp/start/ale/ale_linters/objc/clang.vim | 23 + .../acp/start/ale/ale_linters/objc/clangd.vim | 17 + .../start/ale/ale_linters/objcpp/clang.vim | 23 + .../start/ale/ale_linters/objcpp/clangd.vim | 17 + .../start/ale/ale_linters/ocaml/merlin.vim | 17 + pack/acp/start/ale/ale_linters/ocaml/ols.vim | 14 + pack/acp/start/ale/ale_linters/perl/perl.vim | 64 + .../start/ale/ale_linters/perl/perlcritic.vim | 61 + .../acp/start/ale/ale_linters/perl6/perl6.vim | 166 + .../start/ale/ale_linters/php/langserver.vim | 27 + pack/acp/start/ale/ale_linters/php/phan.vim | 73 + pack/acp/start/ale/ale_linters/php/php.vim | 39 + pack/acp/start/ale/ale_linters/php/phpcs.vim | 54 + pack/acp/start/ale/ale_linters/php/phpmd.vim | 38 + .../acp/start/ale/ale_linters/php/phpstan.vim | 74 + pack/acp/start/ale/ale_linters/php/psalm.vim | 21 + pack/acp/start/ale/ale_linters/po/alex.vim | 4 + pack/acp/start/ale/ale_linters/po/msgfmt.vim | 30 + .../start/ale/ale_linters/po/proselint.vim | 9 + .../start/ale/ale_linters/po/writegood.vim | 4 + pack/acp/start/ale/ale_linters/pod/alex.vim | 4 + .../start/ale/ale_linters/pod/proselint.vim | 9 + .../start/ale/ale_linters/pod/writegood.vim | 4 + pack/acp/start/ale/ale_linters/pony/ponyc.vim | 16 + .../ale/ale_linters/powershell/powershell.vim | 91 + .../powershell/psscriptanalyzer.vim | 76 + .../start/ale/ale_linters/prolog/swipl.vim | 100 + .../ale/ale_linters/proto/protoc_gen_lint.vim | 27 + .../acp/start/ale/ale_linters/pug/puglint.vim | 56 + .../ale/ale_linters/puppet/languageserver.vim | 37 + .../start/ale/ale_linters/puppet/puppet.vim | 37 + .../ale/ale_linters/puppet/puppetlint.vim | 18 + .../start/ale/ale_linters/pyrex/cython.vim | 38 + .../start/ale/ale_linters/python/bandit.vim | 68 + .../start/ale/ale_linters/python/flake8.vim | 146 + .../acp/start/ale/ale_linters/python/mypy.vim | 81 + .../ale/ale_linters/python/prospector.vim | 100 + .../ale/ale_linters/python/pycodestyle.vim | 75 + .../ale/ale_linters/python/pydocstyle.vim | 73 + .../start/ale/ale_linters/python/pyflakes.vim | 50 + .../start/ale/ale_linters/python/pylama.vim | 92 + .../start/ale/ale_linters/python/pylint.vim | 92 + .../acp/start/ale/ale_linters/python/pyls.vim | 36 + .../acp/start/ale/ale_linters/python/pyre.vim | 34 + .../start/ale/ale_linters/python/vulture.vim | 80 + pack/acp/start/ale/ale_linters/qml/qmlfmt.vim | 25 + .../acp/start/ale/ale_linters/qml/qmllint.vim | 29 + pack/acp/start/ale/ale_linters/r/lintr.vim | 35 + .../acp/start/ale/ale_linters/racket/raco.vim | 33 + pack/acp/start/ale/ale_linters/reason/ls.vim | 23 + .../start/ale/ale_linters/reason/merlin.vim | 17 + pack/acp/start/ale/ale_linters/reason/ols.vim | 14 + .../start/ale/ale_linters/review/redpen.vim | 9 + pack/acp/start/ale/ale_linters/rst/alex.vim | 4 + .../start/ale/ale_linters/rst/proselint.vim | 9 + pack/acp/start/ale/ale_linters/rst/redpen.vim | 9 + .../start/ale/ale_linters/rst/rstcheck.vim | 38 + .../start/ale/ale_linters/rst/textlint.vim | 9 + pack/acp/start/ale/ale_linters/rst/vale.vim | 9 + .../start/ale/ale_linters/rst/writegood.vim | 4 + .../start/ale/ale_linters/ruby/brakeman.vim | 51 + .../ale_linters/ruby/rails_best_practices.vim | 49 + pack/acp/start/ale/ale_linters/ruby/reek.vim | 65 + .../start/ale/ale_linters/ruby/rubocop.vim | 31 + pack/acp/start/ale/ale_linters/ruby/ruby.vim | 12 + .../start/ale/ale_linters/ruby/solargraph.vim | 22 + .../start/ale/ale_linters/ruby/standardrb.vim | 23 + pack/acp/start/ale/ale_linters/rust/cargo.vim | 98 + pack/acp/start/ale/ale_linters/rust/rls.vim | 27 + pack/acp/start/ale/ale_linters/rust/rustc.vim | 33 + .../start/ale/ale_linters/sass/sasslint.vim | 28 + .../start/ale/ale_linters/sass/stylelint.vim | 13 + pack/acp/start/ale/ale_linters/scala/fsc.vim | 14 + .../start/ale/ale_linters/scala/sbtserver.vim | 31 + .../start/ale/ale_linters/scala/scalac.vim | 15 + .../ale/ale_linters/scala/scalastyle.vim | 86 + .../start/ale/ale_linters/scss/sasslint.vim | 28 + .../start/ale/ale_linters/scss/scsslint.vim | 34 + .../start/ale/ale_linters/scss/stylelint.vim | 19 + .../ale/ale_linters/sh/language_server.vim | 32 + pack/acp/start/ale/ale_linters/sh/shell.vim | 57 + .../start/ale/ale_linters/sh/shellcheck.vim | 107 + .../start/ale/ale_linters/slim/slimlint.vim | 55 + pack/acp/start/ale/ale_linters/sml/smlnj.vim | 9 + .../start/ale/ale_linters/sml/smlnj_cm.vim | 21 + .../ale/ale_linters/solidity/solhint.vim | 29 + .../start/ale/ale_linters/solidity/solium.vim | 9 + .../start/ale/ale_linters/spec/rpmlint.vim | 78 + pack/acp/start/ale/ale_linters/sql/sqlint.vim | 28 + .../ale/ale_linters/stylus/stylelint.vim | 20 + .../ale/ale_linters/sugarss/stylelint.vim | 21 + .../ale/ale_linters/swift/sourcekitlsp.vim | 13 + .../start/ale/ale_linters/swift/swiftlint.vim | 69 + .../start/ale/ale_linters/tcl/nagelfar.vim | 39 + .../ale/ale_linters/terraform/terraform.vim | 49 + .../ale/ale_linters/terraform/tflint.vim | 58 + .../ale/ale_linters/testft/testlinter.vim | 10 + pack/acp/start/ale/ale_linters/tex/alex.vim | 4 + pack/acp/start/ale/ale_linters/tex/chktex.vim | 54 + .../acp/start/ale/ale_linters/tex/lacheck.vim | 43 + .../start/ale/ale_linters/tex/proselint.vim | 9 + pack/acp/start/ale/ale_linters/tex/redpen.vim | 9 + pack/acp/start/ale/ale_linters/tex/texlab.vim | 21 + .../start/ale/ale_linters/tex/textlint.vim | 9 + pack/acp/start/ale/ale_linters/tex/vale.vim | 9 + .../start/ale/ale_linters/tex/writegood.vim | 4 + .../start/ale/ale_linters/texinfo/alex.vim | 4 + .../ale/ale_linters/texinfo/proselint.vim | 9 + .../ale/ale_linters/texinfo/writegood.vim | 4 + pack/acp/start/ale/ale_linters/text/alex.vim | 4 + .../ale/ale_linters/text/languagetool.vim | 4 + .../start/ale/ale_linters/text/proselint.vim | 9 + .../acp/start/ale/ale_linters/text/redpen.vim | 9 + .../start/ale/ale_linters/text/textlint.vim | 9 + pack/acp/start/ale/ale_linters/text/vale.vim | 9 + .../start/ale/ale_linters/text/writegood.vim | 4 + .../start/ale/ale_linters/thrift/thrift.vim | 87 + .../ale/ale_linters/typescript/eslint.vim | 9 + .../ale/ale_linters/typescript/tslint.vim | 75 + .../ale/ale_linters/typescript/tsserver.vim | 17 + .../ale/ale_linters/typescript/typecheck.vim | 33 + .../start/ale/ale_linters/typescript/xo.vim | 23 + .../ale/ale_linters/verilog/iverilog.vim | 43 + .../ale/ale_linters/verilog/verilator.vim | 59 + .../start/ale/ale_linters/verilog/vlog.vim | 36 + .../start/ale/ale_linters/verilog/xvlog.vim | 35 + pack/acp/start/ale/ale_linters/vhdl/ghdl.vim | 37 + pack/acp/start/ale/ale_linters/vhdl/vcom.vim | 38 + pack/acp/start/ale/ale_linters/vhdl/xvhdl.vim | 37 + .../vim/ale_custom_linting_rules.vim | 65 + pack/acp/start/ale/ale_linters/vim/vint.vim | 60 + pack/acp/start/ale/ale_linters/vue/vls.vim | 22 + pack/acp/start/ale/ale_linters/xhtml/alex.vim | 4 + .../start/ale/ale_linters/xhtml/proselint.vim | 9 + .../start/ale/ale_linters/xhtml/writegood.vim | 4 + .../acp/start/ale/ale_linters/xml/xmllint.vim | 65 + .../start/ale/ale_linters/yaml/swaglint.vim | 40 + .../start/ale/ale_linters/yaml/yamllint.vim | 50 + .../start/ale/ale_linters/yang/yang_lsp.vim | 15 + pack/acp/start/ale/autoload/ale.vim | 261 ++ pack/acp/start/ale/autoload/ale/ant.vim | 41 + pack/acp/start/ale/autoload/ale/args.vim | 43 + pack/acp/start/ale/autoload/ale/assert.vim | 331 ++ pack/acp/start/ale/autoload/ale/balloon.vim | 58 + pack/acp/start/ale/autoload/ale/c.vim | 395 ++ pack/acp/start/ale/autoload/ale/command.vim | 379 ++ .../acp/start/ale/autoload/ale/completion.vim | 697 ++++ .../ale/autoload/ale/completion/python.vim | 3 + pack/acp/start/ale/autoload/ale/cursor.vim | 167 + pack/acp/start/ale/autoload/ale/d.vim | 16 + pack/acp/start/ale/autoload/ale/debugging.vim | 264 ++ .../acp/start/ale/autoload/ale/definition.vim | 156 + pack/acp/start/ale/autoload/ale/engine.vim | 733 ++++ .../start/ale/autoload/ale/engine/ignore.vim | 50 + pack/acp/start/ale/autoload/ale/events.vim | 155 + pack/acp/start/ale/autoload/ale/filetypes.vim | 60 + pack/acp/start/ale/autoload/ale/fix.vim | 416 ++ .../start/ale/autoload/ale/fix/registry.vim | 524 +++ .../ale/autoload/ale/fixers/autopep8.vim | 26 + .../ale/autoload/ale/fixers/bibclean.vim | 15 + .../start/ale/autoload/ale/fixers/black.vim | 37 + .../ale/autoload/ale/fixers/brittany.vim | 22 + .../ale/autoload/ale/fixers/clangformat.vim | 22 + .../ale/autoload/ale/fixers/cmakeformat.vim | 18 + .../start/ale/autoload/ale/fixers/dartfmt.vim | 18 + .../ale/autoload/ale/fixers/elm_format.vim | 23 + .../start/ale/autoload/ale/fixers/eslint.vim | 80 + .../start/ale/autoload/ale/fixers/fecs.vim | 17 + .../start/ale/autoload/ale/fixers/fixjson.vim | 28 + .../ale/autoload/ale/fixers/floskell.vim | 20 + .../start/ale/autoload/ale/fixers/generic.vim | 25 + .../autoload/ale/fixers/generic_python.vim | 75 + .../start/ale/autoload/ale/fixers/gofmt.vim | 18 + .../ale/autoload/ale/fixers/goimports.vim | 22 + .../start/ale/autoload/ale/fixers/gomod.vim | 10 + .../ale/fixers/google_java_format.vim | 23 + .../start/ale/autoload/ale/fixers/hackfmt.vim | 18 + .../start/ale/autoload/ale/fixers/help.vim | 24 + .../start/ale/autoload/ale/fixers/hfmt.vim | 16 + .../start/ale/autoload/ale/fixers/hlint.vim | 13 + .../ale/autoload/ale/fixers/importjs.vim | 25 + .../start/ale/autoload/ale/fixers/isort.vim | 25 + pack/acp/start/ale/autoload/ale/fixers/jq.vim | 22 + .../start/ale/autoload/ale/fixers/ktlint.vim | 9 + .../ale/autoload/ale/fixers/latexindent.vim | 18 + .../ale/autoload/ale/fixers/mix_format.vim | 25 + .../ale/autoload/ale/fixers/ocamlformat.vim | 18 + .../ale/autoload/ale/fixers/ocp_indent.vim | 18 + .../ale/autoload/ale/fixers/perltidy.vim | 18 + .../ale/autoload/ale/fixers/pgformatter.vim | 12 + .../ale/autoload/ale/fixers/php_cs_fixer.vim | 24 + .../start/ale/autoload/ale/fixers/phpcbf.vim | 25 + .../ale/autoload/ale/fixers/prettier.vim | 108 + .../autoload/ale/fixers/prettier_eslint.vim | 56 + .../autoload/ale/fixers/prettier_standard.vim | 24 + .../ale/autoload/ale/fixers/puppetlint.vim | 22 + .../start/ale/autoload/ale/fixers/qmlfmt.vim | 11 + .../start/ale/autoload/ale/fixers/refmt.vim | 18 + .../ale/fixers/reorder_python_imports.vim | 25 + .../start/ale/autoload/ale/fixers/rubocop.vim | 20 + .../start/ale/autoload/ale/fixers/rufo.vim | 20 + .../start/ale/autoload/ale/fixers/rustfmt.vim | 15 + .../ale/autoload/ale/fixers/scalafmt.vim | 25 + .../start/ale/autoload/ale/fixers/shfmt.vim | 31 + .../start/ale/autoload/ale/fixers/sqlfmt.vim | 13 + .../ale/autoload/ale/fixers/standard.vim | 25 + .../ale/autoload/ale/fixers/standardrb.vim | 23 + .../ale/autoload/ale/fixers/stylelint.vim | 22 + .../start/ale/autoload/ale/fixers/styler.vim | 16 + .../autoload/ale/fixers/stylish_haskell.vim | 21 + .../ale/autoload/ale/fixers/swiftformat.vim | 25 + .../ale/autoload/ale/fixers/terraform.vim | 17 + .../ale/autoload/ale/fixers/textlint.vim | 15 + .../start/ale/autoload/ale/fixers/tidy.vim | 26 + .../start/ale/autoload/ale/fixers/tslint.vim | 22 + .../ale/autoload/ale/fixers/uncrustify.vim | 16 + .../start/ale/autoload/ale/fixers/xmllint.vim | 29 + pack/acp/start/ale/autoload/ale/fixers/xo.vim | 23 + .../start/ale/autoload/ale/fixers/yapf.vim | 26 + pack/acp/start/ale/autoload/ale/go.vim | 27 + pack/acp/start/ale/autoload/ale/gradle.vim | 67 + .../start/ale/autoload/ale/gradle/init.gradle | 23 + .../start/ale/autoload/ale/handlers/alex.vim | 54 + .../start/ale/autoload/ale/handlers/ccls.vim | 19 + .../ale/autoload/ale/handlers/cppcheck.vim | 62 + .../ale/autoload/ale/handlers/cpplint.vim | 21 + .../start/ale/autoload/ale/handlers/css.vim | 70 + .../ale/autoload/ale/handlers/elixir.vim | 28 + .../ale/autoload/ale/handlers/eslint.vim | 246 ++ .../start/ale/autoload/ale/handlers/fecs.vim | 52 + .../ale/autoload/ale/handlers/flawfinder.vim | 48 + .../start/ale/autoload/ale/handlers/gawk.vim | 27 + .../start/ale/autoload/ale/handlers/gcc.vim | 159 + .../start/ale/autoload/ale/handlers/go.vim | 26 + .../ale/autoload/ale/handlers/haskell.vim | 101 + .../autoload/ale/handlers/haskell_stack.vim | 7 + .../start/ale/autoload/ale/handlers/hlint.vim | 8 + .../ale/autoload/ale/handlers/ktlint.vim | 45 + .../autoload/ale/handlers/languagetool.vim | 74 + .../autoload/ale/handlers/markdownlint.vim | 17 + .../start/ale/autoload/ale/handlers/ols.vim | 26 + .../start/ale/autoload/ale/handlers/pony.vim | 33 + .../ale/autoload/ale/handlers/redpen.vim | 65 + .../start/ale/autoload/ale/handlers/ruby.vim | 46 + .../start/ale/autoload/ale/handlers/rust.vim | 78 + .../start/ale/autoload/ale/handlers/scala.vim | 37 + .../start/ale/autoload/ale/handlers/sh.vim | 20 + .../start/ale/autoload/ale/handlers/sml.vim | 93 + .../ale/autoload/ale/handlers/textlint.vim | 39 + .../ale/autoload/ale/handlers/tslint.vim | 13 + .../ale/autoload/ale/handlers/tsserver.vim | 8 + .../start/ale/autoload/ale/handlers/unix.vim | 26 + .../start/ale/autoload/ale/handlers/vale.vim | 39 + .../ale/autoload/ale/handlers/writegood.vim | 72 + pack/acp/start/ale/autoload/ale/highlight.vim | 159 + pack/acp/start/ale/autoload/ale/history.vim | 62 + pack/acp/start/ale/autoload/ale/hover.vim | 189 + pack/acp/start/ale/autoload/ale/java.vim | 26 + pack/acp/start/ale/autoload/ale/job.vim | 373 ++ pack/acp/start/ale/autoload/ale/julia.vim | 19 + pack/acp/start/ale/autoload/ale/linter.vim | 551 +++ pack/acp/start/ale/autoload/ale/list.vim | 197 + .../ale/autoload/ale/loclist_jumping.vim | 163 + pack/acp/start/ale/autoload/ale/lsp.vim | 631 +++ .../start/ale/autoload/ale/lsp/message.vim | 164 + pack/acp/start/ale/autoload/ale/lsp/reset.vim | 25 + .../start/ale/autoload/ale/lsp/response.vim | 151 + .../ale/autoload/ale/lsp/tsserver_message.vim | 79 + .../acp/start/ale/autoload/ale/lsp_linter.vim | 466 +++ pack/acp/start/ale/autoload/ale/node.vim | 42 + .../start/ale/autoload/ale/other_source.vim | 21 + pack/acp/start/ale/autoload/ale/path.vim | 224 ++ .../ale/autoload/ale/pattern_options.vim | 47 + .../acp/start/ale/autoload/ale/powershell.vim | 32 + pack/acp/start/ale/autoload/ale/preview.vim | 98 + pack/acp/start/ale/autoload/ale/python.vim | 157 + .../acp/start/ale/autoload/ale/references.vim | 127 + pack/acp/start/ale/autoload/ale/ruby.vim | 76 + pack/acp/start/ale/autoload/ale/semver.vim | 78 + pack/acp/start/ale/autoload/ale/sign.vim | 388 ++ pack/acp/start/ale/autoload/ale/socket.vim | 152 + .../acp/start/ale/autoload/ale/statusline.vim | 135 + pack/acp/start/ale/autoload/ale/swift.vim | 13 + pack/acp/start/ale/autoload/ale/symbol.vim | 110 + pack/acp/start/ale/autoload/ale/test.vim | 187 + pack/acp/start/ale/autoload/ale/toggle.vim | 100 + pack/acp/start/ale/autoload/ale/uri.vim | 18 + pack/acp/start/ale/autoload/ale/util.vim | 479 +++ .../start/ale/autoload/ale/virtualtext.vim | 135 + pack/acp/start/ale/doc/ale-ada.txt | 25 + pack/acp/start/ale/doc/ale-ansible.txt | 16 + pack/acp/start/ale/doc/ale-asciidoc.txt | 18 + pack/acp/start/ale/doc/ale-asm.txt | 25 + pack/acp/start/ale/doc/ale-awk.txt | 25 + pack/acp/start/ale/doc/ale-bib.txt | 19 + pack/acp/start/ale/doc/ale-c.txt | 324 ++ pack/acp/start/ale/doc/ale-chef.txt | 46 + pack/acp/start/ale/doc/ale-clojure.txt | 28 + pack/acp/start/ale/doc/ale-cloudformation.txt | 14 + pack/acp/start/ale/doc/ale-cmake.txt | 43 + pack/acp/start/ale/doc/ale-cpp.txt | 322 ++ pack/acp/start/ale/doc/ale-cs.txt | 112 + pack/acp/start/ale/doc/ale-css.txt | 47 + pack/acp/start/ale/doc/ale-cuda.txt | 32 + pack/acp/start/ale/doc/ale-d.txt | 23 + pack/acp/start/ale/doc/ale-dart.txt | 71 + pack/acp/start/ale/doc/ale-development.txt | 358 ++ pack/acp/start/ale/doc/ale-dockerfile.txt | 60 + pack/acp/start/ale/doc/ale-elixir.txt | 89 + pack/acp/start/ale/doc/ale-elm.txt | 68 + pack/acp/start/ale/doc/ale-erlang.txt | 58 + pack/acp/start/ale/doc/ale-eruby.txt | 37 + pack/acp/start/ale/doc/ale-fish.txt | 14 + pack/acp/start/ale/doc/ale-fortran.txt | 55 + pack/acp/start/ale/doc/ale-fountain.txt | 6 + pack/acp/start/ale/doc/ale-fuse.txt | 25 + pack/acp/start/ale/doc/ale-gitcommit.txt | 44 + pack/acp/start/ale/doc/ale-glsl.txt | 56 + pack/acp/start/ale/doc/ale-go.txt | 234 ++ pack/acp/start/ale/doc/ale-graphql.txt | 22 + pack/acp/start/ale/doc/ale-hack.txt | 51 + pack/acp/start/ale/doc/ale-handlebars.txt | 25 + pack/acp/start/ale/doc/ale-haskell.txt | 154 + pack/acp/start/ale/doc/ale-hcl.txt | 11 + pack/acp/start/ale/doc/ale-html.txt | 130 + pack/acp/start/ale/doc/ale-idris.txt | 23 + pack/acp/start/ale/doc/ale-ispc.txt | 24 + pack/acp/start/ale/doc/ale-java.txt | 206 + pack/acp/start/ale/doc/ale-javascript.txt | 336 ++ pack/acp/start/ale/doc/ale-json.txt | 105 + pack/acp/start/ale/doc/ale-julia.txt | 20 + pack/acp/start/ale/doc/ale-kotlin.txt | 113 + pack/acp/start/ale/doc/ale-latex.txt | 18 + pack/acp/start/ale/doc/ale-less.txt | 66 + pack/acp/start/ale/doc/ale-llvm.txt | 19 + pack/acp/start/ale/doc/ale-lua.txt | 34 + pack/acp/start/ale/doc/ale-markdown.txt | 71 + pack/acp/start/ale/doc/ale-mercury.txt | 26 + pack/acp/start/ale/doc/ale-nasm.txt | 26 + pack/acp/start/ale/doc/ale-nroff.txt | 12 + pack/acp/start/ale/doc/ale-objc.txt | 73 + pack/acp/start/ale/doc/ale-objcpp.txt | 42 + pack/acp/start/ale/doc/ale-ocaml.txt | 82 + pack/acp/start/ale/doc/ale-pawn.txt | 12 + pack/acp/start/ale/doc/ale-perl.txt | 91 + pack/acp/start/ale/doc/ale-perl6.txt | 43 + pack/acp/start/ale/doc/ale-php.txt | 227 ++ pack/acp/start/ale/doc/ale-po.txt | 12 + pack/acp/start/ale/doc/ale-pod.txt | 12 + pack/acp/start/ale/doc/ale-pony.txt | 25 + pack/acp/start/ale/doc/ale-powershell.txt | 77 + pack/acp/start/ale/doc/ale-prolog.txt | 56 + pack/acp/start/ale/doc/ale-proto.txt | 33 + pack/acp/start/ale/doc/ale-pug.txt | 44 + pack/acp/start/ale/doc/ale-puppet.txt | 57 + pack/acp/start/ale/doc/ale-pyrex.txt | 25 + pack/acp/start/ale/doc/ale-python.txt | 764 ++++ pack/acp/start/ale/doc/ale-qml.txt | 18 + pack/acp/start/ale/doc/ale-r.txt | 45 + pack/acp/start/ale/doc/ale-reasonml.txt | 76 + .../start/ale/doc/ale-restructuredtext.txt | 26 + pack/acp/start/ale/doc/ale-ruby.txt | 155 + pack/acp/start/ale/doc/ale-rust.txt | 248 ++ pack/acp/start/ale/doc/ale-sass.txt | 31 + pack/acp/start/ale/doc/ale-scala.txt | 98 + pack/acp/start/ale/doc/ale-scss.txt | 64 + pack/acp/start/ale/doc/ale-sh.txt | 115 + pack/acp/start/ale/doc/ale-sml.txt | 36 + pack/acp/start/ale/doc/ale-solidity.txt | 24 + pack/acp/start/ale/doc/ale-spec.txt | 43 + pack/acp/start/ale/doc/ale-sql.txt | 43 + pack/acp/start/ale/doc/ale-stylus.txt | 33 + pack/acp/start/ale/doc/ale-sugarss.txt | 31 + .../doc/ale-supported-languages-and-tools.txt | 488 +++ pack/acp/start/ale/doc/ale-swift.txt | 21 + pack/acp/start/ale/doc/ale-tcl.txt | 25 + pack/acp/start/ale/doc/ale-terraform.txt | 59 + pack/acp/start/ale/doc/ale-tex.txt | 77 + pack/acp/start/ale/doc/ale-texinfo.txt | 12 + pack/acp/start/ale/doc/ale-text.txt | 42 + pack/acp/start/ale/doc/ale-thrift.txt | 46 + pack/acp/start/ale/doc/ale-typescript.txt | 115 + pack/acp/start/ale/doc/ale-vala.txt | 12 + pack/acp/start/ale/doc/ale-verilog.txt | 102 + pack/acp/start/ale/doc/ale-vhdl.txt | 92 + pack/acp/start/ale/doc/ale-vim-help.txt | 12 + pack/acp/start/ale/doc/ale-vim.txt | 27 + pack/acp/start/ale/doc/ale-vue.txt | 31 + pack/acp/start/ale/doc/ale-xhtml.txt | 12 + pack/acp/start/ale/doc/ale-xml.txt | 34 + pack/acp/start/ale/doc/ale-yaml.txt | 92 + pack/acp/start/ale/doc/ale-yang.txt | 17 + pack/acp/start/ale/doc/ale.txt | 3378 +++++++++++++++++ .../start/ale/ftplugin/ale-fix-suggest.vim | 2 + .../ale/ftplugin/ale-preview-selection.vim | 16 + pack/acp/start/ale/ftplugin/ale-preview.vim | 2 + pack/acp/start/ale/plugin/ale.vim | 274 ++ .../rplugin/python3/deoplete/sources/ale.py | 54 + pack/acp/start/ale/supported-tools.md | 497 +++ pack/acp/start/ale/syntax/ale-fix-suggest.vim | 13 + .../ale/syntax/ale-preview-selection.vim | 11 + plugins.md | 1 + vimrc | 4 +- 568 files changed, 36790 insertions(+), 2 deletions(-) create mode 100644 pack/acp/start/ale/LICENSE create mode 100644 pack/acp/start/ale/ale_linters/ada/gcc.vim create mode 100644 pack/acp/start/ale/ale_linters/ansible/ansible_lint.vim create mode 100644 pack/acp/start/ale/ale_linters/apiblueprint/drafter.vim create mode 100644 pack/acp/start/ale/ale_linters/asciidoc/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/asciidoc/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/asciidoc/redpen.vim create mode 100644 pack/acp/start/ale/ale_linters/asciidoc/textlint.vim create mode 100644 pack/acp/start/ale/ale_linters/asciidoc/vale.vim create mode 100644 pack/acp/start/ale/ale_linters/asciidoc/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/asm/gcc.vim create mode 100644 pack/acp/start/ale/ale_linters/awk/gawk.vim create mode 100644 pack/acp/start/ale/ale_linters/bib/bibclean.vim create mode 100644 pack/acp/start/ale/ale_linters/c/ccls.vim create mode 100644 pack/acp/start/ale/ale_linters/c/clang.vim create mode 100644 pack/acp/start/ale/ale_linters/c/clangd.vim create mode 100644 pack/acp/start/ale/ale_linters/c/clangtidy.vim create mode 100644 pack/acp/start/ale/ale_linters/c/cppcheck.vim create mode 100644 pack/acp/start/ale/ale_linters/c/cquery.vim create mode 100644 pack/acp/start/ale/ale_linters/c/flawfinder.vim create mode 100644 pack/acp/start/ale/ale_linters/c/gcc.vim create mode 100644 pack/acp/start/ale/ale_linters/chef/cookstyle.vim create mode 100644 pack/acp/start/ale/ale_linters/chef/foodcritic.vim create mode 100644 pack/acp/start/ale/ale_linters/clojure/clj_kondo.vim create mode 100644 pack/acp/start/ale/ale_linters/clojure/joker.vim create mode 100644 pack/acp/start/ale/ale_linters/cloudformation/cfn_python_lint.vim create mode 100644 pack/acp/start/ale/ale_linters/cmake/cmakelint.vim create mode 100644 pack/acp/start/ale/ale_linters/coffee/coffee.vim create mode 100644 pack/acp/start/ale/ale_linters/coffee/coffeelint.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/ccls.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/clang.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/clangcheck.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/clangd.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/clangtidy.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/clazy.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/cppcheck.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/cpplint.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/cquery.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/flawfinder.vim create mode 100644 pack/acp/start/ale/ale_linters/cpp/gcc.vim create mode 100644 pack/acp/start/ale/ale_linters/crystal/ameba.vim create mode 100644 pack/acp/start/ale/ale_linters/crystal/crystal.vim create mode 100644 pack/acp/start/ale/ale_linters/cs/mcs.vim create mode 100644 pack/acp/start/ale/ale_linters/cs/mcsc.vim create mode 100644 pack/acp/start/ale/ale_linters/css/csslint.vim create mode 100644 pack/acp/start/ale/ale_linters/css/fecs.vim create mode 100644 pack/acp/start/ale/ale_linters/css/stylelint.vim create mode 100644 pack/acp/start/ale/ale_linters/cucumber/cucumber.vim create mode 100644 pack/acp/start/ale/ale_linters/cuda/nvcc.vim create mode 100644 pack/acp/start/ale/ale_linters/cypher/cypher_lint.vim create mode 100644 pack/acp/start/ale/ale_linters/d/dls.vim create mode 100644 pack/acp/start/ale/ale_linters/d/dmd.vim create mode 100644 pack/acp/start/ale/ale_linters/dafny/dafny.vim create mode 100644 pack/acp/start/ale/ale_linters/dart/dartanalyzer.vim create mode 100644 pack/acp/start/ale/ale_linters/dart/language_server.vim create mode 100644 pack/acp/start/ale/ale_linters/dockerfile/dockerfile_lint.vim create mode 100644 pack/acp/start/ale/ale_linters/dockerfile/hadolint.vim create mode 100644 pack/acp/start/ale/ale_linters/elixir/credo.vim create mode 100644 pack/acp/start/ale/ale_linters/elixir/dialyxir.vim create mode 100644 pack/acp/start/ale/ale_linters/elixir/dogma.vim create mode 100644 pack/acp/start/ale/ale_linters/elixir/elixir_ls.vim create mode 100644 pack/acp/start/ale/ale_linters/elixir/mix.vim create mode 100644 pack/acp/start/ale/ale_linters/elm/elm_lsp.vim create mode 100644 pack/acp/start/ale/ale_linters/elm/make.vim create mode 100644 pack/acp/start/ale/ale_linters/erlang/dialyzer.vim create mode 100644 pack/acp/start/ale/ale_linters/erlang/erlc.vim create mode 100644 pack/acp/start/ale/ale_linters/erlang/syntaxerl.vim create mode 100644 pack/acp/start/ale/ale_linters/eruby/erb.vim create mode 100644 pack/acp/start/ale/ale_linters/eruby/erubi.vim create mode 100644 pack/acp/start/ale/ale_linters/eruby/erubis.vim create mode 100644 pack/acp/start/ale/ale_linters/eruby/ruumba.vim create mode 100644 pack/acp/start/ale/ale_linters/fish/fish.vim create mode 100644 pack/acp/start/ale/ale_linters/fortran/gcc.vim create mode 100644 pack/acp/start/ale/ale_linters/fortran/language_server.vim create mode 100644 pack/acp/start/ale/ale_linters/fountain/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/fuse/fusionlint.vim create mode 100644 pack/acp/start/ale/ale_linters/gitcommit/gitlint.vim create mode 100644 pack/acp/start/ale/ale_linters/glsl/glslang.vim create mode 100644 pack/acp/start/ale/ale_linters/glsl/glslls.vim create mode 100644 pack/acp/start/ale/ale_linters/go/bingo.vim create mode 100644 pack/acp/start/ale/ale_linters/go/gobuild.vim create mode 100644 pack/acp/start/ale/ale_linters/go/gofmt.vim create mode 100644 pack/acp/start/ale/ale_linters/go/golangci_lint.vim create mode 100644 pack/acp/start/ale/ale_linters/go/golint.vim create mode 100644 pack/acp/start/ale/ale_linters/go/gometalinter.vim create mode 100644 pack/acp/start/ale/ale_linters/go/gopls.vim create mode 100644 pack/acp/start/ale/ale_linters/go/gosimple.vim create mode 100644 pack/acp/start/ale/ale_linters/go/gotype.vim create mode 100644 pack/acp/start/ale/ale_linters/go/govet.vim create mode 100644 pack/acp/start/ale/ale_linters/go/langserver.vim create mode 100644 pack/acp/start/ale/ale_linters/go/staticcheck.vim create mode 100644 pack/acp/start/ale/ale_linters/graphql/eslint.vim create mode 100644 pack/acp/start/ale/ale_linters/graphql/gqlint.vim create mode 100644 pack/acp/start/ale/ale_linters/hack/hack.vim create mode 100644 pack/acp/start/ale/ale_linters/hack/hhast.vim create mode 100644 pack/acp/start/ale/ale_linters/haml/hamllint.vim create mode 100644 pack/acp/start/ale/ale_linters/handlebars/embertemplatelint.vim create mode 100644 pack/acp/start/ale/ale_linters/haskell/cabal_ghc.vim create mode 100644 pack/acp/start/ale/ale_linters/haskell/ghc.vim create mode 100644 pack/acp/start/ale/ale_linters/haskell/ghc_mod.vim create mode 100644 pack/acp/start/ale/ale_linters/haskell/hdevtools.vim create mode 100644 pack/acp/start/ale/ale_linters/haskell/hie.vim create mode 100644 pack/acp/start/ale/ale_linters/haskell/hlint.vim create mode 100644 pack/acp/start/ale/ale_linters/haskell/stack_build.vim create mode 100644 pack/acp/start/ale/ale_linters/haskell/stack_ghc.vim create mode 100644 pack/acp/start/ale/ale_linters/help/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/help/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/help/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/html/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/html/fecs.vim create mode 100644 pack/acp/start/ale/ale_linters/html/htmlhint.vim create mode 100644 pack/acp/start/ale/ale_linters/html/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/html/stylelint.vim create mode 100644 pack/acp/start/ale/ale_linters/html/tidy.vim create mode 100644 pack/acp/start/ale/ale_linters/html/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/idris/idris.vim create mode 100644 pack/acp/start/ale/ale_linters/ispc/ispc.vim create mode 100644 pack/acp/start/ale/ale_linters/java/checkstyle.vim create mode 100644 pack/acp/start/ale/ale_linters/java/eclipselsp.vim create mode 100644 pack/acp/start/ale/ale_linters/java/javac.vim create mode 100644 pack/acp/start/ale/ale_linters/java/javalsp.vim create mode 100644 pack/acp/start/ale/ale_linters/java/pmd.vim create mode 100644 pack/acp/start/ale/ale_linters/javascript/eslint.vim create mode 100644 pack/acp/start/ale/ale_linters/javascript/fecs.vim create mode 100755 pack/acp/start/ale/ale_linters/javascript/flow.vim create mode 100644 pack/acp/start/ale/ale_linters/javascript/flow_ls.vim create mode 100644 pack/acp/start/ale/ale_linters/javascript/jscs.vim create mode 100644 pack/acp/start/ale/ale_linters/javascript/jshint.vim create mode 100644 pack/acp/start/ale/ale_linters/javascript/standard.vim create mode 100644 pack/acp/start/ale/ale_linters/javascript/tsserver.vim create mode 100644 pack/acp/start/ale/ale_linters/javascript/xo.vim create mode 100644 pack/acp/start/ale/ale_linters/json/jsonlint.vim create mode 100644 pack/acp/start/ale/ale_linters/julia/languageserver.vim create mode 100644 pack/acp/start/ale/ale_linters/kotlin/kotlinc.vim create mode 100644 pack/acp/start/ale/ale_linters/kotlin/ktlint.vim create mode 100644 pack/acp/start/ale/ale_linters/kotlin/languageserver.vim create mode 100755 pack/acp/start/ale/ale_linters/less/lessc.vim create mode 100644 pack/acp/start/ale/ale_linters/less/stylelint.vim create mode 100644 pack/acp/start/ale/ale_linters/llvm/llc.vim create mode 100644 pack/acp/start/ale/ale_linters/lua/luac.vim create mode 100644 pack/acp/start/ale/ale_linters/lua/luacheck.vim create mode 100644 pack/acp/start/ale/ale_linters/mail/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/mail/languagetool.vim create mode 100644 pack/acp/start/ale/ale_linters/mail/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/mail/vale.vim create mode 100644 pack/acp/start/ale/ale_linters/make/checkmake.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/languagetool.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/markdownlint.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/mdl.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/redpen.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/remark_lint.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/textlint.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/vale.vim create mode 100644 pack/acp/start/ale/ale_linters/markdown/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/matlab/mlint.vim create mode 100644 pack/acp/start/ale/ale_linters/mercury/mmc.vim create mode 100644 pack/acp/start/ale/ale_linters/nasm/nasm.vim create mode 100644 pack/acp/start/ale/ale_linters/nim/nimcheck.vim create mode 100644 pack/acp/start/ale/ale_linters/nix/nix.vim create mode 100644 pack/acp/start/ale/ale_linters/nroff/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/nroff/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/nroff/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/objc/ccls.vim create mode 100644 pack/acp/start/ale/ale_linters/objc/clang.vim create mode 100644 pack/acp/start/ale/ale_linters/objc/clangd.vim create mode 100644 pack/acp/start/ale/ale_linters/objcpp/clang.vim create mode 100644 pack/acp/start/ale/ale_linters/objcpp/clangd.vim create mode 100644 pack/acp/start/ale/ale_linters/ocaml/merlin.vim create mode 100644 pack/acp/start/ale/ale_linters/ocaml/ols.vim create mode 100644 pack/acp/start/ale/ale_linters/perl/perl.vim create mode 100644 pack/acp/start/ale/ale_linters/perl/perlcritic.vim create mode 100644 pack/acp/start/ale/ale_linters/perl6/perl6.vim create mode 100644 pack/acp/start/ale/ale_linters/php/langserver.vim create mode 100644 pack/acp/start/ale/ale_linters/php/phan.vim create mode 100644 pack/acp/start/ale/ale_linters/php/php.vim create mode 100644 pack/acp/start/ale/ale_linters/php/phpcs.vim create mode 100644 pack/acp/start/ale/ale_linters/php/phpmd.vim create mode 100644 pack/acp/start/ale/ale_linters/php/phpstan.vim create mode 100644 pack/acp/start/ale/ale_linters/php/psalm.vim create mode 100644 pack/acp/start/ale/ale_linters/po/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/po/msgfmt.vim create mode 100644 pack/acp/start/ale/ale_linters/po/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/po/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/pod/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/pod/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/pod/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/pony/ponyc.vim create mode 100755 pack/acp/start/ale/ale_linters/powershell/powershell.vim create mode 100644 pack/acp/start/ale/ale_linters/powershell/psscriptanalyzer.vim create mode 100644 pack/acp/start/ale/ale_linters/prolog/swipl.vim create mode 100644 pack/acp/start/ale/ale_linters/proto/protoc_gen_lint.vim create mode 100644 pack/acp/start/ale/ale_linters/pug/puglint.vim create mode 100644 pack/acp/start/ale/ale_linters/puppet/languageserver.vim create mode 100644 pack/acp/start/ale/ale_linters/puppet/puppet.vim create mode 100644 pack/acp/start/ale/ale_linters/puppet/puppetlint.vim create mode 100644 pack/acp/start/ale/ale_linters/pyrex/cython.vim create mode 100644 pack/acp/start/ale/ale_linters/python/bandit.vim create mode 100644 pack/acp/start/ale/ale_linters/python/flake8.vim create mode 100644 pack/acp/start/ale/ale_linters/python/mypy.vim create mode 100644 pack/acp/start/ale/ale_linters/python/prospector.vim create mode 100644 pack/acp/start/ale/ale_linters/python/pycodestyle.vim create mode 100644 pack/acp/start/ale/ale_linters/python/pydocstyle.vim create mode 100644 pack/acp/start/ale/ale_linters/python/pyflakes.vim create mode 100644 pack/acp/start/ale/ale_linters/python/pylama.vim create mode 100644 pack/acp/start/ale/ale_linters/python/pylint.vim create mode 100644 pack/acp/start/ale/ale_linters/python/pyls.vim create mode 100644 pack/acp/start/ale/ale_linters/python/pyre.vim create mode 100644 pack/acp/start/ale/ale_linters/python/vulture.vim create mode 100644 pack/acp/start/ale/ale_linters/qml/qmlfmt.vim create mode 100644 pack/acp/start/ale/ale_linters/qml/qmllint.vim create mode 100644 pack/acp/start/ale/ale_linters/r/lintr.vim create mode 100644 pack/acp/start/ale/ale_linters/racket/raco.vim create mode 100644 pack/acp/start/ale/ale_linters/reason/ls.vim create mode 100644 pack/acp/start/ale/ale_linters/reason/merlin.vim create mode 100644 pack/acp/start/ale/ale_linters/reason/ols.vim create mode 100644 pack/acp/start/ale/ale_linters/review/redpen.vim create mode 100644 pack/acp/start/ale/ale_linters/rst/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/rst/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/rst/redpen.vim create mode 100644 pack/acp/start/ale/ale_linters/rst/rstcheck.vim create mode 100644 pack/acp/start/ale/ale_linters/rst/textlint.vim create mode 100644 pack/acp/start/ale/ale_linters/rst/vale.vim create mode 100644 pack/acp/start/ale/ale_linters/rst/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/ruby/brakeman.vim create mode 100644 pack/acp/start/ale/ale_linters/ruby/rails_best_practices.vim create mode 100644 pack/acp/start/ale/ale_linters/ruby/reek.vim create mode 100644 pack/acp/start/ale/ale_linters/ruby/rubocop.vim create mode 100644 pack/acp/start/ale/ale_linters/ruby/ruby.vim create mode 100644 pack/acp/start/ale/ale_linters/ruby/solargraph.vim create mode 100644 pack/acp/start/ale/ale_linters/ruby/standardrb.vim create mode 100644 pack/acp/start/ale/ale_linters/rust/cargo.vim create mode 100644 pack/acp/start/ale/ale_linters/rust/rls.vim create mode 100644 pack/acp/start/ale/ale_linters/rust/rustc.vim create mode 100644 pack/acp/start/ale/ale_linters/sass/sasslint.vim create mode 100644 pack/acp/start/ale/ale_linters/sass/stylelint.vim create mode 100644 pack/acp/start/ale/ale_linters/scala/fsc.vim create mode 100644 pack/acp/start/ale/ale_linters/scala/sbtserver.vim create mode 100644 pack/acp/start/ale/ale_linters/scala/scalac.vim create mode 100644 pack/acp/start/ale/ale_linters/scala/scalastyle.vim create mode 100644 pack/acp/start/ale/ale_linters/scss/sasslint.vim create mode 100644 pack/acp/start/ale/ale_linters/scss/scsslint.vim create mode 100644 pack/acp/start/ale/ale_linters/scss/stylelint.vim create mode 100644 pack/acp/start/ale/ale_linters/sh/language_server.vim create mode 100644 pack/acp/start/ale/ale_linters/sh/shell.vim create mode 100644 pack/acp/start/ale/ale_linters/sh/shellcheck.vim create mode 100644 pack/acp/start/ale/ale_linters/slim/slimlint.vim create mode 100644 pack/acp/start/ale/ale_linters/sml/smlnj.vim create mode 100644 pack/acp/start/ale/ale_linters/sml/smlnj_cm.vim create mode 100644 pack/acp/start/ale/ale_linters/solidity/solhint.vim create mode 100644 pack/acp/start/ale/ale_linters/solidity/solium.vim create mode 100644 pack/acp/start/ale/ale_linters/spec/rpmlint.vim create mode 100644 pack/acp/start/ale/ale_linters/sql/sqlint.vim create mode 100644 pack/acp/start/ale/ale_linters/stylus/stylelint.vim create mode 100644 pack/acp/start/ale/ale_linters/sugarss/stylelint.vim create mode 100644 pack/acp/start/ale/ale_linters/swift/sourcekitlsp.vim create mode 100644 pack/acp/start/ale/ale_linters/swift/swiftlint.vim create mode 100644 pack/acp/start/ale/ale_linters/tcl/nagelfar.vim create mode 100755 pack/acp/start/ale/ale_linters/terraform/terraform.vim create mode 100644 pack/acp/start/ale/ale_linters/terraform/tflint.vim create mode 100644 pack/acp/start/ale/ale_linters/testft/testlinter.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/chktex.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/lacheck.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/redpen.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/texlab.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/textlint.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/vale.vim create mode 100644 pack/acp/start/ale/ale_linters/tex/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/texinfo/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/texinfo/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/texinfo/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/text/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/text/languagetool.vim create mode 100644 pack/acp/start/ale/ale_linters/text/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/text/redpen.vim create mode 100644 pack/acp/start/ale/ale_linters/text/textlint.vim create mode 100644 pack/acp/start/ale/ale_linters/text/vale.vim create mode 100644 pack/acp/start/ale/ale_linters/text/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/thrift/thrift.vim create mode 100644 pack/acp/start/ale/ale_linters/typescript/eslint.vim create mode 100644 pack/acp/start/ale/ale_linters/typescript/tslint.vim create mode 100644 pack/acp/start/ale/ale_linters/typescript/tsserver.vim create mode 100644 pack/acp/start/ale/ale_linters/typescript/typecheck.vim create mode 100644 pack/acp/start/ale/ale_linters/typescript/xo.vim create mode 100644 pack/acp/start/ale/ale_linters/verilog/iverilog.vim create mode 100644 pack/acp/start/ale/ale_linters/verilog/verilator.vim create mode 100644 pack/acp/start/ale/ale_linters/verilog/vlog.vim create mode 100644 pack/acp/start/ale/ale_linters/verilog/xvlog.vim create mode 100644 pack/acp/start/ale/ale_linters/vhdl/ghdl.vim create mode 100644 pack/acp/start/ale/ale_linters/vhdl/vcom.vim create mode 100644 pack/acp/start/ale/ale_linters/vhdl/xvhdl.vim create mode 100644 pack/acp/start/ale/ale_linters/vim/ale_custom_linting_rules.vim create mode 100644 pack/acp/start/ale/ale_linters/vim/vint.vim create mode 100644 pack/acp/start/ale/ale_linters/vue/vls.vim create mode 100644 pack/acp/start/ale/ale_linters/xhtml/alex.vim create mode 100644 pack/acp/start/ale/ale_linters/xhtml/proselint.vim create mode 100644 pack/acp/start/ale/ale_linters/xhtml/writegood.vim create mode 100644 pack/acp/start/ale/ale_linters/xml/xmllint.vim create mode 100644 pack/acp/start/ale/ale_linters/yaml/swaglint.vim create mode 100644 pack/acp/start/ale/ale_linters/yaml/yamllint.vim create mode 100644 pack/acp/start/ale/ale_linters/yang/yang_lsp.vim create mode 100644 pack/acp/start/ale/autoload/ale.vim create mode 100644 pack/acp/start/ale/autoload/ale/ant.vim create mode 100644 pack/acp/start/ale/autoload/ale/args.vim create mode 100644 pack/acp/start/ale/autoload/ale/assert.vim create mode 100644 pack/acp/start/ale/autoload/ale/balloon.vim create mode 100644 pack/acp/start/ale/autoload/ale/c.vim create mode 100644 pack/acp/start/ale/autoload/ale/command.vim create mode 100644 pack/acp/start/ale/autoload/ale/completion.vim create mode 100644 pack/acp/start/ale/autoload/ale/completion/python.vim create mode 100644 pack/acp/start/ale/autoload/ale/cursor.vim create mode 100644 pack/acp/start/ale/autoload/ale/d.vim create mode 100644 pack/acp/start/ale/autoload/ale/debugging.vim create mode 100644 pack/acp/start/ale/autoload/ale/definition.vim create mode 100644 pack/acp/start/ale/autoload/ale/engine.vim create mode 100644 pack/acp/start/ale/autoload/ale/engine/ignore.vim create mode 100644 pack/acp/start/ale/autoload/ale/events.vim create mode 100644 pack/acp/start/ale/autoload/ale/filetypes.vim create mode 100644 pack/acp/start/ale/autoload/ale/fix.vim create mode 100644 pack/acp/start/ale/autoload/ale/fix/registry.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/autopep8.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/bibclean.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/black.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/brittany.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/clangformat.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/cmakeformat.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/dartfmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/elm_format.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/eslint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/fecs.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/fixjson.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/floskell.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/generic.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/generic_python.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/gofmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/goimports.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/gomod.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/google_java_format.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/hackfmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/help.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/hfmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/hlint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/importjs.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/isort.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/jq.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/ktlint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/latexindent.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/mix_format.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/ocamlformat.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/ocp_indent.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/perltidy.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/pgformatter.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/php_cs_fixer.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/phpcbf.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/prettier.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/prettier_eslint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/prettier_standard.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/puppetlint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/qmlfmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/refmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/reorder_python_imports.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/rubocop.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/rufo.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/rustfmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/scalafmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/shfmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/sqlfmt.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/standard.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/standardrb.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/stylelint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/styler.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/stylish_haskell.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/swiftformat.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/terraform.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/textlint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/tidy.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/tslint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/uncrustify.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/xmllint.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/xo.vim create mode 100644 pack/acp/start/ale/autoload/ale/fixers/yapf.vim create mode 100644 pack/acp/start/ale/autoload/ale/go.vim create mode 100644 pack/acp/start/ale/autoload/ale/gradle.vim create mode 100644 pack/acp/start/ale/autoload/ale/gradle/init.gradle create mode 100644 pack/acp/start/ale/autoload/ale/handlers/alex.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/ccls.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/cppcheck.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/cpplint.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/css.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/elixir.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/eslint.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/fecs.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/flawfinder.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/gawk.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/gcc.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/go.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/haskell.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/haskell_stack.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/hlint.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/ktlint.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/languagetool.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/markdownlint.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/ols.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/pony.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/redpen.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/ruby.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/rust.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/scala.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/sh.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/sml.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/textlint.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/tslint.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/tsserver.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/unix.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/vale.vim create mode 100644 pack/acp/start/ale/autoload/ale/handlers/writegood.vim create mode 100644 pack/acp/start/ale/autoload/ale/highlight.vim create mode 100644 pack/acp/start/ale/autoload/ale/history.vim create mode 100644 pack/acp/start/ale/autoload/ale/hover.vim create mode 100644 pack/acp/start/ale/autoload/ale/java.vim create mode 100644 pack/acp/start/ale/autoload/ale/job.vim create mode 100644 pack/acp/start/ale/autoload/ale/julia.vim create mode 100644 pack/acp/start/ale/autoload/ale/linter.vim create mode 100644 pack/acp/start/ale/autoload/ale/list.vim create mode 100644 pack/acp/start/ale/autoload/ale/loclist_jumping.vim create mode 100644 pack/acp/start/ale/autoload/ale/lsp.vim create mode 100644 pack/acp/start/ale/autoload/ale/lsp/message.vim create mode 100644 pack/acp/start/ale/autoload/ale/lsp/reset.vim create mode 100644 pack/acp/start/ale/autoload/ale/lsp/response.vim create mode 100644 pack/acp/start/ale/autoload/ale/lsp/tsserver_message.vim create mode 100644 pack/acp/start/ale/autoload/ale/lsp_linter.vim create mode 100644 pack/acp/start/ale/autoload/ale/node.vim create mode 100644 pack/acp/start/ale/autoload/ale/other_source.vim create mode 100644 pack/acp/start/ale/autoload/ale/path.vim create mode 100644 pack/acp/start/ale/autoload/ale/pattern_options.vim create mode 100644 pack/acp/start/ale/autoload/ale/powershell.vim create mode 100644 pack/acp/start/ale/autoload/ale/preview.vim create mode 100644 pack/acp/start/ale/autoload/ale/python.vim create mode 100644 pack/acp/start/ale/autoload/ale/references.vim create mode 100644 pack/acp/start/ale/autoload/ale/ruby.vim create mode 100644 pack/acp/start/ale/autoload/ale/semver.vim create mode 100644 pack/acp/start/ale/autoload/ale/sign.vim create mode 100644 pack/acp/start/ale/autoload/ale/socket.vim create mode 100644 pack/acp/start/ale/autoload/ale/statusline.vim create mode 100644 pack/acp/start/ale/autoload/ale/swift.vim create mode 100644 pack/acp/start/ale/autoload/ale/symbol.vim create mode 100644 pack/acp/start/ale/autoload/ale/test.vim create mode 100644 pack/acp/start/ale/autoload/ale/toggle.vim create mode 100644 pack/acp/start/ale/autoload/ale/uri.vim create mode 100644 pack/acp/start/ale/autoload/ale/util.vim create mode 100644 pack/acp/start/ale/autoload/ale/virtualtext.vim create mode 100644 pack/acp/start/ale/doc/ale-ada.txt create mode 100644 pack/acp/start/ale/doc/ale-ansible.txt create mode 100644 pack/acp/start/ale/doc/ale-asciidoc.txt create mode 100644 pack/acp/start/ale/doc/ale-asm.txt create mode 100644 pack/acp/start/ale/doc/ale-awk.txt create mode 100644 pack/acp/start/ale/doc/ale-bib.txt create mode 100644 pack/acp/start/ale/doc/ale-c.txt create mode 100644 pack/acp/start/ale/doc/ale-chef.txt create mode 100644 pack/acp/start/ale/doc/ale-clojure.txt create mode 100644 pack/acp/start/ale/doc/ale-cloudformation.txt create mode 100644 pack/acp/start/ale/doc/ale-cmake.txt create mode 100644 pack/acp/start/ale/doc/ale-cpp.txt create mode 100644 pack/acp/start/ale/doc/ale-cs.txt create mode 100644 pack/acp/start/ale/doc/ale-css.txt create mode 100644 pack/acp/start/ale/doc/ale-cuda.txt create mode 100644 pack/acp/start/ale/doc/ale-d.txt create mode 100644 pack/acp/start/ale/doc/ale-dart.txt create mode 100644 pack/acp/start/ale/doc/ale-development.txt create mode 100644 pack/acp/start/ale/doc/ale-dockerfile.txt create mode 100644 pack/acp/start/ale/doc/ale-elixir.txt create mode 100644 pack/acp/start/ale/doc/ale-elm.txt create mode 100644 pack/acp/start/ale/doc/ale-erlang.txt create mode 100644 pack/acp/start/ale/doc/ale-eruby.txt create mode 100644 pack/acp/start/ale/doc/ale-fish.txt create mode 100644 pack/acp/start/ale/doc/ale-fortran.txt create mode 100644 pack/acp/start/ale/doc/ale-fountain.txt create mode 100644 pack/acp/start/ale/doc/ale-fuse.txt create mode 100644 pack/acp/start/ale/doc/ale-gitcommit.txt create mode 100644 pack/acp/start/ale/doc/ale-glsl.txt create mode 100644 pack/acp/start/ale/doc/ale-go.txt create mode 100644 pack/acp/start/ale/doc/ale-graphql.txt create mode 100644 pack/acp/start/ale/doc/ale-hack.txt create mode 100644 pack/acp/start/ale/doc/ale-handlebars.txt create mode 100644 pack/acp/start/ale/doc/ale-haskell.txt create mode 100644 pack/acp/start/ale/doc/ale-hcl.txt create mode 100644 pack/acp/start/ale/doc/ale-html.txt create mode 100644 pack/acp/start/ale/doc/ale-idris.txt create mode 100644 pack/acp/start/ale/doc/ale-ispc.txt create mode 100644 pack/acp/start/ale/doc/ale-java.txt create mode 100644 pack/acp/start/ale/doc/ale-javascript.txt create mode 100644 pack/acp/start/ale/doc/ale-json.txt create mode 100644 pack/acp/start/ale/doc/ale-julia.txt create mode 100644 pack/acp/start/ale/doc/ale-kotlin.txt create mode 100644 pack/acp/start/ale/doc/ale-latex.txt create mode 100644 pack/acp/start/ale/doc/ale-less.txt create mode 100644 pack/acp/start/ale/doc/ale-llvm.txt create mode 100644 pack/acp/start/ale/doc/ale-lua.txt create mode 100644 pack/acp/start/ale/doc/ale-markdown.txt create mode 100644 pack/acp/start/ale/doc/ale-mercury.txt create mode 100644 pack/acp/start/ale/doc/ale-nasm.txt create mode 100644 pack/acp/start/ale/doc/ale-nroff.txt create mode 100644 pack/acp/start/ale/doc/ale-objc.txt create mode 100644 pack/acp/start/ale/doc/ale-objcpp.txt create mode 100644 pack/acp/start/ale/doc/ale-ocaml.txt create mode 100644 pack/acp/start/ale/doc/ale-pawn.txt create mode 100644 pack/acp/start/ale/doc/ale-perl.txt create mode 100644 pack/acp/start/ale/doc/ale-perl6.txt create mode 100644 pack/acp/start/ale/doc/ale-php.txt create mode 100644 pack/acp/start/ale/doc/ale-po.txt create mode 100644 pack/acp/start/ale/doc/ale-pod.txt create mode 100644 pack/acp/start/ale/doc/ale-pony.txt create mode 100644 pack/acp/start/ale/doc/ale-powershell.txt create mode 100644 pack/acp/start/ale/doc/ale-prolog.txt create mode 100644 pack/acp/start/ale/doc/ale-proto.txt create mode 100644 pack/acp/start/ale/doc/ale-pug.txt create mode 100644 pack/acp/start/ale/doc/ale-puppet.txt create mode 100644 pack/acp/start/ale/doc/ale-pyrex.txt create mode 100644 pack/acp/start/ale/doc/ale-python.txt create mode 100644 pack/acp/start/ale/doc/ale-qml.txt create mode 100644 pack/acp/start/ale/doc/ale-r.txt create mode 100644 pack/acp/start/ale/doc/ale-reasonml.txt create mode 100644 pack/acp/start/ale/doc/ale-restructuredtext.txt create mode 100644 pack/acp/start/ale/doc/ale-ruby.txt create mode 100644 pack/acp/start/ale/doc/ale-rust.txt create mode 100644 pack/acp/start/ale/doc/ale-sass.txt create mode 100644 pack/acp/start/ale/doc/ale-scala.txt create mode 100644 pack/acp/start/ale/doc/ale-scss.txt create mode 100644 pack/acp/start/ale/doc/ale-sh.txt create mode 100644 pack/acp/start/ale/doc/ale-sml.txt create mode 100644 pack/acp/start/ale/doc/ale-solidity.txt create mode 100644 pack/acp/start/ale/doc/ale-spec.txt create mode 100644 pack/acp/start/ale/doc/ale-sql.txt create mode 100644 pack/acp/start/ale/doc/ale-stylus.txt create mode 100644 pack/acp/start/ale/doc/ale-sugarss.txt create mode 100644 pack/acp/start/ale/doc/ale-supported-languages-and-tools.txt create mode 100644 pack/acp/start/ale/doc/ale-swift.txt create mode 100644 pack/acp/start/ale/doc/ale-tcl.txt create mode 100644 pack/acp/start/ale/doc/ale-terraform.txt create mode 100644 pack/acp/start/ale/doc/ale-tex.txt create mode 100644 pack/acp/start/ale/doc/ale-texinfo.txt create mode 100644 pack/acp/start/ale/doc/ale-text.txt create mode 100644 pack/acp/start/ale/doc/ale-thrift.txt create mode 100644 pack/acp/start/ale/doc/ale-typescript.txt create mode 100644 pack/acp/start/ale/doc/ale-vala.txt create mode 100644 pack/acp/start/ale/doc/ale-verilog.txt create mode 100644 pack/acp/start/ale/doc/ale-vhdl.txt create mode 100644 pack/acp/start/ale/doc/ale-vim-help.txt create mode 100644 pack/acp/start/ale/doc/ale-vim.txt create mode 100644 pack/acp/start/ale/doc/ale-vue.txt create mode 100644 pack/acp/start/ale/doc/ale-xhtml.txt create mode 100644 pack/acp/start/ale/doc/ale-xml.txt create mode 100644 pack/acp/start/ale/doc/ale-yaml.txt create mode 100644 pack/acp/start/ale/doc/ale-yang.txt create mode 100644 pack/acp/start/ale/doc/ale.txt create mode 100644 pack/acp/start/ale/ftplugin/ale-fix-suggest.vim create mode 100644 pack/acp/start/ale/ftplugin/ale-preview-selection.vim create mode 100644 pack/acp/start/ale/ftplugin/ale-preview.vim create mode 100644 pack/acp/start/ale/plugin/ale.vim create mode 100644 pack/acp/start/ale/rplugin/python3/deoplete/sources/ale.py create mode 100644 pack/acp/start/ale/supported-tools.md create mode 100644 pack/acp/start/ale/syntax/ale-fix-suggest.vim create mode 100644 pack/acp/start/ale/syntax/ale-preview-selection.vim diff --git a/pack/acp/start/ale/LICENSE b/pack/acp/start/ale/LICENSE new file mode 100644 index 0000000..f8f3524 --- /dev/null +++ b/pack/acp/start/ale/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2016-2019, 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/pack/acp/start/ale/ale_linters/ada/gcc.vim b/pack/acp/start/ale/ale_linters/ada/gcc.vim new file mode 100644 index 0000000..87496b8 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ada/gcc.vim @@ -0,0 +1,54 @@ +" Author: Martino Pilia +" Description: Lint Ada files with GCC + +call ale#Set('ada_gcc_executable', 'gcc') + +" -gnatwa: activate most optional warnings +" -gnatq: try semantic analysis even if syntax errors have been found +call ale#Set('ada_gcc_options', '-gnatwa -gnatq') + +function! ale_linters#ada#gcc#GetCommand(buffer) abort + " Build a suitable output file name. The output file is specified because + " the .ali file may be created even if no code generation is attempted. + " The output file name must match the source file name (except for the + " extension), so here we cannot use the null file as output. + let l:tmp_dir = fnamemodify(ale#command#CreateDirectory(a:buffer), ':p') + let l:out_file = l:tmp_dir . fnamemodify(bufname(a:buffer), ':t:r') . '.o' + + " -gnatc: Check syntax and semantics only (no code generation attempted) + return '%e -x ada -c -gnatc' + \ . ' -o ' . ale#Escape(l:out_file) + \ . ' -I ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . ale#Pad(ale#Var(a:buffer, 'ada_gcc_options')) + \ . ' %t' +endfunction + +" For the message format please refer to: +" https://gcc.gnu.org/onlinedocs/gnat_ugn/Output-and-Error-Message-Control.html +" https://gcc.gnu.org/onlinedocs/gnat_ugn/Warning-Message-Control.html +function! ale_linters#ada#gcc#Handle(buffer, lines) abort + " Error format: ::: + " Warning format: ::: warning: + let l:re = '\v(.+):([0-9]+):([0-9]+):\s+(warning:)?\s*(.+)\s*' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:re) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': str2nr(l:match[2]), + \ 'col': str2nr(l:match[3]), + \ 'type': l:match[4] is# 'warning:' ? 'W' : 'E', + \ 'text': l:match[5], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('ada', { +\ 'name': 'gcc', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'ada_gcc_executable')}, +\ 'command': function('ale_linters#ada#gcc#GetCommand'), +\ 'callback': 'ale_linters#ada#gcc#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/ansible/ansible_lint.vim b/pack/acp/start/ale/ale_linters/ansible/ansible_lint.vim new file mode 100644 index 0000000..c4affa3 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ansible/ansible_lint.vim @@ -0,0 +1,56 @@ +" Author: Bjorn Neergaard +" Description: ansible-lint for ansible-yaml files + +call ale#Set('ansible_ansible_lint_executable', 'ansible-lint') + +function! ale_linters#ansible#ansible_lint#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'ansible_ansible_lint_executable') +endfunction + +function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort + for l:line in a:lines[:10] + if match(l:line, '^Traceback') >= 0 + return [{ + \ 'lnum': 1, + \ 'text': 'An exception was thrown. See :ALEDetail', + \ 'detail': join(a:lines, "\n"), + \}] + endif + endfor + + " Matches patterns line the following: + " + " test.yml:35: [EANSIBLE0002] Trailing whitespace + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: \[?([[:alnum:]]+)\]? (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:code = l:match[4] + + if l:code is# 'EANSIBLE0002' + \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + " Skip warnings for trailing whitespace if the option is off. + continue + endif + + if ale#path#IsBufferPath(a:buffer, l:match[1]) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[5], + \ 'code': l:code, + \ 'type': l:code[:0] is# 'E' ? 'E' : 'W', + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('ansible', { +\ 'name': 'ansible_lint', +\ 'aliases': ['ansible', 'ansible-lint'], +\ 'executable': function('ale_linters#ansible#ansible_lint#GetExecutable'), +\ 'command': '%e -p %t', +\ 'callback': 'ale_linters#ansible#ansible_lint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/apiblueprint/drafter.vim b/pack/acp/start/ale/ale_linters/apiblueprint/drafter.vim new file mode 100644 index 0000000..5d40c53 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/apiblueprint/drafter.vim @@ -0,0 +1,38 @@ +" Author: nametake https://nametake.github.io +" Description: apiblueprint parser + +function! ale_linters#apiblueprint#drafter#HandleErrors(buffer, lines) abort + " Matches patterns line the following: + " + " warning: (3) unable to parse response signature, expected 'response [] [()]'; line 4, column 3k - line 4, column 22 + " warning: (10) message-body asset is expected to be a pre-formatted code block, separate it by a newline and indent every of its line by 12 spaces or 3 tabs; line 30, column 5 - line 30, column 9; line 31, column 9 - line 31, column 14; line 32, column 9 - line 32, column 14 + let l:pattern = '\(^.*\): (\d\+) \(.\{-\}\); line \(\d\+\), column \(\d\+\) - line \d\+, column \d\+\(.*; line \d\+, column \d\+ - line \(\d\+\), column \(\d\+\)\)\{-\}$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines[2:], l:pattern) + let l:item = { + \ 'type': l:match[1] is# 'warning' ? 'W' : 'E', + \ 'text': l:match[2], + \ 'lnum': l:match[3] + 0, + \ 'col': l:match[4] + 0, + \} + + if l:match[5] isnot# '' + let l:item.end_lnum = l:match[6] + 0 + let l:item.end_col = l:match[7] + 0 + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + + +call ale#linter#Define('apiblueprint', { +\ 'name': 'drafter', +\ 'output_stream': 'stderr', +\ 'executable': 'drafter', +\ 'command': 'drafter --use-line-num --validate', +\ 'callback': 'ale_linters#apiblueprint#drafter#HandleErrors', +\}) diff --git a/pack/acp/start/ale/ale_linters/asciidoc/alex.vim b/pack/acp/start/ale/ale_linters/asciidoc/alex.vim new file mode 100644 index 0000000..97976b2 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/asciidoc/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for asciidoc files + +call ale#handlers#alex#DefineLinter('asciidoc', '--text') diff --git a/pack/acp/start/ale/ale_linters/asciidoc/proselint.vim b/pack/acp/start/ale/ale_linters/asciidoc/proselint.vim new file mode 100644 index 0000000..b636c06 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/asciidoc/redpen.vim b/pack/acp/start/ale/ale_linters/asciidoc/redpen.vim new file mode 100644 index 0000000..819e385 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/asciidoc/redpen.vim @@ -0,0 +1,9 @@ +" Author: rhysd https://rhysd.github.io +" Description: Redpen, a proofreading tool (http://redpen.cc) + +call ale#linter#Define('asciidoc', { +\ 'name': 'redpen', +\ 'executable': 'redpen', +\ 'command': 'redpen -f asciidoc -r json %t', +\ 'callback': 'ale#handlers#redpen#HandleRedpenOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/asciidoc/textlint.vim b/pack/acp/start/ale/ale_linters/asciidoc/textlint.vim new file mode 100644 index 0000000..308a3a2 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/asciidoc/textlint.vim @@ -0,0 +1,9 @@ +" Author: TANIGUCHI Masaya +" Description: textlint for AsciiDoc files + +call ale#linter#Define('asciidoc', { +\ 'name': 'textlint', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), +\ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/asciidoc/vale.vim b/pack/acp/start/ale/ale_linters/asciidoc/vale.vim new file mode 100644 index 0000000..b3cf454 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/asciidoc/vale.vim @@ -0,0 +1,9 @@ +" Author: Jeff Kreeftmeijer https://github.com/jeffkreeftmeijer +" Description: vale for AsciiDoc files + +call ale#linter#Define('asciidoc', { +\ 'name': 'vale', +\ 'executable': 'vale', +\ 'command': 'vale --output=line %t', +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/pack/acp/start/ale/ale_linters/asciidoc/writegood.vim b/pack/acp/start/ale/ale_linters/asciidoc/writegood.vim new file mode 100644 index 0000000..a29b7e9 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/asciidoc/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for AsciiDoc files + +call ale#handlers#writegood#DefineLinter('asciidoc') diff --git a/pack/acp/start/ale/ale_linters/asm/gcc.vim b/pack/acp/start/ale/ale_linters/asm/gcc.vim new file mode 100644 index 0000000..eecab6e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/asm/gcc.vim @@ -0,0 +1,37 @@ +" Author: Lucas Kolstad +" Description: gcc linter for asm files + +call ale#Set('asm_gcc_executable', 'gcc') +call ale#Set('asm_gcc_options', '-Wall') + +function! ale_linters#asm#gcc#GetCommand(buffer) abort + " `-o /dev/null` or `-o null` is needed to catch all errors, + " -fsyntax-only doesn't catch everything. + return '%e -x assembler' + \ . ' -o ' . g:ale#util#nul_file + \ . '-iquote ' . 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': {b -> ale#Var(b, 'asm_gcc_executable')}, +\ 'command': function('ale_linters#asm#gcc#GetCommand'), +\ 'callback': 'ale_linters#asm#gcc#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/awk/gawk.vim b/pack/acp/start/ale/ale_linters/awk/gawk.vim new file mode 100644 index 0000000..f795c57 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/awk/gawk.vim @@ -0,0 +1,22 @@ +" Author: kmarc +" Description: This file adds support for using GNU awk with sripts. + +call ale#Set('awk_gawk_executable', 'gawk') +call ale#Set('awk_gawk_options', '') + +function! ale_linters#awk#gawk#GetCommand(buffer) abort + " note the --source 'BEGIN ...' is to prevent + " gawk from attempting to execute the body of the script + " it is linting. + return '%e --source ' . ale#Escape('BEGIN { exit } END { exit 1 }') + \ . ale#Pad(ale#Var(a:buffer, 'awk_gawk_options')) + \ . ' -f %t --lint /dev/null' +endfunction + +call ale#linter#Define('awk', { +\ 'name': 'gawk', +\ 'executable': {b -> ale#Var(b, 'awk_gawk_executable')}, +\ 'command': function('ale_linters#awk#gawk#GetCommand'), +\ 'callback': 'ale#handlers#gawk#HandleGawkFormat', +\ 'output_stream': 'both' +\}) diff --git a/pack/acp/start/ale/ale_linters/bib/bibclean.vim b/pack/acp/start/ale/ale_linters/bib/bibclean.vim new file mode 100644 index 0000000..9056a9c --- /dev/null +++ b/pack/acp/start/ale/ale_linters/bib/bibclean.vim @@ -0,0 +1,75 @@ +" Author: Horacio Sanson - https://github.com/hsanson +" Description: Support for bibclean linter for BibTeX files. + +call ale#Set('bib_bibclean_executable', 'bibclean') + +function! ale_linters#bib#bibclean#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'bib_bibclean_executable') + + return ale#Escape(l:executable) . ' -file-position ' +endfunction + +function! ale_linters#bib#bibclean#get_type(str) abort + if a:str is# '??' + return 'E' + else + return 'W' + endif +endfunction + +function! ale_linters#bib#bibclean#match_msg(line) abort + return matchlist(a:line, '^\(.*\) "stdin", line \(.*\): \(.*\)$') +endfunction + +function! ale_linters#bib#bibclean#match_entry(line) abort + return matchlist(a:line, 'Entry input byte=.* line=\(.*\) column=\(.*\) output .*$') +endfunction + +function! ale_linters#bib#bibclean#match_value(line) abort + return matchlist(a:line, 'Value input byte=.* line=\(.*\) column=\(.*\) output .*$') +endfunction + +function! ale_linters#bib#bibclean#Handle(buffer, lines) abort + let l:output = [] + + let l:type = 'E' + let l:msg = '' + + for l:line in a:lines + if empty(l:msg) + let l:mlist = ale_linters#bib#bibclean#match_msg(l:line) + + if !empty(l:mlist) + let l:msg = l:mlist[3] + let l:type = ale_linters#bib#bibclean#get_type(l:mlist[1]) + endif + else + if l:type is# 'E' + let l:mlist = ale_linters#bib#bibclean#match_entry(l:line) + else + let l:mlist = ale_linters#bib#bibclean#match_value(l:line) + endif + + if !empty(l:mlist) + call add(l:output, { + \ 'lnum': l:mlist[1], + \ 'col': l:mlist[2], + \ 'text': l:msg, + \ 'type': l:type + \}) + + let l:msg = '' + endif + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('bib', { +\ 'name': 'bibclean', +\ 'executable': {b -> ale#Var(b, 'bib_bibclean_executable')}, +\ 'command': function('ale_linters#bib#bibclean#GetCommand'), +\ 'output_stream': 'stderr', +\ 'callback': 'ale_linters#bib#bibclean#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/c/ccls.vim b/pack/acp/start/ale/ale_linters/c/ccls.vim new file mode 100644 index 0000000..9e3dafe --- /dev/null +++ b/pack/acp/start/ale/ale_linters/c/ccls.vim @@ -0,0 +1,14 @@ +" Author: Ye Jingchen , Ben Falconer , jtalowell +" Description: A language server for C + +call ale#Set('c_ccls_executable', 'ccls') +call ale#Set('c_ccls_init_options', {}) + +call ale#linter#Define('c', { +\ 'name': 'ccls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'c_ccls_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'), +\ 'initialization_options': {b -> ale#Var(b, 'c_ccls_init_options')}, +\}) diff --git a/pack/acp/start/ale/ale_linters/c/clang.vim b/pack/acp/start/ale/ale_linters/c/clang.vim new file mode 100644 index 0000000..681101f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/c/clang.vim @@ -0,0 +1,24 @@ +" Author: Masahiro H https://github.com/mshr-h +" Description: clang linter for c files + +call ale#Set('c_clang_executable', 'clang') +call ale#Set('c_clang_options', '-std=c11 -Wall') + +function! ale_linters#c#clang#GetCommand(buffer, output) abort + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + + " -iquote with the directory the file is in makes #include work for + " headers in the same directory. + return '%e -S -x c -fsyntax-only' + \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . ale#Pad(l:cflags) + \ . ale#Pad(ale#Var(a:buffer, 'c_clang_options')) . ' -' +endfunction + +call ale#linter#Define('c', { +\ 'name': 'clang', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'c_clang_executable')}, +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clang#GetCommand'))}, +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/pack/acp/start/ale/ale_linters/c/clangd.vim b/pack/acp/start/ale/ale_linters/c/clangd.vim new file mode 100644 index 0000000..79b600f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/c/clangd.vim @@ -0,0 +1,17 @@ +" Author: Andrey Melentyev +" Description: Clangd language server + +call ale#Set('c_clangd_executable', 'clangd') +call ale#Set('c_clangd_options', '') + +function! ale_linters#c#clangd#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options')) +endfunction + +call ale#linter#Define('c', { +\ 'name': 'clangd', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'c_clangd_executable')}, +\ 'command': function('ale_linters#c#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/c/clangtidy.vim b/pack/acp/start/ale/ale_linters/c/clangtidy.vim new file mode 100644 index 0000000..f998866 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/c/clangtidy.vim @@ -0,0 +1,49 @@ +" Author: vdeurzen , w0rp , +" gagbo , Andrej Radovic +" Description: clang-tidy linter for c files + +call ale#Set('c_clangtidy_executable', 'clang-tidy') +" Set this option to check the checks clang-tidy will apply. +" The number of checks that can be applied to C files is limited in contrast to +" C++ +" +" Consult the check list in clang-tidy's documentation: +" http://clang.llvm.org/extra/clang-tidy/checks/list.html + +call ale#Set('c_clangtidy_checks', []) +" Set this option to manually set some options for clang-tidy to use as compile +" flags. +" This will disable compile_commands.json detection. +call ale#Set('c_clangtidy_options', '') +" Set this option to manually set options for clang-tidy directly. +call ale#Set('c_clangtidy_extra_options', '') +call ale#Set('c_build_dir', '') + +function! ale_linters#c#clangtidy#GetCommand(buffer) abort + let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',') + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + + " Get the extra options if we couldn't find a build directory. + let l:options = empty(l:build_dir) + \ ? ale#Var(a:buffer, 'c_clangtidy_options') + \ : '' + + " Get the options to pass directly to clang-tidy + let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options') + + return '%e' + \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') + \ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '') + \ . ' %s' + \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') + \ . (!empty(l:options) ? ' -- ' . l:options : '') +endfunction + +call ale#linter#Define('c', { +\ 'name': 'clangtidy', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')}, +\ 'command': function('ale_linters#c#clangtidy#GetCommand'), +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/c/cppcheck.vim b/pack/acp/start/ale/ale_linters/c/cppcheck.vim new file mode 100644 index 0000000..309b285 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/c/cppcheck.vim @@ -0,0 +1,28 @@ +" 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#GetCommand(buffer) abort + let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer) + let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) + let l:buffer_path_include = empty(l:compile_commands_option) + \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) + \ : '' + + return l:cd_command + \ . '%e -q --language=c' + \ . ale#Pad(l:compile_commands_option) + \ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options')) + \ . l:buffer_path_include + \ . ' %t' +endfunction + +call ale#linter#Define('c', { +\ 'name': 'cppcheck', +\ 'output_stream': 'both', +\ 'executable': {b -> ale#Var(b, 'c_cppcheck_executable')}, +\ 'command': function('ale_linters#c#cppcheck#GetCommand'), +\ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/c/cquery.vim b/pack/acp/start/ale/ale_linters/c/cquery.vim new file mode 100644 index 0000000..ff0f34a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/c/cquery.vim @@ -0,0 +1,30 @@ +" Author: Ben Falconer , jtalowell +" Description: A language server for C + +call ale#Set('c_cquery_executable', 'cquery') +call ale#Set('c_cquery_cache_directory', expand('~/.cache/cquery')) + +function! ale_linters#c#cquery#GetProjectRoot(buffer) abort + " Try to find cquery configuration files first. + let l:config = ale#path#FindNearestFile(a:buffer, '.cquery') + + if !empty(l:config) + return fnamemodify(l:config, ':h') + endif + + " Fall back on default project root detection. + return ale#c#FindProjectRoot(a:buffer) +endfunction + +function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort + return {'cacheDirectory': ale#Var(a:buffer, 'c_cquery_cache_directory')} +endfunction + +call ale#linter#Define('c', { +\ 'name': 'cquery', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'c_cquery_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#c#cquery#GetProjectRoot'), +\ 'initialization_options': function('ale_linters#c#cquery#GetInitializationOptions'), +\}) diff --git a/pack/acp/start/ale/ale_linters/c/flawfinder.vim b/pack/acp/start/ale/ale_linters/c/flawfinder.vim new file mode 100644 index 0000000..53c3671 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/c/flawfinder.vim @@ -0,0 +1,25 @@ +" Author: Christian Gibbons +" Description: flawfinder linter for c files + +call ale#Set('c_flawfinder_executable', 'flawfinder') +call ale#Set('c_flawfinder_options', '') +call ale#Set('c_flawfinder_minlevel', 1) +call ale#Set('c_flawfinder_error_severity', 6) + +function! ale_linters#c#flawfinder#GetCommand(buffer) abort + " Set the minimum vulnerability level for flawfinder to bother with + let l:minlevel = ' --minlevel=' . ale#Var(a:buffer, 'c_flawfinder_minlevel') + + return '%e -CDQS' + \ . ale#Pad(ale#Var(a:buffer, 'c_flawfinder_options')) + \ . l:minlevel + \ . ' %t' +endfunction + +call ale#linter#Define('c', { +\ 'name': 'flawfinder', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'c_flawfinder_executable')}, +\ 'command': function('ale_linters#c#flawfinder#GetCommand'), +\ 'callback': 'ale#handlers#flawfinder#HandleFlawfinderFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/c/gcc.vim b/pack/acp/start/ale/ale_linters/c/gcc.vim new file mode 100644 index 0000000..1df1018 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/c/gcc.vim @@ -0,0 +1,28 @@ +" 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#GetCommand(buffer, output) abort + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + + " -iquote with the directory the file is in makes #include work for + " headers in the same directory. + " + " `-o /dev/null` or `-o null` is needed to catch all errors, + " -fsyntax-only doesn't catch everything. + return '%e -S -x c' + \ . ' -o ' . g:ale#util#nul_file + \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . ale#Pad(l:cflags) + \ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -' +endfunction + +call ale#linter#Define('c', { +\ 'name': 'gcc', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'c_gcc_executable')}, +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#gcc#GetCommand'))}, +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/pack/acp/start/ale/ale_linters/chef/cookstyle.vim b/pack/acp/start/ale/ale_linters/chef/cookstyle.vim new file mode 100644 index 0000000..50bae2a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/chef/cookstyle.vim @@ -0,0 +1,54 @@ +" Author: Raphael Hoegger - https://github.com/pfuender +" Description: Cookstyle (RuboCop based), a code style analyzer for Ruby files + +call ale#Set('chef_cookstyle_executable', 'cookstyle') +call ale#Set('chef_cookstyle_options', '') + +function! ale_linters#chef#cookstyle#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'chef_cookstyle_options') + + return '%e' . ale#Pad(escape(l:options, '~')) . ' --force-exclusion --format json --stdin ' . ' %s' +endfunction + +function! ale_linters#chef#cookstyle#Handle(buffer, lines) abort + if len(a:lines) == 0 + return [] + endif + + let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], {}) + + if !has_key(l:errors, 'summary') + \|| l:errors['summary']['offense_count'] == 0 + \|| empty(l:errors['files']) + return [] + endif + + let l:output = [] + + for l:error in l:errors['files'][0]['offenses'] + let l:start_col = str2nr(l:error['location']['start_column']) + let l:end_col = str2nr(l:error['location']['last_column']) + + if !l:end_col + let l:end_col = l:start_col + 1 + endif + + call add(l:output, { + \ 'lnum': str2nr(l:error['location']['line']), + \ 'col': l:start_col, + \ 'end_col': l:end_col, + \ 'code': l:error['cop_name'], + \ 'text': l:error['message'], + \ 'type': l:error['severity'] is? 'convention' ? 'W' : 'E', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('chef', { +\ 'name': 'cookstyle', +\ 'executable': {b -> ale#Var(b, 'chef_cookstyle_executable')}, +\ 'command': function('ale_linters#chef#cookstyle#GetCommand'), +\ 'callback': 'ale_linters#chef#cookstyle#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/chef/foodcritic.vim b/pack/acp/start/ale/ale_linters/chef/foodcritic.vim new file mode 100644 index 0000000..48beba7 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/chef/foodcritic.vim @@ -0,0 +1,41 @@ +" Author: Edward Larkey +" Author: Jose Junior +" Author: w0rp +" Description: This file adds the foodcritic linter for Chef files. + +call ale#Set('chef_foodcritic_executable', 'foodcritic') +call ale#Set('chef_foodcritic_options', '') + +function! ale_linters#chef#foodcritic#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'chef_foodcritic_options') + + return '%e' . ale#Pad(escape(l:options, '~')) . ' %s' +endfunction + +function! ale_linters#chef#foodcritic#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " FC002: Avoid string interpolation where not required: httpd.rb:13 + let l:pattern = '\v([^:]+): (.+): ([a-zA-Z]?:?[^:]+):(\d+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'code': l:match[1], + \ 'text': l:match[2], + \ 'filename': l:match[3], + \ 'lnum': l:match[4] + 0, + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('chef', { +\ 'name': 'foodcritic', +\ 'executable': {b -> ale#Var(b, 'chef_foodcritic_executable')}, +\ 'command': function('ale_linters#chef#foodcritic#GetCommand'), +\ 'callback': 'ale_linters#chef#foodcritic#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/clojure/clj_kondo.vim b/pack/acp/start/ale/ale_linters/clojure/clj_kondo.vim new file mode 100644 index 0000000..5dd11c1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/clojure/clj_kondo.vim @@ -0,0 +1,34 @@ +" Author: Masashi Iizuka +" Description: linter for clojure using clj-kondo https://github.com/borkdude/clj-kondo + +function! ale_linters#clojure#clj_kondo#HandleCljKondoFormat(buffer, lines) abort + " output format + " ::: : + let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+):? ((Exception|error|warning): ?(.+))$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:type = 'E' + + if l:match[4] is? 'warning' + let l:type = 'W' + endif + + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[3], + \ 'type': l:type, + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('clojure', { +\ 'name': 'clj-kondo', +\ 'output_stream': 'stdout', +\ 'executable': 'clj-kondo', +\ 'command': 'clj-kondo --lint %t', +\ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/clojure/joker.vim b/pack/acp/start/ale/ale_linters/clojure/joker.vim new file mode 100644 index 0000000..1f17cd3 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/clojure/joker.vim @@ -0,0 +1,34 @@ +" Author: Nic West +" Description: linter for clojure using joker https://github.com/candid82/joker + +function! ale_linters#clojure#joker#HandleJokerFormat(buffer, lines) abort + " output format + " ::: : + let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+):? ((Read error|Parse error|Parse warning|Exception): ?(.+))$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:type = 'E' + + if l:match[4] is? 'Parse warning' + let l:type = 'W' + endif + + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[3], + \ 'type': l:type, + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('clojure', { +\ 'name': 'joker', +\ 'output_stream': 'stderr', +\ 'executable': 'joker', +\ 'command': 'joker --working-dir %s --lint %t', +\ 'callback': 'ale_linters#clojure#joker#HandleJokerFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/cloudformation/cfn_python_lint.vim b/pack/acp/start/ale/ale_linters/cloudformation/cfn_python_lint.vim new file mode 100644 index 0000000..d0ac7b2 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cloudformation/cfn_python_lint.vim @@ -0,0 +1,35 @@ +" Author: Yasuhiro Kiyota +" Description: Support cfn-python-lint for AWS Cloudformation template file + +function! ale_linters#cloudformation#cfn_python_lint#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " sample.template.yaml:96:7:96:15:E3012:Property Resources/Sample/Properties/FromPort should be of type Integer + let l:pattern = '\v^(.*):(\d+):(\d+):(\d+):(\d+):([[:alnum:]]+):(.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:code = l:match[6] + + if ale#path#IsBufferPath(a:buffer, l:match[1]) + call add(l:output, { + \ 'lnum': l:match[2], + \ 'col': l:match[3], + \ 'end_lnum': l:match[4], + \ 'end_col': l:match[5], + \ 'code': l:code, + \ 'type': l:code[:0] is# 'E' ? 'E' : 'W', + \ 'text': l:match[7] + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('cloudformation', { +\ 'name': 'cloudformation', +\ 'executable': 'cfn-lint', +\ 'command': 'cfn-lint --template %t --format parseable', +\ 'callback': 'ale_linters#cloudformation#cfn_python_lint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/cmake/cmakelint.vim b/pack/acp/start/ale/ale_linters/cmake/cmakelint.vim new file mode 100644 index 0000000..d955a26 --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#cmake#cmakelint#Executable'), +\ 'command': function('ale_linters#cmake#cmakelint#Command'), +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/pack/acp/start/ale/ale_linters/coffee/coffee.vim b/pack/acp/start/ale/ale_linters/coffee/coffee.vim new file mode 100644 index 0000000..8e89163 --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#coffee#coffee#GetExecutable'), +\ 'command': function('ale_linters#coffee#coffee#GetCommand'), +\ 'output_stream': 'stderr', +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/coffee/coffeelint.vim b/pack/acp/start/ale/ale_linters/coffee/coffeelint.vim new file mode 100644 index 0000000..b7c85fa --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#coffee#coffeelint#GetExecutable'), +\ 'command': function('ale_linters#coffee#coffeelint#GetCommand'), +\ 'callback': 'ale_linters#coffee#coffeelint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/ccls.vim b/pack/acp/start/ale/ale_linters/cpp/ccls.vim new file mode 100644 index 0000000..b265ff7 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/ccls.vim @@ -0,0 +1,14 @@ +" Author: Ye Jingchen , Ben Falconer , jtalowell +" Description: A language server for C++ + +call ale#Set('cpp_ccls_executable', 'ccls') +call ale#Set('cpp_ccls_init_options', {}) + +call ale#linter#Define('cpp', { +\ 'name': 'ccls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'cpp_ccls_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'), +\ 'initialization_options': {b -> ale#Var(b, 'cpp_ccls_init_options')}, +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/clang.vim b/pack/acp/start/ale/ale_linters/cpp/clang.vim new file mode 100644 index 0000000..e48291e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/clang.vim @@ -0,0 +1,24 @@ +" 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#GetCommand(buffer, output) abort + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + + " -iquote with the directory the file is in makes #include work for + " headers in the same directory. + return '%e -S -x c++ -fsyntax-only' + \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . ale#Pad(l:cflags) + \ . ale#Pad(ale#Var(a:buffer, 'cpp_clang_options')) . ' -' +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'clang', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'cpp_clang_executable')}, +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clang#GetCommand'))}, +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/clangcheck.vim b/pack/acp/start/ale/ale_linters/cpp/clangcheck.vim new file mode 100644 index 0000000..7d32a57 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/clangcheck.vim @@ -0,0 +1,35 @@ +" 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#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:root, l:json_file] = ale#c#FindCompileCommands(a:buffer) + let l:build_dir = ale#path#Dirname(l:json_file) + endif + + " The extra arguments in the command are used to prevent .plist files from + " being generated. These are only added if no build directory can be + " detected. + return '%e -analyze %s' + \ . (empty(l:build_dir) ? ' -extra-arg -Xclang -extra-arg -analyzer-output=text' : '') + \ . ale#Pad(l:user_options) + \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'clangcheck', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'cpp_clangcheck_executable')}, +\ 'command': function('ale_linters#cpp#clangcheck#GetCommand'), +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/clangd.vim b/pack/acp/start/ale/ale_linters/cpp/clangd.vim new file mode 100644 index 0000000..fab605f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/clangd.vim @@ -0,0 +1,17 @@ +" Author: Andrey Melentyev +" Description: Clangd language server + +call ale#Set('cpp_clangd_executable', 'clangd') +call ale#Set('cpp_clangd_options', '') + +function! ale_linters#cpp#clangd#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options')) +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'clangd', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')}, +\ 'command': function('ale_linters#cpp#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/clangtidy.vim b/pack/acp/start/ale/ale_linters/cpp/clangtidy.vim new file mode 100644 index 0000000..085bc33 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/clangtidy.vim @@ -0,0 +1,43 @@ +" 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 to use as compile +" flags. +" This will disable compile_commands.json detection. +call ale#Set('cpp_clangtidy_options', '') +" Set this option to manually set options for clang-tidy directly. +call ale#Set('cpp_clangtidy_extra_options', '') +call ale#Set('c_build_dir', '') + +function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort + let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',') + let l:build_dir = ale#c#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') + \ : '' + + " Get the options to pass directly to clang-tidy + let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options') + + return '%e' + \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') + \ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '') + \ . ' %s' + \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') + \ . (!empty(l:options) ? ' -- ' . l:options : '') +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'clangtidy', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')}, +\ 'command': function('ale_linters#cpp#clangtidy#GetCommand'), +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/clazy.vim b/pack/acp/start/ale/ale_linters/cpp/clazy.vim new file mode 100644 index 0000000..9b29ac9 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/clazy.vim @@ -0,0 +1,32 @@ +" Description: clazy linter for cpp files (clang-based and Qt-oriented) + +call ale#Set('cpp_clazy_executable', 'clazy-standalone') +" Set this option to check the checks clazy will apply. +call ale#Set('cpp_clazy_checks', ['level1']) +" Set this option to manually set some options for clazy. +" This will disable compile_commands.json detection. +call ale#Set('cpp_clazy_options', '') +call ale#Set('c_build_dir', '') + +function! ale_linters#cpp#clazy#GetCommand(buffer) abort + let l:checks = join(ale#Var(a:buffer, 'cpp_clazy_checks'), ',') + let l:build_dir = ale#c#GetBuildDirectory(a:buffer) + + " Get the extra options if we couldn't find a build directory. + let l:options = ale#Var(a:buffer, 'cpp_clazy_options') + + return '%e' + \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') + \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' %s' +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'clazy', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'cpp_clazy_executable')}, +\ 'command': function('ale_linters#cpp#clazy#GetCommand'), +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/cppcheck.vim b/pack/acp/start/ale/ale_linters/cpp/cppcheck.vim new file mode 100644 index 0000000..7cd80db --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/cppcheck.vim @@ -0,0 +1,28 @@ +" 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#GetCommand(buffer) abort + let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer) + let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) + let l:buffer_path_include = empty(l:compile_commands_option) + \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) + \ : '' + + return l:cd_command + \ . '%e -q --language=c++' + \ . ale#Pad(l:compile_commands_option) + \ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options')) + \ . l:buffer_path_include + \ . ' %t' +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'cppcheck', +\ 'output_stream': 'both', +\ 'executable': {b -> ale#Var(b, 'cpp_cppcheck_executable')}, +\ 'command': function('ale_linters#cpp#cppcheck#GetCommand'), +\ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/cpplint.vim b/pack/acp/start/ale/ale_linters/cpp/cpplint.vim new file mode 100644 index 0000000..f1f6ce7 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/cpplint.vim @@ -0,0 +1,20 @@ +" 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#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'cpp_cpplint_options') + + return '%e' . ale#Pad(l:options) . ' %s' +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'cpplint', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'cpp_cpplint_executable')}, +\ 'command': function('ale_linters#cpp#cpplint#GetCommand'), +\ 'callback': 'ale#handlers#cpplint#HandleCppLintFormat', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/cquery.vim b/pack/acp/start/ale/ale_linters/cpp/cquery.vim new file mode 100644 index 0000000..2971cdc --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/cquery.vim @@ -0,0 +1,30 @@ +" Author: Ben Falconer +" Description: A language server for C++ + +call ale#Set('cpp_cquery_executable', 'cquery') +call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery')) + +function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort + " Try to find cquery configuration files first. + let l:config = ale#path#FindNearestFile(a:buffer, '.cquery') + + if !empty(l:config) + return fnamemodify(l:config, ':h') + endif + + " Fall back on default project root detection. + return ale#c#FindProjectRoot(a:buffer) +endfunction + +function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort + return {'cacheDirectory': ale#Var(a:buffer, 'cpp_cquery_cache_directory')} +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'cquery', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'cpp_cquery_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#cpp#cquery#GetProjectRoot'), +\ 'initialization_options': function('ale_linters#cpp#cquery#GetInitializationOptions'), +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/flawfinder.vim b/pack/acp/start/ale/ale_linters/cpp/flawfinder.vim new file mode 100644 index 0000000..5bfdea2 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cpp/flawfinder.vim @@ -0,0 +1,25 @@ +" Author: Christian Gibbons +" Description: flawfinder linter for c++ files + +call ale#Set('cpp_flawfinder_executable', 'flawfinder') +call ale#Set('cpp_flawfinder_options', '') +call ale#Set('cpp_flawfinder_minlevel', 1) +call ale#Set('c_flawfinder_error_severity', 6) + +function! ale_linters#cpp#flawfinder#GetCommand(buffer) abort + " Set the minimum vulnerability level for flawfinder to bother with + let l:minlevel = ' --minlevel=' . ale#Var(a:buffer, 'cpp_flawfinder_minlevel') + + return '%e -CDQS' + \ . ale#Var(a:buffer, 'cpp_flawfinder_options') + \ . l:minlevel + \ . ' %t' +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'flawfinder', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'cpp_flawfinder_executable')}, +\ 'command': function('ale_linters#cpp#flawfinder#GetCommand'), +\ 'callback': 'ale#handlers#flawfinder#HandleFlawfinderFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/cpp/gcc.vim b/pack/acp/start/ale/ale_linters/cpp/gcc.vim new file mode 100644 index 0000000..108d6d7 --- /dev/null +++ b/pack/acp/start/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#GetCommand(buffer, output) abort + let l:cflags = ale#c#GetCFlags(a:buffer, a:output) + + " -iquote with the directory the file is in makes #include work for + " headers in the same directory. + " + " `-o /dev/null` or `-o null` is needed to catch all errors, + " -fsyntax-only doesn't catch everything. + return '%e -S -x c++' + \ . ' -o ' . g:ale#util#nul_file + \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . ale#Pad(l:cflags) + \ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -' +endfunction + +call ale#linter#Define('cpp', { +\ 'name': 'gcc', +\ 'aliases': ['g++'], +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'cpp_gcc_executable')}, +\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#gcc#GetCommand'))}, +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/pack/acp/start/ale/ale_linters/crystal/ameba.vim b/pack/acp/start/ale/ale_linters/crystal/ameba.vim new file mode 100644 index 0000000..5dfc7f4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/crystal/ameba.vim @@ -0,0 +1,57 @@ +" Author: Harrison Bachrach - https://github.com/HarrisonB +" Description: Ameba, a linter for crystal files + +call ale#Set('crystal_ameba_executable', 'bin/ameba') + +function! ale_linters#crystal#ameba#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'crystal_ameba_executable') + + return ale#Escape(l:executable) + \ . ' --format json ' + \ . ale#Escape(expand('#' . a:buffer . ':p')) +endfunction + +" Handle output from ameba +function! ale_linters#crystal#ameba#HandleAmebaOutput(buffer, lines) abort + if len(a:lines) == 0 + return [] + endif + + let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], {}) + + if !has_key(l:errors, 'summary') + \|| l:errors['summary']['issues_count'] == 0 + \|| empty(l:errors['sources']) + return [] + endif + + let l:output = [] + + for l:error in l:errors['sources'][0]['issues'] + let l:start_col = str2nr(l:error['location']['column']) + let l:end_col = str2nr(l:error['end_location']['column']) + + if !l:end_col + let l:end_col = l:start_col + 1 + endif + + call add(l:output, { + \ 'lnum': str2nr(l:error['location']['line']), + \ 'col': l:start_col, + \ 'end_col': l:end_col, + \ 'code': l:error['rule_name'], + \ 'text': l:error['message'], + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('crystal', { +\ 'name': 'ameba', +\ 'executable': {b -> ale#Var(b, 'crystal_ameba_executable')}, +\ 'command': function('ale_linters#crystal#ameba#GetCommand'), +\ 'callback': 'ale_linters#crystal#ameba#HandleAmebaOutput', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/crystal/crystal.vim b/pack/acp/start/ale/ale_linters/crystal/crystal.vim new file mode 100644 index 0000000..3c2fefb --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#crystal#crystal#GetCommand'), +\ 'callback': 'ale_linters#crystal#crystal#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/cs/mcs.vim b/pack/acp/start/ale/ale_linters/cs/mcs.vim new file mode 100644 index 0000000..1b373e7 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cs/mcs.vim @@ -0,0 +1,37 @@ +let g:ale_cs_mcs_options = get(g:, 'ale_cs_mcs_options', '') + +function! ale_linters#cs#mcs#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'cs_mcs_options') + + return 'mcs -unsafe --parse' + \ . (!empty(l:options) ? ' ' . l: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 = '^\v(.+\.cs)\((\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, + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \ 'code': l:match[5], + \ 'text': l:match[6], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('cs',{ +\ 'name': 'mcs', +\ 'output_stream': 'stderr', +\ 'executable': 'mcs', +\ 'command': function('ale_linters#cs#mcs#GetCommand'), +\ 'callback': 'ale_linters#cs#mcs#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/cs/mcsc.vim b/pack/acp/start/ale/ale_linters/cs/mcsc.vim new file mode 100644 index 0000000..dd067eb --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cs/mcsc.vim @@ -0,0 +1,81 @@ +call ale#Set('cs_mcsc_options', '') +call ale#Set('cs_mcsc_source', '') +call ale#Set('cs_mcsc_assembly_path', []) +call ale#Set('cs_mcsc_assemblies', []) + +function! s:GetWorkingDirectory(buffer) abort + let l:working_directory = ale#Var(a:buffer, 'cs_mcsc_source') + + if !empty(l:working_directory) + return l:working_directory + endif + + return expand('#' . a:buffer . ':p:h') +endfunction + +function! ale_linters#cs#mcsc#GetCommand(buffer) abort + " Pass assembly paths via the -lib: parameter. + let l:path_list = ale#Var(a:buffer, 'cs_mcsc_assembly_path') + + let l:lib_option = !empty(l:path_list) + \ ? '-lib:' . join(map(copy(l:path_list), 'ale#Escape(v:val)'), ',') + \ : '' + + " Pass paths to DLL files via the -r: parameter. + let l:assembly_list = ale#Var(a:buffer, 'cs_mcsc_assemblies') + + let l:r_option = !empty(l:assembly_list) + \ ? '-r:' . join(map(copy(l:assembly_list), 'ale#Escape(v:val)'), ',') + \ : '' + + " register temporary module target file with ale + " register temporary module target file with ALE. + let l:out = ale#command#CreateFile(a:buffer) + + " The code is compiled as a module and the output is redirected to a + " temporary file. + return ale#path#CdString(s:GetWorkingDirectory(a:buffer)) + \ . 'mcs -unsafe' + \ . ale#Pad(ale#Var(a:buffer, 'cs_mcsc_options')) + \ . ale#Pad(l:lib_option) + \ . ale#Pad(l:r_option) + \ . ' -out:' . l:out + \ . ' -t:module' + \ . ' -recurse:' . ale#Escape('*.cs') +endfunction + +function! ale_linters#cs#mcsc#Handle(buffer, lines) abort + " Look for lines like the following. + " + " Tests.cs(12,29): error CSXXXX: ; expected + " + " NOTE: pattern also captures file name as linter compiles all + " files within the source tree rooted at the specified source + " path and not just the file loaded in the buffer + let l:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$' + let l:output = [] + + let l:dir = s:GetWorkingDirectory(a:buffer) + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \ 'code': l:match[5], + \ 'text': l:match[6], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('cs',{ +\ 'name': 'mcsc', +\ 'output_stream': 'stderr', +\ 'executable': 'mcs', +\ 'command': function('ale_linters#cs#mcsc#GetCommand'), +\ 'callback': 'ale_linters#cs#mcsc#Handle', +\ 'lint_file': 1 +\}) diff --git a/pack/acp/start/ale/ale_linters/css/csslint.vim b/pack/acp/start/ale/ale_linters/css/csslint.vim new file mode 100644 index 0000000..50c21ce --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#css#csslint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleCSSLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/css/fecs.vim b/pack/acp/start/ale/ale_linters/css/fecs.vim new file mode 100644 index 0000000..511847c --- /dev/null +++ b/pack/acp/start/ale/ale_linters/css/fecs.vim @@ -0,0 +1,9 @@ +" Author: harttle +" Description: fecs for CSS files + +call ale#linter#Define('css', { +\ 'name': 'fecs', +\ 'executable': function('ale#handlers#fecs#GetExecutable'), +\ 'command': function('ale#handlers#fecs#GetCommand'), +\ 'callback': 'ale#handlers#fecs#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/css/stylelint.vim b/pack/acp/start/ale/ale_linters/css/stylelint.vim new file mode 100644 index 0000000..38cb0e0 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/css/stylelint.vim @@ -0,0 +1,19 @@ +" Author: diartyz + +call ale#Set('css_stylelint_executable', 'stylelint') +call ale#Set('css_stylelint_options', '') +call ale#Set('css_stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#css#stylelint#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'css_stylelint_options')) + \ . ' --stdin-filename %s' +endfunction + +call ale#linter#Define('css', { +\ 'name': 'stylelint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'css_stylelint', [ +\ 'node_modules/.bin/stylelint', +\ ])}, +\ 'command': function('ale_linters#css#stylelint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleStyleLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/cucumber/cucumber.vim b/pack/acp/start/ale/ale_linters/cucumber/cucumber.vim new file mode 100644 index 0000000..0cfd815 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cucumber/cucumber.vim @@ -0,0 +1,46 @@ +" Author: Eddie Lebow https://github.com/elebow +" Description: Cucumber, a BDD test tool + +function! ale_linters#cucumber#cucumber#GetCommand(buffer) abort + let l:features_dir = ale#path#FindNearestDirectory(a:buffer, 'features') + + if !empty(l:features_dir) + let l:features_arg = '-r ' . ale#Escape(l:features_dir) + else + let l:features_arg = '' + endif + + return 'cucumber --dry-run --quiet --strict --format=json ' + \ . l:features_arg . ' %t' +endfunction + +function! ale_linters#cucumber#cucumber#Handle(buffer, lines) abort + try + let l:json = ale#util#FuzzyJSONDecode(a:lines, {})[0] + catch + return [] + endtry + + let l:output = [] + + for l:element in get(l:json, 'elements', []) + for l:step in l:element['steps'] + if l:step['result']['status'] is# 'undefined' + call add(l:output, { + \ 'lnum': l:step['line'], + \ 'code': 'E', + \ 'text': 'Undefined step' + \}) + endif + endfor + endfor + + return l:output +endfunction + +call ale#linter#Define('cucumber', { +\ 'name': 'cucumber', +\ 'executable': 'cucumber', +\ 'command': function('ale_linters#cucumber#cucumber#GetCommand'), +\ 'callback': 'ale_linters#cucumber#cucumber#Handle' +\}) diff --git a/pack/acp/start/ale/ale_linters/cuda/nvcc.vim b/pack/acp/start/ale/ale_linters/cuda/nvcc.vim new file mode 100644 index 0000000..f3af07b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cuda/nvcc.vim @@ -0,0 +1,49 @@ +" Author: blahgeek +" Description: NVCC linter for cuda files + +call ale#Set('cuda_nvcc_executable', 'nvcc') +call ale#Set('cuda_nvcc_options', '-std=c++11') + +function! ale_linters#cuda#nvcc#GetCommand(buffer) abort + " Unused: use ale#util#nul_file + " let l:output_file = ale#util#Tempname() . '.ii' + " call ale#command#ManageFile(a:buffer, l:output_file) + return '%e -cuda' + \ . ale#Pad(ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))) + \ . ale#Pad(ale#Var(a:buffer, 'cuda_nvcc_options')) + \ . ' %s -o ' . g:ale#util#nul_file +endfunction + +function! ale_linters#cuda#nvcc#HandleNVCCFormat(buffer, lines) abort + " Look for lines like the following. + " + " test.cu(8): error: argument of type "void *" is incompatible with parameter of type "int *" + let l:pattern = '\v^([^:\(\)]+):?\(?(\d+)\)?:(\d+)?:?\s*\w*\s*(error|warning): (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': str2nr(l:match[2]), + \ 'type': l:match[4] =~# 'error' ? 'E' : 'W', + \ 'text': l:match[5], + \ 'filename': fnamemodify(l:match[1], ':p'), + \} + + if !empty(l:match[3]) + let l:item.col = str2nr(l:match[3]) + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('cuda', { +\ 'name': 'nvcc', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'cuda_nvcc_executable')}, +\ 'command': function('ale_linters#cuda#nvcc#GetCommand'), +\ 'callback': 'ale_linters#cuda#nvcc#HandleNVCCFormat', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/cypher/cypher_lint.vim b/pack/acp/start/ale/ale_linters/cypher/cypher_lint.vim new file mode 100644 index 0000000..408ddd6 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/cypher/cypher_lint.vim @@ -0,0 +1,26 @@ +" Author: Francisco Lopes +" Description: Linting for Neo4j's Cypher + +function! ale_linters#cypher#cypher_lint#Handle(buffer, lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+): (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[4], + \ 'type': 'E', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('cypher', { +\ 'name': 'cypher_lint', +\ 'executable': 'cypher-lint', +\ 'command': 'cypher-lint', +\ 'output_stream': 'stderr', +\ 'callback': 'ale_linters#cypher#cypher_lint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/d/dls.vim b/pack/acp/start/ale/ale_linters/d/dls.vim new file mode 100644 index 0000000..78d1c15 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/d/dls.vim @@ -0,0 +1,22 @@ +" Author: aurieh +" Description: A Language Server implementation for D + +call ale#Set('d_dls_executable', 'dls') + +function! ale_linters#d#dls#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'd_dls_executable') +endfunction + +function! ale_linters#d#dls#FindProjectRoot(buffer) abort + " Note: this will return . if dub config is empty + " dls can run outside DUB projects just fine + return fnamemodify(ale#d#FindDUBConfig(a:buffer), ':h') +endfunction + +call ale#linter#Define('d', { +\ 'name': 'dls', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#d#dls#GetExecutable'), +\ 'command': function('ale_linters#d#dls#GetExecutable'), +\ 'project_root': function('ale_linters#d#dls#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/d/dmd.vim b/pack/acp/start/ale/ale_linters/d/dmd.vim new file mode 100644 index 0000000..14461ae --- /dev/null +++ b/pack/acp/start/ale/ale_linters/d/dmd.vim @@ -0,0 +1,74 @@ +" Author: w0rp +" Description: "dmd for D files" + +function! ale_linters#d#dmd#GetDUBCommand(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 = ale#d#FindDUBConfig(a:buffer) + + if empty(l:dub_file) + return '' + endif + + " To support older dub versions, we just change the directory to + " the directory where we found the dub config, and then run `dub describe` + " from that directory. + return 'cd ' . ale#Escape(fnamemodify(l:dub_file, ':h')) + \ . ' && dub describe --import-paths' +endfunction + +function! ale_linters#d#dmd#RunDUBCommand(buffer) abort + let l:command = ale_linters#d#dmd#GetDUBCommand(a:buffer) + + if empty(l:command) + " If we can't run DUB, just run DMD. + return ale_linters#d#dmd#DMDCommand(a:buffer, [], {}) + endif + + return ale#command#Run(a:buffer, l:command, function('ale_linters#d#dmd#DMDCommand')) +endfunction + +function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) 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- -wi -vcolumns -c %t' +endfunction + +function! ale_linters#d#dmd#Handle(buffer, lines) abort + " Matches patterns lines like the following: + " /tmp/tmp.qclsa7qLP7/file.d(1): Error: function declaration without return type. (Note that constructors are always named 'this') + " /tmp/tmp.G1L5xIizvB.d(8,8): Error: module weak_reference is in file 'dstruct/weak_reference.d' which cannot be read + let l:pattern = '^[^(]\+(\([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': function('ale_linters#d#dmd#RunDUBCommand'), +\ 'callback': 'ale_linters#d#dmd#Handle', +\ 'output_stream': 'stderr', +\}) diff --git a/pack/acp/start/ale/ale_linters/dafny/dafny.vim b/pack/acp/start/ale/ale_linters/dafny/dafny.vim new file mode 100644 index 0000000..b5b9067 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/dafny/dafny.vim @@ -0,0 +1,26 @@ +" Author: Taylor Blau + +function! ale_linters#dafny#dafny#Handle(buffer, lines) abort + let l:pattern = '\v(.*)\((\d+),(\d+)\): (.*): (.*)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'col': l:match[3] + 0, + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[5], + \ 'type': l:match[4] =~# '^Error' ? 'E' : 'W' + \ }) + endfor + + return l:output +endfunction + +call ale#linter#Define('dafny', { +\ 'name': 'dafny', +\ 'executable': 'dafny', +\ 'command': 'dafny %s /compile:0', +\ 'callback': 'ale_linters#dafny#dafny#Handle', +\ 'lint_file': 1, +\ }) diff --git a/pack/acp/start/ale/ale_linters/dart/dartanalyzer.vim b/pack/acp/start/ale/ale_linters/dart/dartanalyzer.vim new file mode 100644 index 0000000..0a4d974 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/dart/dartanalyzer.vim @@ -0,0 +1,36 @@ +" Author: w0rp +" Description: Check Dart files with dartanalyzer + +call ale#Set('dart_dartanalyzer_executable', 'dartanalyzer') + +function! ale_linters#dart#dartanalyzer#GetCommand(buffer) abort + let l:path = ale#path#FindNearestFile(a:buffer, '.packages') + + return '%e' + \ . (!empty(l:path) ? ' --packages ' . ale#Escape(l:path) : '') + \ . ' %s' +endfunction + +function! ale_linters#dart#dartanalyzer#Handle(buffer, lines) abort + let l:pattern = '\v^ ([a-z]+) . (.+) at (.+):(\d+):(\d+) . (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'type': l:match[1] is# 'error' ? 'E' : 'W', + \ 'text': l:match[6] . ': ' . l:match[2], + \ 'lnum': str2nr(l:match[4]), + \ 'col': str2nr(l:match[5]), + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('dart', { +\ 'name': 'dartanalyzer', +\ 'executable': {b -> ale#Var(b, 'dart_dartanalyzer_executable')}, +\ 'command': function('ale_linters#dart#dartanalyzer#GetCommand'), +\ 'callback': 'ale_linters#dart#dartanalyzer#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/dart/language_server.vim b/pack/acp/start/ale/ale_linters/dart/language_server.vim new file mode 100644 index 0000000..d0e639c --- /dev/null +++ b/pack/acp/start/ale/ale_linters/dart/language_server.vim @@ -0,0 +1,20 @@ +" Author: aurieh +" Description: A language server for dart + +call ale#Set('dart_language_server_executable', 'dart_language_server') + +function! ale_linters#dart#language_server#GetProjectRoot(buffer) abort + " Note: pub only looks for pubspec.yaml, there's no point in adding + " support for pubspec.yml + let l:pubspec = ale#path#FindNearestFile(a:buffer, 'pubspec.yaml') + + return !empty(l:pubspec) ? fnamemodify(l:pubspec, ':h:h') : '' +endfunction + +call ale#linter#Define('dart', { +\ 'name': 'language_server', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'dart_language_server_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#dart#language_server#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/dockerfile/dockerfile_lint.vim b/pack/acp/start/ale/ale_linters/dockerfile/dockerfile_lint.vim new file mode 100644 index 0000000..95768b1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/dockerfile/dockerfile_lint.vim @@ -0,0 +1,61 @@ +" Author: Alexander Olofsson + +call ale#Set('dockerfile_dockerfile_lint_executable', 'dockerfile_lint') +call ale#Set('dockerfile_dockerfile_lint_options', '') + +function! ale_linters#dockerfile#dockerfile_lint#GetType(type) abort + if a:type is? 'error' + return 'E' + elseif a:type is? 'warn' + return 'W' + endif + + return 'I' +endfunction + +function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort + try + let l:data = json_decode(join(a:lines, '')) + catch + return [] + endtry + + if empty(l:data) + " Should never happen, but it's better to be on the safe side + return [] + endif + + let l:messages = [] + + for l:type in ['error', 'warn', 'info'] + for l:object in l:data[l:type]['data'] + let l:line = get(l:object, 'line', -1) + let l:message = l:object['message'] + + if get(l:object, 'description', 'None') isnot# 'None' + let l:message = l:message . '. ' . l:object['description'] + endif + + call add(l:messages, { + \ 'lnum': l:line, + \ 'text': l:message, + \ 'type': ale_linters#dockerfile#dockerfile_lint#GetType(l:type), + \}) + endfor + endfor + + return l:messages +endfunction + +function! ale_linters#dockerfile#dockerfile_lint#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'dockerfile_dockerfile_lint_options')) + \ . ' -p -j -f' + \ . ' %t' +endfunction + +call ale#linter#Define('dockerfile', { +\ 'name': 'dockerfile_lint', +\ 'executable': {b -> ale#Var(b, 'dockerfile_dockerfile_lint_executable')}, +\ 'command': function('ale_linters#dockerfile#dockerfile_lint#GetCommand'), +\ 'callback': 'ale_linters#dockerfile#dockerfile_lint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/dockerfile/hadolint.vim b/pack/acp/start/ale/ale_linters/dockerfile/hadolint.vim new file mode 100644 index 0000000..e57cd76 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/dockerfile/hadolint.vim @@ -0,0 +1,99 @@ +" Author: hauleth - https://github.com/hauleth + +" always, yes, never +call ale#Set('dockerfile_hadolint_use_docker', 'never') +call ale#Set('dockerfile_hadolint_docker_image', 'hadolint/hadolint') + +function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " /dev/stdin:19 DL3001 Pipe chain should start with a raw value. + " /dev/stdin:19:3 unexpected thing + let l:pattern = '\v^/dev/stdin:(\d+):?(\d+)? ((DL|SC)(\d+) )?(.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:lnum = 0 + let l:colnum = 0 + + if l:match[1] isnot# '' + let l:lnum = l:match[1] + 0 + endif + + if l:match[2] isnot# '' + let l:colnum = l:match[2] + 0 + endif + + let l:type = 'W' + let l:text = l:match[6] + let l:detail = l:match[6] + let l:domain = 'https://github.com/hadolint/hadolint/wiki/' + + if l:match[4] is# 'SC' + let l:domain = 'https://github.com/koalaman/shellcheck/wiki/' + endif + + if l:match[5] isnot# '' + let l:code = l:match[4] . l:match[5] + let l:link = ' ( ' . l:domain . l:code . ' )' + let l:detail = l:code . l:link . "\n\n" . l:detail + else + let l:type = 'E' + endif + + call add(l:output, { + \ 'lnum': l:lnum, + \ 'col': l:colnum, + \ 'type': l:type, + \ 'text': l:text, + \ 'detail': l:detail + \}) + endfor + + return l:output +endfunction + +" This is a little different than the typical 'executable' callback. We want +" to afford the user the chance to say always use docker, never use docker, +" and use docker if the hadolint executable is not present on the system. +" +" In the case of neither docker nor hadolint executables being present, it +" really doesn't matter which we return -- either will have the effect of +" 'nope, can't use this linter!'. + +function! ale_linters#dockerfile#hadolint#GetExecutable(buffer) abort + let l:use_docker = ale#Var(a:buffer, 'dockerfile_hadolint_use_docker') + + " check for mandatory directives + if l:use_docker is# 'never' + return 'hadolint' + elseif l:use_docker is# 'always' + return 'docker' + 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': function('ale_linters#dockerfile#hadolint#GetExecutable'), +\ 'command': function('ale_linters#dockerfile#hadolint#GetCommand'), +\ 'callback': 'ale_linters#dockerfile#hadolint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/elixir/credo.vim b/pack/acp/start/ale/ale_linters/elixir/credo.vim new file mode 100644 index 0000000..317ecab --- /dev/null +++ b/pack/acp/start/ale/ale_linters/elixir/credo.vim @@ -0,0 +1,63 @@ +" 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] + + " Refactoring opportunities + if l:type is# 'F' + let l:type = 'W' + " Consistency + elseif l:type is# 'C' + let l:type = 'W' + " Software Design + elseif l:type is# 'D' + let l:type = 'I' + " Code Readability + elseif l:type is# 'R' + let l:type = 'I' + 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 + +function! ale_linters#elixir#credo#GetMode() abort + if get(g:, 'ale_elixir_credo_strict', 0) + return '--strict' + else + return 'suggest' + endif +endfunction + +function! ale_linters#elixir#credo#GetCommand(buffer) abort + let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) + let l:mode = ale_linters#elixir#credo#GetMode() + + return ale#path#CdString(l:project_root) + \ . 'mix help credo && ' + \ . 'mix credo ' . ale_linters#elixir#credo#GetMode() + \ . ' --format=flycheck --read-from-stdin %s' +endfunction + +call ale#linter#Define('elixir', { +\ 'name': 'credo', +\ 'executable': 'mix', +\ 'command': function('ale_linters#elixir#credo#GetCommand'), +\ 'callback': 'ale_linters#elixir#credo#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/elixir/dialyxir.vim b/pack/acp/start/ale/ale_linters/elixir/dialyxir.vim new file mode 100644 index 0000000..c7da775 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/elixir/dialyxir.vim @@ -0,0 +1,41 @@ +" Author: Fran C. - https://github.com/franciscoj +" Description: Add dialyzer support for elixir through dialyxir +" https://github.com/jeremyjh/dialyxir + +function! ale_linters#elixir#dialyxir#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " lib/filename.ex:19: Function fname/1 has no local return + let l:pattern = '\v(.+):(\d+): (.+)$' + let l:output = [] + let l:type = 'W' + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + if bufname(a:buffer) == l:match[1] + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': l:match[2] + 0, + \ 'col': 0, + \ 'type': l:type, + \ 'text': l:match[3], + \}) + endif + endfor + + return l:output +endfunction + +function! ale_linters#elixir#dialyxir#GetCommand(buffer) abort + let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) + + return ale#path#CdString(l:project_root) + \ . ' mix help dialyzer && mix dialyzer' +endfunction + +call ale#linter#Define('elixir', { +\ 'name': 'dialyxir', +\ 'executable': 'mix', +\ 'command': function('ale_linters#elixir#dialyxir#GetCommand'), +\ 'callback': 'ale_linters#elixir#dialyxir#Handle', +\}) + diff --git a/pack/acp/start/ale/ale_linters/elixir/dogma.vim b/pack/acp/start/ale/ale_linters/elixir/dogma.vim new file mode 100644 index 0000000..1c72115 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/elixir/dogma.vim @@ -0,0 +1,45 @@ +" 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 + +function! ale_linters#elixir#dogma#GetCommand(buffer) abort + let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) + + return ale#path#CdString(l:project_root) + \ . ' mix help dogma && mix dogma %s --format=flycheck' +endfunction + +call ale#linter#Define('elixir', { +\ 'name': 'dogma', +\ 'executable': 'mix', +\ 'command': function('ale_linters#elixir#dogma#GetCommand'), +\ 'lint_file': 1, +\ 'callback': 'ale_linters#elixir#dogma#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/elixir/elixir_ls.vim b/pack/acp/start/ale/ale_linters/elixir/elixir_ls.vim new file mode 100644 index 0000000..d5517de --- /dev/null +++ b/pack/acp/start/ale/ale_linters/elixir/elixir_ls.vim @@ -0,0 +1,21 @@ +" Author: Jon Parise +" Description: ElixirLS integration (https://github.com/JakeBecker/elixir-ls) + +call ale#Set('elixir_elixir_ls_release', 'elixir-ls') +call ale#Set('elixir_elixir_ls_config', {}) + +function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort + let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_elixir_ls_release')) + let l:cmd = has('win32') ? '\language_server.bat' : '/language_server.sh' + + return l:dir . l:cmd +endfunction + +call ale#linter#Define('elixir', { +\ 'name': 'elixir-ls', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#elixir#elixir_ls#GetExecutable'), +\ 'command': function('ale_linters#elixir#elixir_ls#GetExecutable'), +\ 'project_root': function('ale#handlers#elixir#FindMixUmbrellaRoot'), +\ 'lsp_config': {b -> ale#Var(b, 'elixir_elixir_ls_config')}, +\}) diff --git a/pack/acp/start/ale/ale_linters/elixir/mix.vim b/pack/acp/start/ale/ale_linters/elixir/mix.vim new file mode 100644 index 0000000..abf5d0a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/elixir/mix.vim @@ -0,0 +1,52 @@ +" Author: evnu - https://github.com/evnu +" Author: colbydehart - https://github.com/colbydehart +" Description: Mix compile checking for Elixir files + +function! ale_linters#elixir#mix#Handle(buffer, lines) abort + " Matches patterns like the following: + " + " Error format + " ** (CompileError) apps/sim/lib/sim/server.ex:87: undefined function update_in/4 + " + " TODO: Warning format + " warning: variable "foobar" does not exist and is being expanded to "foobar()", please use parentheses to remove the ambiguity or change the variable name + let l:pattern = '\v\(([^\)]+Error)\) ([^:]+):([^:]+): (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:type = 'E' + let l:text = l:match[4] + + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': l:match[3] + 0, + \ 'col': 0, + \ 'type': l:type, + \ 'text': l:text, + \}) + endfor + + return l:output +endfunction + +function! ale_linters#elixir#mix#GetCommand(buffer) abort + let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) + + let l:temp_dir = ale#command#CreateDirectory(a:buffer) + + let l:mix_build_path = has('win32') + \ ? 'set MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) . ' &&' + \ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) + + return ale#path#CdString(l:project_root) + \ . l:mix_build_path + \ . ' mix compile %s' +endfunction + +call ale#linter#Define('elixir', { +\ 'name': 'mix', +\ 'executable': 'mix', +\ 'command': function('ale_linters#elixir#mix#GetCommand'), +\ 'callback': 'ale_linters#elixir#mix#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/elm/elm_lsp.vim b/pack/acp/start/ale/ale_linters/elm/elm_lsp.vim new file mode 100644 index 0000000..2259286 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/elm/elm_lsp.vim @@ -0,0 +1,22 @@ +" Author: antew - https://github.com/antew +" Description: LSP integration for elm, currently supports diagnostics (linting) + +call ale#Set('elm_lsp_executable', 'elm-lsp') +call ale#Set('elm_lsp_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! elm_lsp#GetRootDir(buffer) abort + let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json') + + return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : '' +endfunction + +call ale#linter#Define('elm', { +\ 'name': 'elm_lsp', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#node#FindExecutable(b, 'elm_lsp', [ +\ 'node_modules/.bin/elm-lsp', +\ ])}, +\ 'command': '%e --stdio', +\ 'project_root': function('elm_lsp#GetRootDir'), +\ 'language': 'elm' +\}) diff --git a/pack/acp/start/ale/ale_linters/elm/make.vim b/pack/acp/start/ale/ale_linters/elm/make.vim new file mode 100644 index 0000000..6b93257 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/elm/make.vim @@ -0,0 +1,240 @@ +" Author: buffalocoder - https://github.com/buffalocoder, soywod - https://github.com/soywod, hecrj - https://github.com/hecrj +" Description: Elm linting in Ale. Closely follows the Syntastic checker in https://github.com/ElmCast/elm-vim. + +call ale#Set('elm_make_executable', 'elm') +call ale#Set('elm_make_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#elm#make#Handle(buffer, lines) abort + let l:output = [] + let l:unparsed_lines = [] + + for l:line in a:lines + if l:line[0] is# '{' + " Elm 0.19 + call ale_linters#elm#make#HandleElm019Line(l:line, l:output) + elseif l:line[0] is# '[' + " Elm 0.18 + call ale_linters#elm#make#HandleElm018Line(l:line, l:output) + 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 + +function! ale_linters#elm#make#HandleElm019Line(line, output) abort + let l:report = json_decode(a:line) + + if l:report.type is? 'error' + " General problem + let l:details = ale_linters#elm#make#ParseMessage(l:report.message) + + if empty(l:report.path) + let l:report.path = 'Elm' + endif + + if ale_linters#elm#make#FileIsBuffer(l:report.path) + call add(a:output, { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': l:details, + \}) + else + call add(a:output, { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': l:report.path .' - '. l:details, + \ 'detail': l:report.path ." ----------\n\n". l:details, + \}) + endif + else + " Compilation errors + for l:error in l:report.errors + let l:file_is_buffer = ale_linters#elm#make#FileIsBuffer(l:error.path) + + for l:problem in l:error.problems + let l:details = ale_linters#elm#make#ParseMessage(l:problem.message) + + if l:file_is_buffer + " Buffer module has problems + call add(a:output, { + \ 'lnum': l:problem.region.start.line, + \ 'col': l:problem.region.start.column, + \ 'end_lnum': l:problem.region.end.line, + \ 'end_col': l:problem.region.end.column, + \ 'type': 'E', + \ 'text': l:details, + \}) + else + " Imported module has problems + let l:location = l:error.path .':'. l:problem.region.start.line + call add(a:output, { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': l:location .' - '. l:details, + \ 'detail': l:location ." ----------\n\n". l:details, + \}) + endif + endfor + endfor + endif +endfunction + +function! ale_linters#elm#make#HandleElm018Line(line, output) abort + let l:errors = json_decode(a:line) + + for l:error in l:errors + let l:file_is_buffer = ale_linters#elm#make#FileIsBuffer(l:error.file) + + if l:file_is_buffer + " Current buffer has problems + call add(a:output, { + \ 'lnum': l:error.region.start.line, + \ 'col': l:error.region.start.column, + \ 'end_lnum': l:error.region.end.line, + \ 'end_col': l:error.region.end.column, + \ 'type': (l:error.type is? 'error') ? 'E' : 'W', + \ 'text': l:error.overview, + \ 'detail': l:error.overview . "\n\n" . l:error.details + \}) + elseif l:error.type is? 'error' + " Imported module has errors + let l:location = l:error.file .':'. l:error.region.start.line + + call add(a:output, { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': l:location .' - '. l:error.overview, + \ 'detail': l:location ." ----------\n\n". l:error.overview . "\n\n" . l:error.details + \}) + endif + endfor +endfunction + +function! ale_linters#elm#make#FileIsBuffer(path) abort + return ale#path#IsTempName(a:path) +endfunction + +function! ale_linters#elm#make#ParseMessage(message) abort + return join(map(copy(a:message), 'ale_linters#elm#make#ParseMessageItem(v:val)'), '') +endfunction + +function! ale_linters#elm#make#ParseMessageItem(item) abort + if type(a:item) is v:t_string + return a:item + else + return a:item.string + endif +endfunction + +function! ale_linters#elm#make#GetPackageFile(buffer) abort + let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json') + + if empty(l:elm_json) + " Fallback to Elm 0.18 + let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm-package.json') + endif + + return l:elm_json +endfunction + +function! ale_linters#elm#make#IsVersionGte19(buffer) abort + let l:elm_json = ale_linters#elm#make#GetPackageFile(a:buffer) + + if l:elm_json =~# '-package' + return 0 + else + return 1 + endif +endfunction + +function! ale_linters#elm#make#GetRootDir(buffer) abort + let l:elm_json = ale_linters#elm#make#GetPackageFile(a:buffer) + + if empty(l:elm_json) + return '' + else + return fnamemodify(l:elm_json, ':p:h') + endif +endfunction + +function! ale_linters#elm#make#IsTest(buffer) abort + let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer) + + if empty(l:root_dir) + return 0 + endif + + let l:tests_dir = join([l:root_dir, 'tests', ''], has('win32') ? '\' : '/') + + let l:buffer_path = fnamemodify(bufname(a:buffer), ':p') + + if stridx(l:buffer_path, l:tests_dir) == 0 + return 1 + else + return 0 + endif +endfunction + +" Return the command to execute the linter in the projects directory. +" If it doesn't, then this will fail when imports are needed. +function! ale_linters#elm#make#GetCommand(buffer) abort + let l:executable = ale_linters#elm#make#GetExecutable(a:buffer) + let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer) + let l:is_v19 = ale_linters#elm#make#IsVersionGte19(a:buffer) + let l:is_using_elm_test = l:executable =~# 'elm-test$' + + if empty(l:root_dir) + let l:dir_set_cmd = '' + else + let l:dir_set_cmd = 'cd ' . ale#Escape(l:root_dir) . ' && ' + endif + + " elm-test needs to know the path of elm-make if elm isn't installed globally. + " https://github.com/rtfeldman/node-test-runner/blob/57728f10668f2d2ab3179e7e3208bcfa9a1f19aa/README.md#--compiler + if l:is_v19 && l:is_using_elm_test + let l:elm_make_executable = ale#node#FindExecutable(a:buffer, 'elm_make', ['node_modules/.bin/elm']) + let l:elm_test_compiler_flag = ' --compiler ' . l:elm_make_executable . ' ' + else + let l:elm_test_compiler_flag = ' ' + endif + + " The elm compiler, at the time of this writing, uses '/dev/null' as + " a sort of flag to tell the compiler not to generate an output file, + " which is why this is hard coded here. + " Source: https://github.com/elm-lang/elm-compiler/blob/19d5a769b30ec0b2fc4475985abb4cd94cd1d6c3/builder/src/Generate/Output.hs#L253 + return l:dir_set_cmd . '%e make --report=json --output=/dev/null' . l:elm_test_compiler_flag . '%t' +endfunction + +function! ale_linters#elm#make#GetExecutable(buffer) abort + let l:is_test = ale_linters#elm#make#IsTest(a:buffer) + let l:is_v19 = ale_linters#elm#make#IsVersionGte19(a:buffer) + + if l:is_test && l:is_v19 + return ale#node#FindExecutable( + \ a:buffer, + \ 'elm_make', + \ ['node_modules/.bin/elm-test', 'node_modules/.bin/elm'] + \) + else + return ale#node#FindExecutable(a:buffer, 'elm_make', ['node_modules/.bin/elm']) + endif +endfunction + +call ale#linter#Define('elm', { +\ 'name': 'make', +\ 'executable': function('ale_linters#elm#make#GetExecutable'), +\ 'output_stream': 'both', +\ 'command': function('ale_linters#elm#make#GetCommand'), +\ 'callback': 'ale_linters#elm#make#Handle' +\}) diff --git a/pack/acp/start/ale/ale_linters/erlang/dialyzer.vim b/pack/acp/start/ale/ale_linters/erlang/dialyzer.vim new file mode 100644 index 0000000..7af64c4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/erlang/dialyzer.vim @@ -0,0 +1,93 @@ +" Author: Autoine Gagne - https://github.com/AntoineGagne +" Description: Define a checker that runs dialyzer on Erlang files. + +let g:ale_erlang_dialyzer_executable = +\ get(g:, 'ale_erlang_dialyzer_executable', 'dialyzer') +let g:ale_erlang_dialyzer_plt_file = +\ get(g:, 'ale_erlang_dialyzer_plt_file', '') +let g:ale_erlang_dialyzer_rebar3_profile = +\ get(g:, 'ale_erlang_dialyzer_rebar3_profile', 'default') + +function! ale_linters#erlang#dialyzer#GetRebar3Profile(buffer) abort + return ale#Var(a:buffer, 'erlang_dialyzer_rebar3_profile') +endfunction + +function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort + let l:plt_file = '' + let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer) + let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile) + + if !empty(l:plt_file_directory) + let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n') + endif + + if !empty(l:plt_file) + return l:plt_file[0] + endif + + if !empty($REBAR_PLT_DIR) + return expand('$REBAR_PLT_DIR/dialyzer/plt') + endif + + return expand('$HOME/.dialyzer_plt') +endfunction + +function! ale_linters#erlang#dialyzer#GetPlt(buffer) abort + let l:plt_file = ale#Var(a:buffer, 'erlang_dialyzer_plt_file') + + if !empty(l:plt_file) + return l:plt_file + endif + + return ale_linters#erlang#dialyzer#FindPlt(a:buffer) +endfunction + +function! ale_linters#erlang#dialyzer#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'erlang_dialyzer_executable') +endfunction + +function! ale_linters#erlang#dialyzer#GetCommand(buffer) abort + let l:command = ale#Escape(ale_linters#erlang#dialyzer#GetExecutable(a:buffer)) + \ . ' -n' + \ . ' --plt ' . ale#Escape(ale_linters#erlang#dialyzer#GetPlt(a:buffer)) + \ . ' -Wunmatched_returns' + \ . ' -Werror_handling' + \ . ' -Wrace_conditions' + \ . ' -Wunderspecs' + \ . ' %s' + + return l:command +endfunction + +function! ale_linters#erlang#dialyzer#Handle(buffer, lines) abort + " Match patterns like the following: + " + " erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available + let l:pattern = '^\S\+:\(\d\+\): \(.\+\)$' + let l:output = [] + + for l:line in a:lines + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) != 0 + let l:code = l:match[2] + + call add(l:output, { + \ 'lnum': str2nr(l:match[1]), + \ 'lcol': 0, + \ 'text': l:code, + \ 'type': 'W' + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('erlang', { +\ 'name': 'dialyzer', +\ 'executable': function('ale_linters#erlang#dialyzer#GetExecutable'), +\ 'command': function('ale_linters#erlang#dialyzer#GetCommand'), +\ 'callback': function('ale_linters#erlang#dialyzer#Handle'), +\ 'lint_file': 1 +\}) diff --git a/pack/acp/start/ale/ale_linters/erlang/erlc.vim b/pack/acp/start/ale/ale_linters/erlang/erlc.vim new file mode 100644 index 0000000..a83bacc --- /dev/null +++ b/pack/acp/start/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 = ale#util#Tempname() + call ale#command#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^([a-zA-Z]?:?[^:]+):(\d+): (Warning: )?(.+)$' + + " parse_transforms are a special case. The error message does not indicate a location: + " error.erl: undefined parse transform 'some_parse_transform' + 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': function('ale_linters#erlang#erlc#GetCommand'), +\ 'callback': 'ale_linters#erlang#erlc#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/erlang/syntaxerl.vim b/pack/acp/start/ale/ale_linters/erlang/syntaxerl.vim new file mode 100644 index 0000000..5d555a8 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/erlang/syntaxerl.vim @@ -0,0 +1,42 @@ +" Author: Dmitri Vereshchagin +" Description: SyntaxErl linter for Erlang files + +call ale#Set('erlang_syntaxerl_executable', 'syntaxerl') + +function! ale_linters#erlang#syntaxerl#RunHelpCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'erlang_syntaxerl_executable') + + return ale#command#Run( + \ a:buffer, + \ ale#Escape(l:executable) . ' -h', + \ function('ale_linters#erlang#syntaxerl#GetCommand'), + \) +endfunction + +function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output, meta) abort + let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1 + + return '%e' . (l:use_b_option ? ' -b %s %t' : ' %t') +endfunction + +function! ale_linters#erlang#syntaxerl#Handle(buffer, lines) abort + let l:pattern = '\v\C:(\d+):( warning:)? (.+)' + let l:loclist = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:loclist, { + \ 'lnum': l:match[1] + 0, + \ 'text': l:match[3], + \ 'type': empty(l:match[2]) ? 'E' : 'W', + \}) + endfor + + return l:loclist +endfunction + +call ale#linter#Define('erlang', { +\ 'name': 'syntaxerl', +\ 'executable': {b -> ale#Var(b, 'erlang_syntaxerl_executable')}, +\ 'command': {b -> ale_linters#erlang#syntaxerl#RunHelpCommand(b)}, +\ 'callback': 'ale_linters#erlang#syntaxerl#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/eruby/erb.vim b/pack/acp/start/ale/ale_linters/eruby/erb.vim new file mode 100644 index 0000000..f343832 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/eruby/erb.vim @@ -0,0 +1,25 @@ +" Author: Matthias Guenther - https://wikimatze.de, Eddie Lebow https://github.com/elebow +" Description: ERB from the Ruby standard library, for eruby/erb files + +function! ale_linters#eruby#erb#GetCommand(buffer) abort + let l:rails_root = ale#ruby#FindRailsRoot(a:buffer) + + if empty(l:rails_root) + return 'erb -P -T - -x %t | ruby -c' + endif + + " Rails-flavored eRuby does not comply with the standard as understood by + " ERB, so we'll have to do some substitution. This does not reduce the + " effectiveness of the linter—the translated code is still evaluated. + return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c' +endfunction + +call ale#linter#Define('eruby', { +\ 'name': 'erb', +\ 'aliases': ['erubylint'], +\ 'executable': 'erb', +\ 'output_stream': 'stderr', +\ 'command': function('ale_linters#eruby#erb#GetCommand'), +\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', +\}) + diff --git a/pack/acp/start/ale/ale_linters/eruby/erubi.vim b/pack/acp/start/ale/ale_linters/eruby/erubi.vim new file mode 100644 index 0000000..ddca3f6 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/eruby/erubi.vim @@ -0,0 +1,32 @@ +" Author: Eddie Lebow https://github.com/elebow +" Description: eruby checker using `erubi` + +function! ale_linters#eruby#erubi#GetCommand(buffer, output, meta) abort + let l:rails_root = ale#ruby#FindRailsRoot(a:buffer) + + if !empty(a:output) + " The empty command in CheckErubi returns nothing if erubi runs and + " emits an error if erubi is not present + return '' + endif + + if empty(l:rails_root) + return 'ruby -r erubi/capture_end -e ' . ale#Escape('puts Erubi::CaptureEndEngine.new($stdin.read).src') . '< %t | ruby -c' + endif + + " Rails-flavored eRuby does not comply with the standard as understood by + " Erubi, so we'll have to do some substitution. This does not reduce the + " effectiveness of the linter---the translated code is still evaluated. + return 'ruby -r erubi/capture_end -e ' . ale#Escape('puts Erubi::CaptureEndEngine.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c' +endfunction + +call ale#linter#Define('eruby', { +\ 'name': 'erubi', +\ 'executable': 'ruby', +\ 'command': {buffer -> ale#command#Run( +\ buffer, +\ 'ruby -r erubi/capture_end -e ' . ale#Escape('""'), +\ function('ale_linters#eruby#erubi#GetCommand'), +\ )}, +\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', +\}) diff --git a/pack/acp/start/ale/ale_linters/eruby/erubis.vim b/pack/acp/start/ale/ale_linters/eruby/erubis.vim new file mode 100644 index 0000000..755c580 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/eruby/erubis.vim @@ -0,0 +1,23 @@ +" Author: Jake Zimmerman , Eddie Lebow https://github.com/elebow +" Description: eruby checker using `erubis`, instead of `erb` + +function! ale_linters#eruby#erubis#GetCommand(buffer) abort + let l:rails_root = ale#ruby#FindRailsRoot(a:buffer) + + if empty(l:rails_root) + return 'erubis -x %t | ruby -c' + endif + + " Rails-flavored eRuby does not comply with the standard as understood by + " Erubis, so we'll have to do some substitution. This does not reduce the + " effectiveness of the linter - the translated code is still evaluated. + return 'ruby -r erubis -e ' . ale#Escape('puts Erubis::Eruby.new($stdin.read.gsub(%{<%=},%{<%})).src') . '< %t | ruby -c' +endfunction + +call ale#linter#Define('eruby', { +\ 'name': 'erubis', +\ 'executable': 'erubis', +\ 'output_stream': 'stderr', +\ 'command': function('ale_linters#eruby#erubis#GetCommand'), +\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', +\}) diff --git a/pack/acp/start/ale/ale_linters/eruby/ruumba.vim b/pack/acp/start/ale/ale_linters/eruby/ruumba.vim new file mode 100644 index 0000000..e68bb51 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/eruby/ruumba.vim @@ -0,0 +1,62 @@ +" Author: aclemons - https://github.com/aclemons +" based on the ale rubocop linter +" Description: Ruumba, RuboCop linting for ERB templates. + +call ale#Set('eruby_ruumba_executable', 'ruumba') +call ale#Set('eruby_ruumba_options', '') + +function! ale_linters#eruby#ruumba#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'eruby_ruumba_executable') + + return ale#handlers#ruby#EscapeExecutable(l:executable, 'ruumba') + \ . ' --format json --force-exclusion ' + \ . ale#Var(a:buffer, 'eruby_ruumba_options') + \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) +endfunction + +function! ale_linters#eruby#ruumba#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, + \ 'code': l:error['cop_name'], + \ 'text': l:error['message'], + \ 'type': ale_linters#eruby#ruumba#GetType(l:error['severity']), + \}) + endfor + + return l:output +endfunction + +function! ale_linters#eruby#ruumba#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('eruby', { +\ 'name': 'ruumba', +\ 'executable': {b -> ale#Var(b, 'eruby_ruumba_executable')}, +\ 'command': function('ale_linters#eruby#ruumba#GetCommand'), +\ 'callback': 'ale_linters#eruby#ruumba#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/fish/fish.vim b/pack/acp/start/ale/ale_linters/fish/fish.vim new file mode 100644 index 0000000..87ede29 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/fish/fish.vim @@ -0,0 +1,67 @@ +" Author: Niraj Thapaliya - https://github.com/nthapaliya +" Description: Lints fish files using fish -n + +function! ale_linters#fish#fish#Handle(buffer, lines) abort + " Matches patterns such as: + " + " home/.config/fish/functions/foo.fish (line 1): Missing end to balance this function definition + " function foo + " ^ + " + " OR, patterns such as: + " + " Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'. + " /tmp/vLz620o/258/test.fish (line 2): if set -q SSH_CLIENT || set -q SSH_TTY + " ^ + " + " fish -n can return errors in either format. + let l:pattern = '^\(.* (line \(\d\+\)): \)\(.*\)$' + let l:column_pattern = '^ *\^' + let l:output = [] + let l:column_offset = 0 + let l:last_line_with_message = '' + + for l:line in a:lines + " Look for error lines first. + let l:match = matchlist(l:line, l:pattern) + + if !empty(l:match) + if !empty(l:last_line_with_message) + let l:text = l:last_line_with_message + else + let l:text = l:match[3] + endif + + let l:column_offset = len(l:match[1]) + + let l:last_line_with_message = '' + call add(l:output, { + \ 'col': 0, + \ 'lnum': str2nr(l:match[2]), + \ 'text': l:text, + \}) + else + " Look for column markers like ' ^' second. + " The column index will be set according to how long the line is. + let l:column_match = matchstr(l:line, l:column_pattern) + + if !empty(l:column_match) && !empty(l:output) + let l:output[-1].col = len(l:column_match) - l:column_offset + let l:last_line_with_message = '' + else + let l:last_line_with_message = l:line + let l:column_offset = 0 + endif + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('fish', { +\ 'name': 'fish', +\ 'output_stream': 'stderr', +\ 'executable': 'fish', +\ 'command': 'fish -n %t', +\ 'callback': 'ale_linters#fish#fish#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/fortran/gcc.vim b/pack/acp/start/ale/ale_linters/fortran/gcc.vim new file mode 100644 index 0000000..6e97d6f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/fortran/gcc.vim @@ -0,0 +1,72 @@ +" Author: w0rp +" Description: gcc for Fortran files + +" This option can be set to 0 to use -ffixed-form +call ale#Set('fortran_gcc_use_free_form', 1) +call ale#Set('fortran_gcc_executable', 'gcc') +" Set this option to change the GCC options for warnings for Fortran. +call ale#Set('fortran_gcc_options', '-Wall') + +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#GetCommand(buffer) abort + let l:layout_option = ale#Var(a:buffer, 'fortran_gcc_use_free_form') + \ ? '-ffree-form' + \ : '-ffixed-form' + + return '%e -S -x f95 -fsyntax-only ' . l:layout_option + \ . ale#Pad(ale#Var(a:buffer, 'fortran_gcc_options')) + \ . ' -' +endfunction + +call ale#linter#Define('fortran', { +\ 'name': 'gcc', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'fortran_gcc_executable')}, +\ 'command': function('ale_linters#fortran#gcc#GetCommand'), +\ 'callback': 'ale_linters#fortran#gcc#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/fortran/language_server.vim b/pack/acp/start/ale/ale_linters/fortran/language_server.vim new file mode 100644 index 0000000..00aa057 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/fortran/language_server.vim @@ -0,0 +1,19 @@ +" Author: unpairedbracket ben.spiers22@gmail.com +" Description: A language server for fortran + +call ale#Set('fortran_language_server_executable', 'fortls') +call ale#Set('fortran_language_server_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#fortran#language_server#GetProjectRoot(buffer) abort + let l:fortls_file = ale#path#FindNearestFile(a:buffer, '.fortls') + + return !empty(l:fortls_file) ? fnamemodify(l:fortls_file, ':h') : '' +endfunction + +call ale#linter#Define('fortran', { +\ 'name': 'language_server', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'fortran_language_server_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#fortran#language_server#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/fountain/proselint.vim b/pack/acp/start/ale/ale_linters/fountain/proselint.vim new file mode 100644 index 0000000..353a2e5 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/fountain/proselint.vim @@ -0,0 +1,9 @@ +" Author: Jansen Mitchell https://github.com/JansenMitchell +" Description: proselint for Fountain files + +call ale#linter#Define('fountain', { +\ 'name': 'proselint', +\ 'executable': 'proselint', +\ 'command': 'proselint %t', +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/pack/acp/start/ale/ale_linters/fuse/fusionlint.vim b/pack/acp/start/ale/ale_linters/fuse/fusionlint.vim new file mode 100644 index 0000000..ffb25d3 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/fuse/fusionlint.vim @@ -0,0 +1,33 @@ +" Author: RyanSquared +" Description: `fusion-lint` linter for FusionScript files + +call ale#Set('fuse_fusionlint_executable', 'fusion-lint') +call ale#Set('fuse_fusionlint_options', '') + +function! ale_linters#fuse#fusionlint#GetCommand(buffer) abort + return '%e' . ale#Pad(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': {b -> ale#Var(b, 'fuse_fusionlint_executable')}, +\ 'command': function('ale_linters#fuse#fusionlint#GetCommand'), +\ 'callback': 'ale_linters#fuse#fusionlint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/gitcommit/gitlint.vim b/pack/acp/start/ale/ale_linters/gitcommit/gitlint.vim new file mode 100644 index 0000000..4b9cec6 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/gitcommit/gitlint.vim @@ -0,0 +1,51 @@ +" Author: Nick Yamane +" Description: gitlint for git commit message files + +call ale#Set('gitcommit_gitlint_executable', 'gitlint') +call ale#Set('gitcommit_gitlint_options', '') +call ale#Set('gitcommit_gitlint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#gitcommit#gitlint#GetExecutable(buffer) abort + return ale#python#FindExecutable(a:buffer, 'gitcommit_gitlint', ['gitlint']) +endfunction + +function! ale_linters#gitcommit#gitlint#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'gitcommit_gitlint_options') + + return '%e' . ale#Pad(l:options) . ' lint' +endfunction + +function! ale_linters#gitcommit#gitlint#Handle(buffer, lines) abort + " Matches patterns line the following: + let l:pattern = '\v^(\d+): (\w+) (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:code = l:match[2] + + if !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + if l:code is# 'T2' || l:code is# 'B2' + continue + endif + endif + + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'text': l:match[3], + \ 'code': l:code, + \ 'type': 'E', + \} + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('gitcommit', { +\ 'name': 'gitlint', +\ 'output_stream': 'stderr', +\ 'executable': function('ale_linters#gitcommit#gitlint#GetExecutable'), +\ 'command': function('ale_linters#gitcommit#gitlint#GetCommand'), +\ 'callback': 'ale_linters#gitcommit#gitlint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/glsl/glslang.vim b/pack/acp/start/ale/ale_linters/glsl/glslang.vim new file mode 100644 index 0000000..bbddce9 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/glsl/glslang.vim @@ -0,0 +1,40 @@ +" Author: Sven-Hendrik Haase +" Description: glslang-based linter for glsl files +" +" TODO: Once https://github.com/KhronosGroup/glslang/pull/1047 is accepted, +" we can use stdin. + +call ale#Set('glsl_glslang_executable', 'glslangValidator') +call ale#Set('glsl_glslang_options', '') + +function! ale_linters#glsl#glslang#GetCommand(buffer) abort + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'glsl_glslang_options')) + \ . ' -C %t' +endfunction + +function! ale_linters#glsl#glslang#Handle(buffer, lines) abort + " Matches patterns like the following: + " + " ERROR: 0:5: 'foo' : undeclared identifier + let l:pattern = '^\(.\+\): \(\d\+\):\(\d\+\): \(.\+\)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': str2nr(l:match[3]), + \ 'col': str2nr(l:match[2]), + \ 'text': l:match[4], + \ 'type': l:match[1] is# 'ERROR' ? 'E' : 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('glsl', { +\ 'name': 'glslang', +\ 'executable': {b -> ale#Var(b, 'glsl_glslang_executable')}, +\ 'command': function('ale_linters#glsl#glslang#GetCommand'), +\ 'callback': 'ale_linters#glsl#glslang#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/glsl/glslls.vim b/pack/acp/start/ale/ale_linters/glsl/glslls.vim new file mode 100644 index 0000000..b62844c --- /dev/null +++ b/pack/acp/start/ale/ale_linters/glsl/glslls.vim @@ -0,0 +1,30 @@ +" Author: Sven-Hendrik Haase +" Description: A language server for glsl + +call ale#Set('glsl_glslls_executable', 'glslls') +call ale#Set('glsl_glslls_logfile', '') + +function! ale_linters#glsl#glslls#GetCommand(buffer) abort + let l:logfile = ale#Var(a:buffer, 'glsl_glslls_logfile') + let l:logfile_args = '' + + if l:logfile isnot# '' + let l:logfile_args = ' --verbose -l ' . l:logfile + endif + + return '%e' . l:logfile_args . ' --stdin' +endfunction + +function! ale_linters#glsl#glslls#GetProjectRoot(buffer) abort + let l:project_root = ale#c#FindProjectRoot(a:buffer) + + return !empty(l:project_root) ? fnamemodify(l:project_root, ':h:h') : '' +endfunction + +call ale#linter#Define('glsl', { +\ 'name': 'glslls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'glsl_glslls_executable')}, +\ 'command': function('ale_linters#glsl#glslls#GetCommand'), +\ 'project_root': function('ale_linters#glsl#glslls#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/go/bingo.vim b/pack/acp/start/ale/ale_linters/go/bingo.vim new file mode 100644 index 0000000..e446bdc --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/bingo.vim @@ -0,0 +1,29 @@ +" Author: Jerko Steiner +" Description: https://github.com/saibing/bingo + +call ale#Set('go_bingo_executable', 'bingo') +call ale#Set('go_bingo_options', '--mode stdio') + +function! ale_linters#go#bingo#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options')) +endfunction + +function! ale_linters#go#bingo#FindProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod') + let l:mods = ':h' + + if empty(l:project_root) + let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git') + let l:mods = ':h:h' + endif + + return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : '' +endfunction + +call ale#linter#Define('go', { +\ 'name': 'bingo', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'go_bingo_executable')}, +\ 'command': function('ale_linters#go#bingo#GetCommand'), +\ 'project_root': function('ale_linters#go#bingo#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/go/gobuild.vim b/pack/acp/start/ale/ale_linters/go/gobuild.vim new file mode 100644 index 0000000..374ded3 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/gobuild.vim @@ -0,0 +1,56 @@ +" Author: Joshua Rubin , Ben Reedy , +" Jeff Willette +" Description: go build for Go files +" inspired by work from dzhou121 + +call ale#Set('go_go_executable', 'go') +call ale#Set('go_gobuild_options', '') + +function! ale_linters#go#gobuild#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'go_gobuild_options') + + " Run go test in local directory with relative path + return ale#path#BufferCdString(a:buffer) + \ . ale#Var(a:buffer, 'go_go_executable') . ' test' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -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:dir = expand('#' . a:buffer . ':p:h') + let l:output = [] + + for l:match in ale_linters#go#gobuild#GetMatches(a:lines) + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[4], + \ 'type': 'E', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('go', { +\ 'name': 'gobuild', +\ 'aliases': ['go build'], +\ 'executable': {b -> ale#Var(b, 'go_go_executable')}, +\ 'command': function('ale_linters#go#gobuild#GetCommand'), +\ 'output_stream': 'stderr', +\ 'callback': 'ale_linters#go#gobuild#Handler', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/go/gofmt.vim b/pack/acp/start/ale/ale_linters/go/gofmt.vim new file mode 100644 index 0000000..337deef --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/go/golangci_lint.vim b/pack/acp/start/ale/ale_linters/go/golangci_lint.vim new file mode 100644 index 0000000..357f794 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/golangci_lint.vim @@ -0,0 +1,56 @@ +" Author: Sascha Grunert +" Description: Adds support of golangci-lint + +call ale#Set('go_golangci_lint_options', '--enable-all') +call ale#Set('go_golangci_lint_executable', 'golangci-lint') +call ale#Set('go_golangci_lint_package', 0) + +function! ale_linters#go#golangci_lint#GetCommand(buffer) abort + let l:filename = expand('#' . a:buffer . ':t') + let l:options = ale#Var(a:buffer, 'go_golangci_lint_options') + let l:lint_package = ale#Var(a:buffer, 'go_golangci_lint_package') + + if l:lint_package + return ale#path#BufferCdString(a:buffer) + \ . '%e run ' + \ . l:options + endif + + return ale#path#BufferCdString(a:buffer) + \ . '%e run ' + \ . ale#Escape(l:filename) + \ . ' ' . l:options +endfunction + +function! ale_linters#go#golangci_lint#GetMatches(lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:?:?:?\s\*?(.+)$' + + return ale#util#GetMatches(a:lines, l:pattern) +endfunction + +function! ale_linters#go#golangci_lint#Handler(buffer, lines) abort + let l:dir = expand('#' . a:buffer . ':p:h') + let l:output = [] + + for l:match in ale_linters#go#golangci_lint#GetMatches(a:lines) + " l:match[1] will already be an absolute path, output from + " golangci_lint + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'type': 'E', + \ 'text': l:match[4], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('go', { +\ 'name': 'golangci-lint', +\ 'executable': {b -> ale#Var(b, 'go_golangci_lint_executable')}, +\ 'command': function('ale_linters#go#golangci_lint#GetCommand'), +\ 'callback': 'ale_linters#go#golangci_lint#Handler', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/go/golint.vim b/pack/acp/start/ale/ale_linters/go/golint.vim new file mode 100644 index 0000000..765e147 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/golint.vim @@ -0,0 +1,21 @@ +" Author: neersighted +" Description: golint for Go files + +call ale#Set('go_golint_executable', 'golint') +call ale#Set('go_golint_options', '') + +function! ale_linters#go#golint#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'go_golint_options') + + return '%e' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' %t' +endfunction + +call ale#linter#Define('go', { +\ 'name': 'golint', +\ 'output_stream': 'both', +\ 'executable': {b -> ale#Var(b, 'go_golint_executable')}, +\ 'command': function('ale_linters#go#golint#GetCommand'), +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/pack/acp/start/ale/ale_linters/go/gometalinter.vim b/pack/acp/start/ale/ale_linters/go/gometalinter.vim new file mode 100644 index 0000000..19d70a8 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/gometalinter.vim @@ -0,0 +1,57 @@ +" Author: Ben Reedy , Jeff Willette +" Description: Adds support for the gometalinter suite for Go files + +call ale#Set('go_gometalinter_options', '') +call ale#Set('go_gometalinter_executable', 'gometalinter') +call ale#Set('go_gometalinter_lint_package', 0) + +function! ale_linters#go#gometalinter#GetCommand(buffer) abort + let l:filename = expand('#' . a:buffer . ':t') + let l:options = ale#Var(a:buffer, 'go_gometalinter_options') + let l:lint_package = ale#Var(a:buffer, 'go_gometalinter_lint_package') + + " BufferCdString is used so that we can be sure the paths output from gometalinter can + " be calculated to absolute paths in the Handler + if l:lint_package + return ale#path#BufferCdString(a:buffer) + \ . '%e' + \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' + endif + + return ale#path#BufferCdString(a:buffer) + \ . '%e' + \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename)) + \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' +endfunction + +function! ale_linters#go#gometalinter#GetMatches(lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:?:?(warning|error):?\s\*?(.+)$' + + return ale#util#GetMatches(a:lines, l:pattern) +endfunction + +function! ale_linters#go#gometalinter#Handler(buffer, lines) abort + let l:dir = expand('#' . a:buffer . ':p:h') + let l:output = [] + + for l:match in ale_linters#go#gometalinter#GetMatches(a:lines) + " l:match[1] will already be an absolute path, output from gometalinter + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'type': tolower(l:match[4]) is# 'warning' ? 'W' : 'E', + \ 'text': l:match[5], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('go', { +\ 'name': 'gometalinter', +\ 'executable': {b -> ale#Var(b, 'go_gometalinter_executable')}, +\ 'command': function('ale_linters#go#gometalinter#GetCommand'), +\ 'callback': 'ale_linters#go#gometalinter#Handler', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/go/gopls.vim b/pack/acp/start/ale/ale_linters/go/gopls.vim new file mode 100644 index 0000000..c411dc2 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/gopls.vim @@ -0,0 +1,30 @@ +" Author: w0rp +" Author: Jerko Steiner +" Description: https://github.com/saibing/gopls + +call ale#Set('go_gopls_executable', 'gopls') +call ale#Set('go_gopls_options', '--mode stdio') + +function! ale_linters#go#gopls#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'go_gopls_options')) +endfunction + +function! ale_linters#go#gopls#FindProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod') + let l:mods = ':h' + + if empty(l:project_root) + let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git') + let l:mods = ':h:h' + endif + + return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : '' +endfunction + +call ale#linter#Define('go', { +\ 'name': 'gopls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'go_gopls_executable')}, +\ 'command': function('ale_linters#go#gopls#GetCommand'), +\ 'project_root': function('ale_linters#go#gopls#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/go/gosimple.vim b/pack/acp/start/ale/ale_linters/go/gosimple.vim new file mode 100644 index 0000000..281a0e5 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/gosimple.vim @@ -0,0 +1,15 @@ +" Author: Ben Reedy +" Description: gosimple for Go files + +function! ale_linters#go#gosimple#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) . ' gosimple .' +endfunction + +call ale#linter#Define('go', { +\ 'name': 'gosimple', +\ 'executable': 'gosimple', +\ 'command': function('ale_linters#go#gosimple#GetCommand'), +\ 'callback': 'ale#handlers#go#Handler', +\ 'output_stream': 'both', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/go/gotype.vim b/pack/acp/start/ale/ale_linters/go/gotype.vim new file mode 100644 index 0000000..d5d563a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/gotype.vim @@ -0,0 +1,19 @@ +" Author: Jelte Fennema +" Description: gotype for Go files + +function! ale_linters#go#gotype#GetCommand(buffer) abort + if expand('#' . a:buffer . ':p') =~# '_test\.go$' + return '' + endif + + return ale#path#BufferCdString(a:buffer) . ' gotype -e .' +endfunction + +call ale#linter#Define('go', { +\ 'name': 'gotype', +\ 'output_stream': 'stderr', +\ 'executable': 'gotype', +\ 'command': function('ale_linters#go#gotype#GetCommand'), +\ 'callback': 'ale#handlers#go#Handler', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/go/govet.vim b/pack/acp/start/ale/ale_linters/go/govet.vim new file mode 100644 index 0000000..bb81d5d --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/govet.vim @@ -0,0 +1,27 @@ +" Author: neersighted +" Description: go vet for Go files +" +" Author: John Eikenberry +" Description: updated to work with go1.10 + +call ale#Set('go_go_executable', 'go') +call ale#Set('go_govet_options', '') + +function! ale_linters#go#govet#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'go_govet_options') + + return ale#path#BufferCdString(a:buffer) . ' ' + \ . ale#Var(a:buffer, 'go_go_executable') . ' vet ' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' .' +endfunction + +call ale#linter#Define('go', { +\ 'name': 'govet', +\ 'aliases': ['go vet'], +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'go_go_executable')}, +\ 'command': function('ale_linters#go#govet#GetCommand'), +\ 'callback': 'ale#handlers#go#Handler', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/go/langserver.vim b/pack/acp/start/ale/ale_linters/go/langserver.vim new file mode 100644 index 0000000..776186c --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/langserver.vim @@ -0,0 +1,28 @@ +" Author: Horacio Sanson +" Description: Support for go-langserver https://github.com/sourcegraph/go-langserver + +call ale#Set('go_langserver_executable', 'go-langserver') +call ale#Set('go_langserver_options', '') + +function! ale_linters#go#langserver#GetCommand(buffer) abort + let l:executable = [ale#Escape(ale#Var(a:buffer, 'go_langserver_executable'))] + let l:options = ale#Var(a:buffer, 'go_langserver_options') + let l:options = substitute(l:options, '-gocodecompletion', '', 'g') + let l:options = filter(split(l:options, ' '), 'empty(v:val) != 1') + + if ale#Var(a:buffer, 'completion_enabled') + call add(l:options, '-gocodecompletion') + endif + + let l:options = uniq(sort(l:options)) + + return join(extend(l:executable, l:options), ' ') +endfunction + +call ale#linter#Define('go', { +\ 'name': 'golangserver', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'go_langserver_executable')}, +\ 'command': function('ale_linters#go#langserver#GetCommand'), +\ 'project_root': function('ale#go#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/go/staticcheck.vim b/pack/acp/start/ale/ale_linters/go/staticcheck.vim new file mode 100644 index 0000000..26fe019 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/go/staticcheck.vim @@ -0,0 +1,33 @@ +" Author: Ben Reedy +" Description: staticcheck for Go files + +call ale#Set('go_staticcheck_options', '') +call ale#Set('go_staticcheck_lint_package', 0) + +function! ale_linters#go#staticcheck#GetCommand(buffer) abort + let l:filename = expand('#' . a:buffer . ':t') + let l:options = ale#Var(a:buffer, 'go_staticcheck_options') + let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package') + + " BufferCdString is used so that we can be sure the paths output from + " staticcheck can be calculated to absolute paths in the Handler + if l:lint_package + return ale#path#BufferCdString(a:buffer) + \ . 'staticcheck' + \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' + endif + + return ale#path#BufferCdString(a:buffer) + \ . 'staticcheck' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' ' . ale#Escape(l:filename) +endfunction + +call ale#linter#Define('go', { +\ 'name': 'staticcheck', +\ 'executable': 'staticcheck', +\ 'command': function('ale_linters#go#staticcheck#GetCommand'), +\ 'callback': 'ale#handlers#go#Handler', +\ 'output_stream': 'both', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/graphql/eslint.vim b/pack/acp/start/ale/ale_linters/graphql/eslint.vim new file mode 100644 index 0000000..654b8c1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/graphql/eslint.vim @@ -0,0 +1,9 @@ +" Author: Benjie Gillam +" Description: eslint for GraphQL files + +call ale#linter#Define('graphql', { +\ 'name': 'eslint', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/graphql/gqlint.vim b/pack/acp/start/ale/ale_linters/graphql/gqlint.vim new file mode 100644 index 0000000..d5029de --- /dev/null +++ b/pack/acp/start/ale/ale_linters/graphql/gqlint.vim @@ -0,0 +1,15 @@ +" Author: Michiel Westerbeek +" Description: Linter for GraphQL Schemas + +function! ale_linters#graphql#gqlint#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) + \ . 'gqlint' + \ . ' --reporter=simple %t' +endfunction + +call ale#linter#Define('graphql', { +\ 'name': 'gqlint', +\ 'executable': 'gqlint', +\ 'command': function('ale_linters#graphql#gqlint#GetCommand'), +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/pack/acp/start/ale/ale_linters/hack/hack.vim b/pack/acp/start/ale/ale_linters/hack/hack.vim new file mode 100644 index 0000000..822b5c8 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/hack/hack.vim @@ -0,0 +1,22 @@ +" Author: Fred Emmott +" Description: Hack support via `hack lsp` + +call ale#Set('hack_hack_executable', 'hh_client') + +function! ale_linters#hack#hack#GetProjectRoot(buffer) abort + let l:hhconfig = ale#path#FindNearestFile(a:buffer, '.hhconfig') + + return !empty(l:hhconfig) ? fnamemodify(l:hhconfig, ':h') : '' +endfunction + +function! ale_linters#hack#hack#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'hack_hack_executable') +endfunction + +call ale#linter#Define('hack', { +\ 'name': 'hack', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#hack#hack#GetExecutable'), +\ 'command': '%e lsp --from vim-ale', +\ 'project_root': function('ale_linters#hack#hack#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/hack/hhast.vim b/pack/acp/start/ale/ale_linters/hack/hhast.vim new file mode 100644 index 0000000..5e6d4de --- /dev/null +++ b/pack/acp/start/ale/ale_linters/hack/hhast.vim @@ -0,0 +1,40 @@ +" Author: Fred Emmott +" Description: Hack support via `hhast lsp` + +call ale#Set('hack_hhast_executable', 'vendor/bin/hhast-lint') + +function! ale_linters#hack#hhast#GetProjectRoot(buffer) abort + " Find the hack root, then figure out if it's also an HHAST root. + " Don't try to use lint configurations from vendor/foo/bar/hhast-lint.json + let l:hhconfig = ale#path#FindNearestFile(a:buffer, '.hhconfig') + + if empty(l:hhconfig) + return '' + endif + + let l:root = fnamemodify(l:hhconfig, ':h') + let l:hhast_config = findfile('hhast-lint.json', l:root) + + return !empty(l:hhast_config) ? l:root : '' +endfunction + +function! ale_linters#hack#hhast#GetExecutable(buffer) abort + let l:root = ale_linters#hack#hhast#GetProjectRoot(a:buffer) + let l:relative = ale#Var(a:buffer, 'hack_hhast_executable') + let l:absolute = findfile(l:relative, l:root) + + return !empty(l:absolute) ? l:absolute : '' +endfunction + +function! ale_linters#hack#hhast#GetInitializationOptions(buffer) abort + return {'lintMode': 'open-files'} +endfunction + +call ale#linter#Define('hack', { +\ 'name': 'hhast', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#hack#hhast#GetExecutable'), +\ 'command': '%e --mode lsp --from vim-ale', +\ 'project_root': function('ale_linters#hack#hhast#GetProjectRoot'), +\ 'initialization_options': function('ale_linters#hack#hhast#GetInitializationOptions'), +\}) diff --git a/pack/acp/start/ale/ale_linters/haml/hamllint.vim b/pack/acp/start/ale/ale_linters/haml/hamllint.vim new file mode 100644 index 0000000..9fcd999 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haml/hamllint.vim @@ -0,0 +1,57 @@ +" Author: Patrick Lewis - https://github.com/patricklewis, thenoseman - https://github.com/thenoseman +" Description: haml-lint for Haml files + +call ale#Set('haml_hamllint_executable', 'haml-lint') + +function! ale_linters#haml#hamllint#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'haml_hamllint_executable') +endfunction + +function! ale_linters#haml#hamllint#GetCommand(buffer) abort + let l:prefix = '' + + let l:rubocop_config_file_path = ale#path#FindNearestFile(a:buffer, '.rubocop.yml') + let l:hamllint_config_file_path = ale#path#FindNearestFile(a:buffer, '.haml-lint.yml') + + " Set HAML_LINT_RUBOCOP_CONF variable as it is needed for haml-lint to + " pick up the rubocop config. + " + " See https://github.com/brigade/haml-lint/blob/master/lib/haml_lint/linter/rubocop.rb#L89 + " HamlLint::Linter::RuboCop#rubocop_flags + if !empty(l:rubocop_config_file_path) + if has('win32') + let l:prefix = 'set HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path) . ' &&' + else + let l:prefix = 'HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path) + endif + endif + + return (!empty(l:prefix) ? l:prefix . ' ' : '') + \ . ale_linters#haml#hamllint#GetExecutable(a:buffer) + \ . (!empty(l:hamllint_config_file_path) ? ' --config ' . ale#Escape(l:hamllint_config_file_path) : '') + \ . ' %t' +endfunction + +function! ale_linters#haml#hamllint#Handle(buffer, lines) abort + " Matches patterns like the following: + " :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': function('ale_linters#haml#hamllint#GetExecutable'), +\ 'command': function('ale_linters#haml#hamllint#GetCommand'), +\ 'callback': 'ale_linters#haml#hamllint#Handle' +\}) diff --git a/pack/acp/start/ale/ale_linters/handlebars/embertemplatelint.vim b/pack/acp/start/ale/ale_linters/handlebars/embertemplatelint.vim new file mode 100644 index 0000000..74bd6a9 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/handlebars/embertemplatelint.vim @@ -0,0 +1,39 @@ +" 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', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#handlebars#embertemplatelint#Handle(buffer, lines) abort + let l:output = [] + let l:json = ale#util#FuzzyJSONDecode(a:lines, {}) + + for l:error in get(values(l:json), 0, []) + if has_key(l:error, 'fatal') + call add(l:output, { + \ 'lnum': get(l:error, 'line', 1), + \ 'col': get(l:error, 'column', 1), + \ 'text': l:error.message, + \ 'type': l:error.severity == 1 ? 'W' : 'E', + \}) + else + call add(l:output, { + \ 'lnum': l:error.line, + \ 'col': l:error.column, + \ 'text': l:error.rule . ': ' . l:error.message, + \ 'type': l:error.severity == 1 ? 'W' : 'E', + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('handlebars', { +\ 'name': 'ember-template-lint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'handlebars_embertemplatelint', [ +\ 'node_modules/.bin/ember-template-lint', +\ ])}, +\ 'command': '%e --json %t', +\ 'callback': 'ale_linters#handlebars#embertemplatelint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/haskell/cabal_ghc.vim b/pack/acp/start/ale/ale_linters/haskell/cabal_ghc.vim new file mode 100644 index 0000000..f3f248f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haskell/cabal_ghc.vim @@ -0,0 +1,20 @@ +" Author: Eric Wolf +" Description: ghc for Haskell files called with cabal exec + +call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0') + +function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) + \ . 'cabal exec -- ghc ' + \ . ale#Var(a:buffer, 'haskell_cabal_ghc_options') + \ . ' %t' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'cabal_ghc', +\ 'aliases': ['cabal-ghc'], +\ 'output_stream': 'stderr', +\ 'executable': 'cabal', +\ 'command': function('ale_linters#haskell#cabal_ghc#GetCommand'), +\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/haskell/ghc.vim b/pack/acp/start/ale/ale_linters/haskell/ghc.vim new file mode 100644 index 0000000..9c3906b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haskell/ghc.vim @@ -0,0 +1,18 @@ +" Author: w0rp +" Description: ghc for Haskell files + +call ale#Set('haskell_ghc_options', '-fno-code -v0') + +function! ale_linters#haskell#ghc#GetCommand(buffer) abort + return 'ghc ' + \ . ale#Var(a:buffer, 'haskell_ghc_options') + \ . ' %t' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'ghc', +\ 'output_stream': 'stderr', +\ 'executable': 'ghc', +\ 'command': function('ale_linters#haskell#ghc#GetCommand'), +\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/haskell/ghc_mod.vim b/pack/acp/start/ale/ale_linters/haskell/ghc_mod.vim new file mode 100644 index 0000000..30e96b4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haskell/ghc_mod.vim @@ -0,0 +1,19 @@ +" Author: wizzup +" Description: ghc-mod for Haskell files + +call ale#Set('haskell_ghc_mod_executable', 'ghc-mod') + +function! ale_linters#haskell#ghc_mod#GetCommand (buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_ghc_mod_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'ghc-mod') + \ . ' --map-file %s=%t check %s' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'ghc_mod', +\ 'aliases': ['ghc-mod'], +\ 'executable': {b -> ale#Var(b, 'haskell_ghc_mod_executable')}, +\ 'command': function('ale_linters#haskell#ghc_mod#GetCommand'), +\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/haskell/hdevtools.vim b/pack/acp/start/ale/ale_linters/haskell/hdevtools.vim new file mode 100644 index 0000000..3e55e4f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haskell/hdevtools.vim @@ -0,0 +1,20 @@ +" Author: rob-b, Takano Akio +" Description: hdevtools for Haskell files + +call ale#Set('haskell_hdevtools_executable', 'hdevtools') +call ale#Set('haskell_hdevtools_options', get(g:, 'hdevtools_options', '-g -Wall')) + +function! ale_linters#haskell#hdevtools#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_hdevtools_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hdevtools') + \ . ' check' . ale#Pad(ale#Var(a:buffer, 'haskell_hdevtools_options')) + \ . ' -p %s %t' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'hdevtools', +\ 'executable': {b -> ale#Var(b, 'haskell_hdevtools_executable')}, +\ 'command': function('ale_linters#haskell#hdevtools#GetCommand'), +\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/haskell/hie.vim b/pack/acp/start/ale/ale_linters/haskell/hie.vim new file mode 100644 index 0000000..c4b5f1d --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haskell/hie.vim @@ -0,0 +1,41 @@ +" Author: Luxed +" Description: A language server for Haskell + +call ale#Set('haskell_hie_executable', 'hie') + +function! ale_linters#haskell#hie#GetProjectRoot(buffer) abort + " Search for the stack file first + let l:project_file = ale#path#FindNearestFile(a:buffer, 'stack.yaml') + + " If it's empty, search for the cabal file + if empty(l:project_file) + " Search all of the paths except for the root filesystem path. + let l:paths = join( + \ ale#path#Upwards(expand('#' . a:buffer . ':p:h'))[:-2], + \ ',' + \) + let l:project_file = globpath(l:paths, '*.cabal') + endif + + " If we still can't find one, use the current file. + if empty(l:project_file) + let l:project_file = expand('#' . a:buffer . ':p') + endif + + return fnamemodify(l:project_file, ':h') +endfunction + +function! ale_linters#haskell#hie#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_hie_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hie') + \ . ' --lsp' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'hie', +\ 'lsp': 'stdio', +\ 'command': function('ale_linters#haskell#hie#GetCommand'), +\ 'executable': {b -> ale#Var(b, 'haskell_hie_executable')}, +\ 'project_root': function('ale_linters#haskell#hie#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/haskell/hlint.vim b/pack/acp/start/ale/ale_linters/haskell/hlint.vim new file mode 100644 index 0000000..1425251 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haskell/hlint.vim @@ -0,0 +1,46 @@ +" Author: jparoz +" Description: hlint for Haskell files + +call ale#Set('haskell_hlint_executable', 'hlint') +call ale#Set('haskell_hlint_options', get(g:, 'hlint_options', '')) + +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 + +function! ale_linters#haskell#hlint#GetCommand(buffer) abort + let l:hlintopts = '--color=never --json' + + return ale#handlers#hlint#GetExecutable(a:buffer) + \ . ' ' . ale#Var(a:buffer, 'haskell_hlint_options') + \ . ' ' . l:hlintopts + \ . ' -' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'hlint', +\ 'executable': {b -> ale#Var(b, 'haskell_hlint_executable')}, +\ 'command': function('ale_linters#haskell#hlint#GetCommand') , +\ 'callback': 'ale_linters#haskell#hlint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/haskell/stack_build.vim b/pack/acp/start/ale/ale_linters/haskell/stack_build.vim new file mode 100644 index 0000000..8f2d9fd --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haskell/stack_build.vim @@ -0,0 +1,23 @@ +" 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', +\ 'aliases': ['stack-build'], +\ 'output_stream': 'stderr', +\ 'executable': function('ale#handlers#haskell#GetStackExecutable'), +\ 'command': function('ale_linters#haskell#stack_build#GetCommand'), +\ 'lint_file': 1, +\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/haskell/stack_ghc.vim b/pack/acp/start/ale/ale_linters/haskell/stack_ghc.vim new file mode 100644 index 0000000..c345fe4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/haskell/stack_ghc.vim @@ -0,0 +1,21 @@ +" Author: w0rp +" Description: ghc for Haskell files, using Stack + +call ale#Set('haskell_stack_ghc_options', '-fno-code -v0') + +function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) + \ . ale#handlers#haskell#GetStackExecutable(a:buffer) + \ . ' ghc -- ' + \ . ale#Var(a:buffer, 'haskell_stack_ghc_options') + \ . ' %t' +endfunction + +call ale#linter#Define('haskell', { +\ 'name': 'stack_ghc', +\ 'aliases': ['stack-ghc'], +\ 'output_stream': 'stderr', +\ 'executable': function('ale#handlers#haskell#GetStackExecutable'), +\ 'command': function('ale_linters#haskell#stack_ghc#GetCommand'), +\ 'callback': 'ale#handlers#haskell#HandleGHCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/help/alex.vim b/pack/acp/start/ale/ale_linters/help/alex.vim new file mode 100644 index 0000000..9be00a8 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/help/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for help files + +call ale#handlers#alex#DefineLinter('help', '--text') diff --git a/pack/acp/start/ale/ale_linters/help/proselint.vim b/pack/acp/start/ale/ale_linters/help/proselint.vim new file mode 100644 index 0000000..6212450 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/help/writegood.vim b/pack/acp/start/ale/ale_linters/help/writegood.vim new file mode 100644 index 0000000..eeb21a7 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/help/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for vim Help files + +call ale#handlers#writegood#DefineLinter('help') diff --git a/pack/acp/start/ale/ale_linters/html/alex.vim b/pack/acp/start/ale/ale_linters/html/alex.vim new file mode 100644 index 0000000..9775675 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/html/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for HTML files + +call ale#handlers#alex#DefineLinter('html', '--html') diff --git a/pack/acp/start/ale/ale_linters/html/fecs.vim b/pack/acp/start/ale/ale_linters/html/fecs.vim new file mode 100644 index 0000000..15e00e1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/html/fecs.vim @@ -0,0 +1,9 @@ +" Author: harttle +" Description: fecs for HTMl files + +call ale#linter#Define('html', { +\ 'name': 'fecs', +\ 'executable': function('ale#handlers#fecs#GetExecutable'), +\ 'command': function('ale#handlers#fecs#GetCommand'), +\ 'callback': 'ale#handlers#fecs#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/html/htmlhint.vim b/pack/acp/start/ale/ale_linters/html/htmlhint.vim new file mode 100644 index 0000000..3e01f51 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/html/htmlhint.vim @@ -0,0 +1,32 @@ +" Author: KabbAmine , deathmaz <00maz1987@gmail.com>, diartyz +" Description: HTMLHint for checking html files + +call ale#Set('html_htmlhint_options', '') +call ale#Set('html_htmlhint_executable', 'htmlhint') +call ale#Set('html_htmlhint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#html#htmlhint#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'html_htmlhint_options') + let l:config = l:options !~# '--config' + \ ? ale#path#FindNearestFile(a:buffer, '.htmlhintrc') + \ : '' + + if !empty(l:config) + let l:options .= ' --config ' . ale#Escape(l:config) + endif + + if !empty(l:options) + let l:options = substitute(l:options, '--format=unix', '', '') + endif + + return '%e' . ale#Pad(l:options) . ' --format=unix %t' +endfunction + +call ale#linter#Define('html', { +\ 'name': 'htmlhint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'html_htmlhint', [ +\ 'node_modules/.bin/htmlhint', +\ ])}, +\ 'command': function('ale_linters#html#htmlhint#GetCommand'), +\ 'callback': 'ale#handlers#unix#HandleAsError', +\}) diff --git a/pack/acp/start/ale/ale_linters/html/proselint.vim b/pack/acp/start/ale/ale_linters/html/proselint.vim new file mode 100644 index 0000000..9fd7d67 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/html/stylelint.vim b/pack/acp/start/ale/ale_linters/html/stylelint.vim new file mode 100644 index 0000000..ae8955f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/html/stylelint.vim @@ -0,0 +1,27 @@ +" Author: Filipe Kiss http://github.com/filipekiss + +call ale#Set('html_stylelint_executable', 'stylelint') +call ale#Set('html_stylelint_options', '') +call ale#Set('html_stylelint_use_global', 0) + +function! ale_linters#html#stylelint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'html_stylelint', [ + \ 'node_modules/.bin/stylelint', + \]) +endfunction + +function! ale_linters#html#stylelint#GetCommand(buffer) abort + let l:executable = ale_linters#html#stylelint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'html_stylelint_options') + + return ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --stdin-filename %s' +endfunction + +call ale#linter#Define('html', { +\ 'name': 'stylelint', +\ 'executable': function('ale_linters#html#stylelint#GetExecutable'), +\ 'command': function('ale_linters#html#stylelint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleStyleLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/html/tidy.vim b/pack/acp/start/ale/ale_linters/html/tidy.vim new file mode 100644 index 0000000..1e476d4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/html/tidy.vim @@ -0,0 +1,70 @@ +" Author: KabbAmine +" Description: This file adds support for checking HTML code with tidy. + +let g:ale_html_tidy_executable = get(g:, 'ale_html_tidy_executable', 'tidy') +let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', '-q -e -language en') + +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') + + " On macOS, old tidy (released on 31 Oct 2006) is installed. It does not + " consider HTML5 so we should avoid it. + let l:executable = ale#Var(a:buffer, 'html_tidy_executable') + + if has('mac') && l:executable is# 'tidy' && exists('*exepath') + \ && exepath(l:executable) is# '/usr/bin/tidy' + return '' + endif + + return printf('%s %s %s -', + \ l:executable, + \ ale#Var(a:buffer, 'html_tidy_options'), + \ l:file_encoding + \) +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': {b -> ale#Var(b, 'html_tidy_executable')}, +\ 'output_stream': 'stderr', +\ 'command': function('ale_linters#html#tidy#GetCommand'), +\ 'callback': 'ale_linters#html#tidy#Handle', +\ }) diff --git a/pack/acp/start/ale/ale_linters/html/writegood.vim b/pack/acp/start/ale/ale_linters/html/writegood.vim new file mode 100644 index 0000000..6a2bd8e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/html/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for html files + +call ale#handlers#writegood#DefineLinter('html') diff --git a/pack/acp/start/ale/ale_linters/idris/idris.vim b/pack/acp/start/ale/ale_linters/idris/idris.vim new file mode 100644 index 0000000..879e92f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/idris/idris.vim @@ -0,0 +1,81 @@ +" 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#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'idris_idris_options') + + return '%e' . ale#Pad(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': {b -> ale#Var(b, 'idris_idris_executable')}, +\ 'command': function('ale_linters#idris#idris#GetCommand'), +\ 'callback': 'ale_linters#idris#idris#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/ispc/ispc.vim b/pack/acp/start/ale/ale_linters/ispc/ispc.vim new file mode 100644 index 0000000..eb36511 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ispc/ispc.vim @@ -0,0 +1,45 @@ +" Author: Martino Pilia +" Description: Lint ispc files with the Intel(R) SPMD Program Compiler + +call ale#Set('ispc_ispc_executable', 'ispc') +call ale#Set('ispc_ispc_options', '') + +function! ale_linters#ispc#ispc#GetCommand(buffer) abort + " --nowrap: do not wrap message lines + return '%e --nowrap' + \ . ale#Pad(ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))) + \ . ale#Pad(ale#Var(a:buffer, 'ispc_ispc_options')) + \ . ' %s' +endfunction + +" Note that we ignore the two warnings in the beginning of the compiler output +" ('no output file specified' and 'no --target specified'), since they have +" nothing to do with linting. +function! ale_linters#ispc#ispc#Handle(buffer, lines) abort + " Message format: :: : + " As far as I know, can be any of: + " 'error', 'Error', 'fatal error', 'Warning', 'Performance Warning' + let l:re = '\v.+:([0-9]+):([0-9]+):\s+([^:]+):\s+(.+)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:re) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': str2nr(l:match[1]), + \ 'col': str2nr(l:match[2]), + \ 'type': l:match[3] =~? 'error' ? 'E' : 'W', + \ 'text': l:match[4], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('ispc', { +\ 'name': 'ispc', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'ispc_ispc_executable')}, +\ 'command': function('ale_linters#ispc#ispc#GetCommand'), +\ 'callback': 'ale_linters#ispc#ispc#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/java/checkstyle.vim b/pack/acp/start/ale/ale_linters/java/checkstyle.vim new file mode 100644 index 0000000..ee3ca7a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/java/checkstyle.vim @@ -0,0 +1,61 @@ +" Author: Devon Meunier +" Description: checkstyle for Java files + +call ale#Set('java_checkstyle_executable', 'checkstyle') +call ale#Set('java_checkstyle_config', 'google_checks.xml') +call ale#Set('java_checkstyle_options', '') + +function! ale_linters#java#checkstyle#Handle(buffer, lines) abort + let l:output = [] + + " modern checkstyle versions + let l:pattern = '\v\[(WARN|ERROR)\] [a-zA-Z]?:?[^:]+:(\d+):(\d+)?:? (.*) \[(.+)\]$' + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'type': l:match[1] is? 'WARN' ? 'W' : 'E', + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[4], + \ 'code': l:match[5], + \}) + endfor + + if !empty(l:output) + return l:output + endif + + " old checkstyle versions + let l:pattern = '\v(.+):(\d+): ([^:]+): (.+)$' + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'type': l:match[3] is? 'warning' ? 'W' : 'E', + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[4], + \}) + endfor + + return l:output +endfunction + +function! ale_linters#java#checkstyle#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'java_checkstyle_options') + let l:config_option = ale#Var(a:buffer, 'java_checkstyle_config') + let l:config = l:options !~# '\v(^| )-c' && !empty(l:config_option) + \ ? ale#path#FindNearestFile(a:buffer, l:config_option) + \ : '' + + return '%e' + \ . ale#Pad(l:options) + \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') + \ . ' %s' +endfunction + +call ale#linter#Define('java', { +\ 'name': 'checkstyle', +\ 'executable': {b -> ale#Var(b, 'java_checkstyle_executable')}, +\ 'command': function('ale_linters#java#checkstyle#GetCommand'), +\ 'callback': 'ale_linters#java#checkstyle#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/java/eclipselsp.vim b/pack/acp/start/ale/ale_linters/java/eclipselsp.vim new file mode 100644 index 0000000..2648893 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/java/eclipselsp.vim @@ -0,0 +1,161 @@ +" Author: Horacio Sanson +" Description: Support for the Eclipse language server https://github.com/eclipse/eclipse.jdt.ls + +let s:version_cache = {} + +call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls')) +call ale#Set('java_eclipselsp_config_path', '') +call ale#Set('java_eclipselsp_workspace_path', '') +call ale#Set('java_eclipselsp_executable', 'java') + +function! ale_linters#java#eclipselsp#Executable(buffer) abort + return ale#Var(a:buffer, 'java_eclipselsp_executable') +endfunction + +function! ale_linters#java#eclipselsp#TargetPath(buffer) abort + return ale#Var(a:buffer, 'java_eclipselsp_path') +endfunction + +function! ale_linters#java#eclipselsp#JarPath(buffer) abort + let l:path = ale_linters#java#eclipselsp#TargetPath(a:buffer) + + " Search jar file within repository path when manually built using mvn + let l:repo_path = l:path . '/org.eclipse.jdt.ls.product/target/repository' + let l:files = globpath(l:repo_path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1) + + if len(l:files) == 1 + return l:files[0] + endif + + " Search jar file within VSCode extensions folder. + let l:files = globpath(l:path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1) + + if len(l:files) == 1 + return l:files[0] + endif + + " Search jar file within system package path + let l:files = globpath('/usr/share/java/jdtls/plugins', 'org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1) + + if len(l:files) == 1 + return l:files[0] + endif + + return '' +endfunction + +function! ale_linters#java#eclipselsp#ConfigurationPath(buffer) abort + let l:path = fnamemodify(ale_linters#java#eclipselsp#JarPath(a:buffer), ':p:h:h') + let l:config_path = ale#Var(a:buffer, 'java_eclipselsp_config_path') + + if !empty(l:config_path) + return ale#path#Simplify(l:config_path) + endif + + if has('win32') + let l:path = l:path . '/config_win' + elseif has('macunix') + let l:path = l:path . '/config_mac' + else + let l:path = l:path . '/config_linux' + endif + + return ale#path#Simplify(l:path) +endfunction + +function! ale_linters#java#eclipselsp#VersionCheck(version_lines) abort + return s:GetVersion('', a:version_lines) +endfunction + +function! s:GetVersion(executable, version_lines) abort + let l:version = [] + + for l:line in a:version_lines + let l:match = matchlist(l:line, '\(\d\+\)\.\(\d\+\)\.\(\d\+\)') + + if !empty(l:match) + let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[3] + 0] + let s:version_cache[a:executable] = l:version + break + endif + endfor + + return l:version +endfunction + +function! ale_linters#java#eclipselsp#CommandWithVersion(buffer, version_lines, meta) abort + let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer) + let l:version = s:GetVersion(l:executable, a:version_lines) + + return ale_linters#java#eclipselsp#Command(a:buffer, l:version) +endfunction + +function! ale_linters#java#eclipselsp#WorkspacePath(buffer) abort + let l:wspath = ale#Var(a:buffer, 'java_eclipselsp_workspace_path') + + if !empty(l:wspath) + return l:wspath + endif + + return ale#path#Dirname(ale#java#FindProjectRoot(a:buffer)) +endfunction + +function! ale_linters#java#eclipselsp#Command(buffer, version) abort + let l:path = ale#Var(a:buffer, 'java_eclipselsp_path') + + let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer) + + let l:cmd = [ ale#Escape(l:executable), + \ '-Declipse.application=org.eclipse.jdt.ls.core.id1', + \ '-Dosgi.bundles.defaultStartLevel=4', + \ '-Declipse.product=org.eclipse.jdt.ls.core.product', + \ '-Dlog.level=ALL', + \ '-noverify', + \ '-Xmx1G', + \ '-jar', + \ ale#Escape(ale_linters#java#eclipselsp#JarPath(a:buffer)), + \ '-configuration', + \ ale#Escape(ale_linters#java#eclipselsp#ConfigurationPath(a:buffer)), + \ '-data', + \ ale#Escape(ale_linters#java#eclipselsp#WorkspacePath(a:buffer)) + \ ] + + if ale#semver#GTE(a:version, [1, 9]) + call add(l:cmd, '--add-modules=ALL-SYSTEM') + call add(l:cmd, '--add-opens java.base/java.util=ALL-UNNAMED') + call add(l:cmd, '--add-opens java.base/java.lang=ALL-UNNAMED') + endif + + return join(l:cmd, ' ') +endfunction + +function! ale_linters#java#eclipselsp#RunWithVersionCheck(buffer) abort + let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer) + + if empty(l:executable) + return '' + endif + + let l:cache = s:version_cache + + if has_key(s:version_cache, l:executable) + return ale_linters#java#eclipselsp#Command(a:buffer, s:version_cache[l:executable]) + endif + + let l:command = ale#Escape(l:executable) . ' -version' + + return ale#command#Run( + \ a:buffer, + \ l:command, + \ function('ale_linters#java#eclipselsp#CommandWithVersion') + \) +endfunction + +call ale#linter#Define('java', { +\ 'name': 'eclipselsp', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#java#eclipselsp#Executable'), +\ 'command': function('ale_linters#java#eclipselsp#RunWithVersionCheck'), +\ 'language': 'java', +\ 'project_root': function('ale#java#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/java/javac.vim b/pack/acp/start/ale/ale_linters/java/javac.vim new file mode 100644 index 0000000..8bb52c0 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/java/javac.vim @@ -0,0 +1,139 @@ +" Author: farenjihn , w0rp +" Description: Lints java files using javac + +let s:classpath_sep = has('unix') ? ':' : ';' + +call ale#Set('java_javac_executable', 'javac') +call ale#Set('java_javac_options', '') +call ale#Set('java_javac_classpath', '') + +function! ale_linters#java#javac#RunWithImportPaths(buffer) abort + let l:command = '' + let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') + + if !empty(l:pom_path) && executable('mvn') + let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h')) + \ . 'mvn dependency:build-classpath' + endif + + " Try to use Gradle if Maven isn't available. + if empty(l:command) + let l:command = ale#gradle#BuildClasspathCommand(a:buffer) + endif + + " Try to use Ant if Gradle and Maven aren't available + if empty(l:command) + let l:command = ale#ant#BuildClasspathCommand(a:buffer) + endif + + if empty(l:command) + return ale_linters#java#javac#GetCommand(a:buffer, [], {}) + endif + + return ale#command#Run( + \ a:buffer, + \ l:command, + \ function('ale_linters#java#javac#GetCommand') + \) +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, meta) 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') + let l:sp_dirs = [] + + if !empty(l:src_dir) + call add(l:sp_dirs, l:src_dir) + + " Automatically include the jaxb directory too, if it's there. + let l:jaxb_dir = fnamemodify(l:src_dir, ':h:h') + \ . (has('win32') ? '\jaxb\' : '/jaxb/') + + if isdirectory(l:jaxb_dir) + call add(l:sp_dirs, l:jaxb_dir) + endif + endif + + " Automatically include the test directory, but only for test code. + if expand('#' . a:buffer . ':p') =~? '\vsrc[/\\]test[/\\]java' + let l:test_dir = ale#path#FindNearestDirectory(a:buffer, 'src/test/java') + + if isdirectory(l:test_dir) + call add(l:sp_dirs, l:test_dir) + endif + endif + + if !empty(l:sp_dirs) + let l:sp_option = '-sourcepath ' + \ . ale#Escape(join(l:sp_dirs, s:classpath_sep)) + endif + + " Create .class files in a temporary directory, which we will delete later. + let l:class_file_directory = ale#command#CreateDirectory(a:buffer) + + " Always run javac from the directory the file is in, so we can resolve + " relative paths correctly. + return ale#path#BufferCdString(a:buffer) + \ . '%e -Xlint' + \ . ale#Pad(l:cp_option) + \ . ale#Pad(l:sp_option) + \ . ' -d ' . ale#Escape(l:class_file_directory) + \ . ale#Pad(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:directory = expand('#' . a:buffer . ':p:h') + let l:pattern = '\v^(.*):(\d+): (.{-1,}):(.+)$' + 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, { + \ 'filename': ale#path#GetAbsPath(l:directory, l:match[1]), + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[3] . ':' . l:match[4], + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('java', { +\ 'name': 'javac', +\ 'executable': {b -> ale#Var(b, 'java_javac_executable')}, +\ 'command': function('ale_linters#java#javac#RunWithImportPaths'), +\ 'output_stream': 'stderr', +\ 'callback': 'ale_linters#java#javac#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/java/javalsp.vim b/pack/acp/start/ale/ale_linters/java/javalsp.vim new file mode 100644 index 0000000..f56675d --- /dev/null +++ b/pack/acp/start/ale/ale_linters/java/javalsp.vim @@ -0,0 +1,41 @@ +" Author: Horacio Sanson +" Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac + +call ale#Set('java_javalsp_executable', '') + +function! ale_linters#java#javalsp#Executable(buffer) abort + return ale#Var(a:buffer, 'java_javalsp_executable') +endfunction + +function! ale_linters#java#javalsp#Command(buffer) abort + let l:executable = ale_linters#java#javalsp#Executable(a:buffer) + + if fnamemodify(l:executable, ':t') is# 'java' + " For backward compatibility. + let l:cmd = [ + \ ale#Escape(l:executable), + \ '--add-exports jdk.compiler/com.sun.tools.javac.api=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.code=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.comp=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.main=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.tree=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.model=javacs', + \ '--add-exports jdk.compiler/com.sun.tools.javac.util=javacs', + \ '--add-opens jdk.compiler/com.sun.tools.javac.api=javacs', + \ '-m javacs/org.javacs.Main', + \] + + return join(l:cmd, ' ') + else + return ale#Escape(l:executable) + endif +endfunction + +call ale#linter#Define('java', { +\ 'name': 'javalsp', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#java#javalsp#Executable'), +\ 'command': function('ale_linters#java#javalsp#Command'), +\ 'language': 'java', +\ 'project_root': function('ale#java#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/java/pmd.vim b/pack/acp/start/ale/ale_linters/java/pmd.vim new file mode 100644 index 0000000..a1f4c93 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/java/pmd.vim @@ -0,0 +1,36 @@ +" Author: Johannes Wienke +" Description: PMD for Java files + +function! ale_linters#java#pmd#Handle(buffer, lines) abort + let l:pattern = '"\(\d\+\)",".*","\(.\+\)","\(\d\+\)","\(\d\+\)","\(.\+\)","\(.\+\)","\(.\+\)"$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'type': 'W', + \ 'lnum': l:match[4] + 0, + \ 'text': l:match[5], + \ 'code': l:match[6] . ' - ' . l:match[7], + \}) + endfor + + return l:output +endfunction + +function! ale_linters#java#pmd#GetCommand(buffer) abort + return 'pmd ' + \ . ale#Var(a:buffer, 'java_pmd_options') + \ . ' -f csv' + \ . ' -d %t' +endfunction + +if !exists('g:ale_java_pmd_options') + let g:ale_java_pmd_options = '-R category/java/bestpractices.xml' +endif + +call ale#linter#Define('java', { +\ 'name': 'pmd', +\ 'executable': 'pmd', +\ 'command': function('ale_linters#java#pmd#GetCommand'), +\ 'callback': 'ale_linters#java#pmd#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/eslint.vim b/pack/acp/start/ale/ale_linters/javascript/eslint.vim new file mode 100644 index 0000000..31fb413 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/javascript/eslint.vim @@ -0,0 +1,10 @@ +" Author: w0rp +" Description: eslint for JavaScript files + +call ale#linter#Define('javascript', { +\ 'name': 'eslint', +\ 'output_stream': 'both', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/fecs.vim b/pack/acp/start/ale/ale_linters/javascript/fecs.vim new file mode 100644 index 0000000..e47c0a0 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/javascript/fecs.vim @@ -0,0 +1,10 @@ +" Author: harttle +" Description: fecs for JavaScript files + +call ale#linter#Define('javascript', { +\ 'name': 'fecs', +\ 'executable': function('ale#handlers#fecs#GetExecutable'), +\ 'command': function('ale#handlers#fecs#GetCommand'), +\ 'read_buffer': 0, +\ 'callback': 'ale#handlers#fecs#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/flow.vim b/pack/acp/start/ale/ale_linters/javascript/flow.vim new file mode 100755 index 0000000..3135e2e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/javascript/flow.vim @@ -0,0 +1,160 @@ +" Author: Zach Perrault -- @zperrault +" Author: Florian Beeres +" Description: FlowType checking for JavaScript files + +call ale#Set('javascript_flow_executable', 'flow') +call ale#Set('javascript_flow_use_home_config', 0) +call ale#Set('javascript_flow_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('javascript_flow_use_respect_pragma', 1) + +function! ale_linters#javascript#flow#GetExecutable(buffer) 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 + + " Don't run Flow with a configuration file from the home directory by + " default, which can eat all of your RAM. + if fnamemodify(l:flow_config, ':h') is? $HOME + \&& !ale#Var(a:buffer, 'javascript_flow_use_home_config') + return '' + endif + + return ale#node#FindExecutable(a:buffer, 'javascript_flow', [ + \ 'node_modules/.bin/flow', + \]) +endfunction + +function! ale_linters#javascript#flow#GetCommand(buffer, version) abort + " If we can parse the version number, then only use --respect-pragma + " if the version is >= 0.36.0, which added the argument. + let l:use_respect_pragma = ale#Var(a:buffer, 'javascript_flow_use_respect_pragma') + \ && (empty(a:version) || ale#semver#GTE(a:version, [0, 36])) + + return '%e check-contents' + \ . (l:use_respect_pragma ? ' --respect-pragma': '') + \ . ' --json --from ale %s < %t' + \ . (!has('win32') ? '; echo' : '') +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! s:ExtraErrorMsg(current, new) abort + let l:newMsg = '' + + if a:current is# '' + " extra messages appear to already have a : + let l:newMsg = a:new + else + let l:newMsg = a:current . ' ' . a:new + endif + + return l:newMsg +endfunction + +function! s:GetDetails(error) abort + let l:detail = '' + + for l:extra_error in a:error.extra + if has_key(l:extra_error, 'message') + for l:extra_message in l:extra_error.message + let l:detail = s:ExtraErrorMsg(l:detail, l:extra_message.descr) + endfor + endif + + if has_key(l:extra_error, 'children') + for l:child in l:extra_error.children + for l:child_message in l:child.message + let l:detail = l:detail . ' ' . l:child_message.descr + endfor + endfor + endif + endfor + + return l:detail +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 + + let l:errorToAdd = { + \ 'lnum': l:line, + \ 'col': l:col, + \ 'text': l:text, + \ 'type': has_key(l:error, 'level') && l:error.level is# 'error' ? 'E' : 'W', + \} + + if has_key(l:error, 'extra') + let l:errorToAdd.detail = l:errorToAdd.text + \ . "\n" . s:GetDetails(l:error) + endif + + call add(l:output, l:errorToAdd) + endfor + + return l:output +endfunction + +call ale#linter#Define('javascript', { +\ 'name': 'flow', +\ 'executable': function('ale_linters#javascript#flow#GetExecutable'), +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale_linters#javascript#flow#GetExecutable(buffer), +\ '%e --version', +\ function('ale_linters#javascript#flow#GetCommand'), +\ )}, +\ 'callback': 'ale_linters#javascript#flow#Handle', +\ 'read_buffer': 0, +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/flow_ls.vim b/pack/acp/start/ale/ale_linters/javascript/flow_ls.vim new file mode 100644 index 0000000..accaaa7 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/javascript/flow_ls.vim @@ -0,0 +1,28 @@ +" Author: t_t +" Description: Integrate ALE with flow-language-server. + +call ale#Set('javascript_flow_ls_executable', 'flow') +call ale#Set('javascript_flow_ls_use_global', +\ get(g:, 'ale_use_global_executables', 0) +\) + +function! ale_linters#javascript#flow_ls#FindProjectRoot(buffer) abort + let l:flow_config = ale#path#FindNearestFile(a:buffer, '.flowconfig') + + if !empty(l:flow_config) + return fnamemodify(l:flow_config, ':h') + endif + + return '' +endfunction + +call ale#linter#Define('javascript', { +\ 'name': 'flow-language-server', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#node#FindExecutable(b, 'javascript_flow_ls', [ +\ 'node_modules/.bin/flow', +\ ])}, +\ 'command': '%e lsp --from ale-lsp', +\ 'project_root': function('ale_linters#javascript#flow_ls#FindProjectRoot'), +\ 'language': 'javascript', +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/jscs.vim b/pack/acp/start/ale/ale_linters/javascript/jscs.vim new file mode 100644 index 0000000..8905b3a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/javascript/jscs.vim @@ -0,0 +1,61 @@ +" 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', get(g:, 'ale_use_global_executables', 0)) + +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 = '%e --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 = '\v^.*:\s+line (\d+),\s+col\s+(\d+),\s+(.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:obj = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[3] + \} + + let l:code_match = matchlist(l:match[3], '\v([^ :]+): (.+)$') + + if !empty(l:code_match) + let l:obj.code = l:code_match[1] + let l:obj.text = l:code_match[2] + endif + + call add(l:output, l:obj) + endfor + + return l:output +endfunction + +call ale#linter#Define('javascript', { +\ 'name': 'jscs', +\ 'executable': {b -> ale#node#FindExecutable(b, 'javascript_jscs', [ +\ 'node_modules/.bin/jscs', +\ ])}, +\ 'command': function('ale_linters#javascript#jscs#GetCommand'), +\ 'callback': 'ale_linters#javascript#jscs#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/jshint.vim b/pack/acp/start/ale/ale_linters/javascript/jshint.vim new file mode 100644 index 0000000..d80a225 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/javascript/jshint.vim @@ -0,0 +1,33 @@ +" 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', get(g:, 'ale_use_global_executables', 0)) + +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 = '%e --reporter unix --extract auto' + + if !empty(l:jshint_config) + let l:command .= ' --config ' . ale#Escape(l:jshint_config) + endif + + let l:command .= ' --filename %s -' + + return l:command +endfunction + +call ale#linter#Define('javascript', { +\ 'name': 'jshint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'javascript_jshint', [ +\ 'node_modules/.bin/jshint', +\ ])}, +\ 'command': function('ale_linters#javascript#jshint#GetCommand'), +\ 'callback': 'ale#handlers#unix#HandleAsError', +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/standard.vim b/pack/acp/start/ale/ale_linters/javascript/standard.vim new file mode 100644 index 0000000..4cd2c30 --- /dev/null +++ b/pack/acp/start/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', get(g:, 'ale_use_global_executables', 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': function('ale_linters#javascript#standard#GetExecutable'), +\ 'command': function('ale_linters#javascript#standard#GetCommand'), +\ 'callback': 'ale#handlers#eslint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/tsserver.vim b/pack/acp/start/ale/ale_linters/javascript/tsserver.vim new file mode 100644 index 0000000..68c252c --- /dev/null +++ b/pack/acp/start/ale/ale_linters/javascript/tsserver.vim @@ -0,0 +1,17 @@ +" Author: Chaucerbao, w0rp +" Description: tsserver integration for ALE + +call ale#Set('javascript_tsserver_executable', 'tsserver') +call ale#Set('javascript_tsserver_config_path', '') +call ale#Set('javascript_tsserver_use_global', get(g:, 'ale_use_global_executables', 0)) + +call ale#linter#Define('javascript', { +\ 'name': 'tsserver', +\ 'lsp': 'tsserver', +\ 'executable': {b -> ale#node#FindExecutable(b, 'javascript_tsserver', [ +\ 'node_modules/.bin/tsserver', +\ ])}, +\ 'command': '%e', +\ 'project_root': function('ale#handlers#tsserver#GetProjectRoot'), +\ 'language': '', +\}) diff --git a/pack/acp/start/ale/ale_linters/javascript/xo.vim b/pack/acp/start/ale/ale_linters/javascript/xo.vim new file mode 100644 index 0000000..e24f4a8 --- /dev/null +++ b/pack/acp/start/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', get(g:, 'ale_use_global_executables', 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 json --stdin --stdin-filename %s' +endfunction + +" xo uses eslint and the output format is the same +call ale#linter#Define('javascript', { +\ 'name': 'xo', +\ 'executable': function('ale_linters#javascript#xo#GetExecutable'), +\ 'command': function('ale_linters#javascript#xo#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', +\}) diff --git a/pack/acp/start/ale/ale_linters/json/jsonlint.vim b/pack/acp/start/ale/ale_linters/json/jsonlint.vim new file mode 100644 index 0000000..f677b48 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/json/jsonlint.vim @@ -0,0 +1,43 @@ +" Author: KabbAmine , David Sierra + +call ale#Set('json_jsonlint_executable', 'jsonlint') +call ale#Set('json_jsonlint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#json#jsonlint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'json_jsonlint', [ + \ 'node_modules/.bin/jsonlint', + \ 'node_modules/jsonlint/lib/cli.js', + \]) +endfunction + +function! ale_linters#json#jsonlint#GetCommand(buffer) abort + let l:executable = ale_linters#json#jsonlint#GetExecutable(a:buffer) + + return ale#node#Executable(a:buffer, l:executable) + \ . ' --compact -' +endfunction + +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': function('ale_linters#json#jsonlint#GetExecutable'), +\ 'output_stream': 'stderr', +\ 'command': function('ale_linters#json#jsonlint#GetCommand'), +\ 'callback': 'ale_linters#json#jsonlint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/julia/languageserver.vim b/pack/acp/start/ale/ale_linters/julia/languageserver.vim new file mode 100644 index 0000000..564bec3 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/julia/languageserver.vim @@ -0,0 +1,21 @@ +" Author: Bartolomeo Stellato +" Description: A language server for Julia + +" Set julia executable variable +call ale#Set('julia_executable', 'julia') + +function! ale_linters#julia#languageserver#GetCommand(buffer) abort + let l:julia_executable = ale#Var(a:buffer, 'julia_executable') + let l:cmd_string = 'using LanguageServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, false); server.runlinter = true; run(server);' + + return ale#Escape(l:julia_executable) . ' --startup-file=no --history-file=no -e ' . ale#Escape(l:cmd_string) +endfunction + +call ale#linter#Define('julia', { +\ 'name': 'languageserver', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'julia_executable')}, +\ 'command': function('ale_linters#julia#languageserver#GetCommand'), +\ 'language': 'julia', +\ 'project_root': function('ale#julia#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/kotlin/kotlinc.vim b/pack/acp/start/ale/ale_linters/kotlin/kotlinc.vim new file mode 100644 index 0000000..3c6854f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/kotlin/kotlinc.vim @@ -0,0 +1,180 @@ +" 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#RunWithImportPaths(buffer) abort + let l:command = '' + + " exec maven/gradle only if classpath is not set + if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# '' + return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {}) + endif + + let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') + + if !empty(l:pom_path) && executable('mvn') + let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h')) + \ . 'mvn dependency:build-classpath' + endif + + " Try to use Gradle if Maven isn't available. + if empty(l:command) + let l:command = ale#gradle#BuildClasspathCommand(a:buffer) + endif + + if empty(l:command) + return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {}) + endif + + return ale#command#Run( + \ a:buffer, + \ l:command, + \ function('ale_linters#kotlin#kotlinc#GetCommand') + \) +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, meta) 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': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'), +\ 'callback': 'ale_linters#kotlin#kotlinc#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/kotlin/ktlint.vim b/pack/acp/start/ale/ale_linters/kotlin/ktlint.vim new file mode 100644 index 0000000..f038400 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/kotlin/ktlint.vim @@ -0,0 +1,10 @@ +" Author: Francis Agyapong +" Description: Lint kotlin files using ktlint + +call ale#linter#Define('kotlin', { +\ 'name': 'ktlint', +\ 'executable': 'ktlint', +\ 'command': function('ale#handlers#ktlint#GetCommand'), +\ 'callback': 'ale#handlers#ktlint#Handle', +\ 'lint_file': 1 +\}) diff --git a/pack/acp/start/ale/ale_linters/kotlin/languageserver.vim b/pack/acp/start/ale/ale_linters/kotlin/languageserver.vim new file mode 100644 index 0000000..af78c0e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/kotlin/languageserver.vim @@ -0,0 +1,29 @@ +" Author: MTDL9 +" Description: Support for the Kotlin language server https://github.com/fwcd/KotlinLanguageServer + +call ale#Set('kotlin_languageserver_executable', 'kotlin-language-server') + +function! ale_linters#kotlin#languageserver#GetProjectRoot(buffer) abort + let l:gradle_root = ale#gradle#FindProjectRoot(a:buffer) + + if !empty(l:gradle_root) + return l:gradle_root + endif + + let l:maven_pom_file = ale#path#FindNearestFile(a:buffer, 'pom.xml') + + if !empty(l:maven_pom_file) + return fnamemodify(l:maven_pom_file, ':h') + endif + + return '' +endfunction + +call ale#linter#Define('kotlin', { +\ 'name': 'languageserver', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'kotlin_languageserver_executable')}, +\ 'command': '%e', +\ 'language': 'kotlin', +\ 'project_root': function('ale_linters#kotlin#languageserver#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/less/lessc.vim b/pack/acp/start/ale/ale_linters/less/lessc.vim new file mode 100755 index 0000000..4ec8b00 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/less/lessc.vim @@ -0,0 +1,47 @@ +" Author: zanona , w0rp +" Description: This file adds support for checking Less code with lessc. + +call ale#Set('less_lessc_executable', 'lessc') +call ale#Set('less_lessc_options', '') +call ale#Set('less_lessc_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#less#lessc#GetCommand(buffer) abort + return '%e --no-color --lint' + \ . ' --include-path=' . ale#Escape(expand('#' . a:buffer . ':p:h')) + \ . ale#Pad(ale#Var(a:buffer, 'less_lessc_options')) + \ . ' -' +endfunction + +function! ale_linters#less#lessc#Handle(buffer, lines) abort + let l:dir = expand('#' . a:buffer . ':p:h') + " Matches patterns like the following: + let l:pattern = '^\(\w\+\): \(.\{-}\) in \(.\{-}\) on line \(\d\+\), column \(\d\+\):$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': l:match[4] + 0, + \ 'col': l:match[5] + 0, + \ 'text': l:match[2], + \ 'type': 'E', + \} + + if l:match[3] isnot# '-' + let l:item.filename = ale#path#GetAbsPath(l:dir, l:match[3]) + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('less', { +\ 'name': 'lessc', +\ 'executable': {b -> ale#node#FindExecutable(b, 'less_lessc', [ +\ 'node_modules/.bin/lessc', +\ ])}, +\ 'command': function('ale_linters#less#lessc#GetCommand'), +\ 'callback': 'ale_linters#less#lessc#Handle', +\ 'output_stream': 'stderr', +\}) diff --git a/pack/acp/start/ale/ale_linters/less/stylelint.vim b/pack/acp/start/ale/ale_linters/less/stylelint.vim new file mode 100644 index 0000000..efb036c --- /dev/null +++ b/pack/acp/start/ale/ale_linters/less/stylelint.vim @@ -0,0 +1,20 @@ +" Author: diartyz , w0rp + +call ale#Set('less_stylelint_executable', 'stylelint') +call ale#Set('less_stylelint_options', '') +call ale#Set('less_stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#less#stylelint#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'less_stylelint_options') + + return '%e' . ale#Pad(l:options) . ' --stdin-filename %s' +endfunction + +call ale#linter#Define('less', { +\ 'name': 'stylelint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'less_stylelint', [ +\ 'node_modules/.bin/stylelint', +\ ])}, +\ 'command': function('ale_linters#less#stylelint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleStyleLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/llvm/llc.vim b/pack/acp/start/ale/ale_linters/llvm/llc.vim new file mode 100644 index 0000000..594be06 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/llvm/llc.vim @@ -0,0 +1,24 @@ +" Author: rhysd +" Description: Support for checking LLVM IR with llc + +call ale#Set('llvm_llc_executable', 'llc') + +function! ale_linters#llvm#llc#HandleErrors(buffer, lines) abort + " Handle '{path}: {file}:{line}:{col}: error: {message}' format + let l:pattern = '\v^[a-zA-Z]?:?[^:]+: [^:]+:(\d+):(\d+): (.+)$' + + return map(ale#util#GetMatches(a:lines, l:pattern), "{ + \ 'lnum': str2nr(v:val[1]), + \ 'col': str2nr(v:val[2]), + \ 'text': v:val[3], + \ 'type': 'E', + \}") +endfunction + +call ale#linter#Define('llvm', { +\ 'name': 'llc', +\ 'executable': {b -> ale#Var(b, 'llvm_llc_executable')}, +\ 'output_stream': 'stderr', +\ 'command': {-> '%e -filetype=null -o=' . g:ale#util#nul_file}, +\ 'callback': 'ale_linters#llvm#llc#HandleErrors', +\}) diff --git a/pack/acp/start/ale/ale_linters/lua/luac.vim b/pack/acp/start/ale/ale_linters/lua/luac.vim new file mode 100644 index 0000000..41674a4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/lua/luac.vim @@ -0,0 +1,31 @@ +" Author: Jon Xie https://github.com/xiejiangzhi +" Description: luac linter for lua files + +call ale#Set('lua_luac_executable', 'luac') + +function! ale_linters#lua#luac#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " luac: stdin:5: '=' expected near ')' + " luac: stdin:8: ')' expected (to close '(' at line 6) near '123' + let l:pattern = '\v^.*:(\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': 'E', + \ 'text': l:match[2], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('lua', { +\ 'name': 'luac', +\ 'executable': {b -> ale#Var(b, 'lua_luac_executable')}, +\ 'command': '%e -p -', +\ 'output_stream': 'stderr', +\ 'callback': 'ale_linters#lua#luac#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/lua/luacheck.vim b/pack/acp/start/ale/ale_linters/lua/luacheck.vim new file mode 100644 index 0000000..34be2b5 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/lua/luacheck.vim @@ -0,0 +1,44 @@ +" Author: Sol Bekic https://github.com/s-ol +" Description: luacheck linter for lua files + +call ale#Set('lua_luacheck_executable', 'luacheck') +call ale#Set('lua_luacheck_options', '') + +function! ale_linters#lua#luacheck#GetCommand(buffer) abort + return '%e' . ale#Pad(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) + if !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + \ && l:match[3] is# 'W' + \ && index(range(611, 614), str2nr(l:match[4])) >= 0 + continue + endif + + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:match[3], + \ 'code': l:match[3] . l:match[4], + \ 'text': l:match[5], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('lua', { +\ 'name': 'luacheck', +\ 'executable': {b -> ale#Var(b, 'lua_luacheck_executable')}, +\ 'command': function('ale_linters#lua#luacheck#GetCommand'), +\ 'callback': 'ale_linters#lua#luacheck#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/mail/alex.vim b/pack/acp/start/ale/ale_linters/mail/alex.vim new file mode 100644 index 0000000..0fceea7 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/mail/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for mail files + +call ale#handlers#alex#DefineLinter('mail', '--text') diff --git a/pack/acp/start/ale/ale_linters/mail/languagetool.vim b/pack/acp/start/ale/ale_linters/mail/languagetool.vim new file mode 100644 index 0000000..330fb8e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/mail/languagetool.vim @@ -0,0 +1,5 @@ +" Author: Vincent (wahrwolf [ät] wolfpit.net) +" Description: languagetool for mails + + +call ale#handlers#languagetool#DefineLinter('mail') diff --git a/pack/acp/start/ale/ale_linters/mail/proselint.vim b/pack/acp/start/ale/ale_linters/mail/proselint.vim new file mode 100644 index 0000000..82c8d1f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/mail/proselint.vim @@ -0,0 +1,9 @@ +" Author: Daniel M. Capella https://github.com/polyzen +" Description: proselint for mail files + +call ale#linter#Define('mail', { +\ 'name': 'proselint', +\ 'executable': 'proselint', +\ 'command': 'proselint %t', +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/pack/acp/start/ale/ale_linters/mail/vale.vim b/pack/acp/start/ale/ale_linters/mail/vale.vim new file mode 100644 index 0000000..e6dfd2e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/mail/vale.vim @@ -0,0 +1,9 @@ +" Author: chew-z https://github.com/chew-z +" Description: vale for Markdown files + +call ale#linter#Define('mail', { +\ 'name': 'vale', +\ 'executable': 'vale', +\ 'command': 'vale --output=JSON %t', +\ 'callback': 'ale#handlers#vale#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/make/checkmake.vim b/pack/acp/start/ale/ale_linters/make/checkmake.vim new file mode 100644 index 0000000..5ebdf91 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/make/checkmake.vim @@ -0,0 +1,25 @@ +" Author: aurieh - https://github.com/aurieh + +function! ale_linters#make#checkmake#Handle(buffer, lines) abort + let l:pattern = '\v^(\d+):(.+):(.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': l:match[1] + 0, + \ 'type': 'E', + \ 'code': l:match[2], + \ 'text': l:match[3], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('make', { +\ 'name': 'checkmake', +\ 'executable': 'checkmake', +\ 'command': 'checkmake %s --format="{{.LineNumber}}:{{.Rule}}:{{.Violation}}"', +\ 'callback': 'ale_linters#make#checkmake#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/markdown/alex.vim b/pack/acp/start/ale/ale_linters/markdown/alex.vim new file mode 100644 index 0000000..63769b5 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/markdown/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for markdown files + +call ale#handlers#alex#DefineLinter('markdown', '') diff --git a/pack/acp/start/ale/ale_linters/markdown/languagetool.vim b/pack/acp/start/ale/ale_linters/markdown/languagetool.vim new file mode 100644 index 0000000..d6bca22 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/markdown/languagetool.vim @@ -0,0 +1,5 @@ +" Author: Vincent (wahrwolf [ät] wolfpit.net) +" Description: languagetool for markdown files + + +call ale#handlers#languagetool#DefineLinter('markdown') diff --git a/pack/acp/start/ale/ale_linters/markdown/markdownlint.vim b/pack/acp/start/ale/ale_linters/markdown/markdownlint.vim new file mode 100644 index 0000000..e935cbf --- /dev/null +++ b/pack/acp/start/ale/ale_linters/markdown/markdownlint.vim @@ -0,0 +1,11 @@ +" Author: Ty-Lucas Kelley +" Description: Adds support for markdownlint + +call ale#linter#Define('markdown', { +\ 'name': 'markdownlint', +\ 'executable': 'markdownlint', +\ 'lint_file': 1, +\ 'output_stream': 'both', +\ 'command': 'markdownlint %s', +\ 'callback': 'ale#handlers#markdownlint#Handle' +\}) diff --git a/pack/acp/start/ale/ale_linters/markdown/mdl.vim b/pack/acp/start/ale/ale_linters/markdown/mdl.vim new file mode 100644 index 0000000..305f535 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/markdown/mdl.vim @@ -0,0 +1,44 @@ +" Author: Steve Dignam , Josh Leeb-du Toit +" Description: Support for mdl, a markdown linter. + +call ale#Set('markdown_mdl_executable', 'mdl') +call ale#Set('markdown_mdl_options', '') + +function! ale_linters#markdown#mdl#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'markdown_mdl_executable') +endfunction + +function! ale_linters#markdown#mdl#GetCommand(buffer) abort + let l:executable = ale_linters#markdown#mdl#GetExecutable(a:buffer) + let l:exec_args = l:executable =~? 'bundle$' + \ ? ' exec mdl' + \ : '' + + let l:options = ale#Var(a:buffer, 'markdown_mdl_options') + + return ale#Escape(l:executable) . l:exec_args + \ . (!empty(l:options) ? ' ' . l:options : '') +endfunction + +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': function('ale_linters#markdown#mdl#GetExecutable'), +\ 'command': function('ale_linters#markdown#mdl#GetCommand'), +\ 'callback': 'ale_linters#markdown#mdl#Handle' +\}) diff --git a/pack/acp/start/ale/ale_linters/markdown/proselint.vim b/pack/acp/start/ale/ale_linters/markdown/proselint.vim new file mode 100644 index 0000000..289d881 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/markdown/redpen.vim b/pack/acp/start/ale/ale_linters/markdown/redpen.vim new file mode 100644 index 0000000..ff2cbaf --- /dev/null +++ b/pack/acp/start/ale/ale_linters/markdown/redpen.vim @@ -0,0 +1,9 @@ +" Author: rhysd https://rhysd.github.io +" Description: Redpen, a proofreading tool (http://redpen.cc) + +call ale#linter#Define('markdown', { +\ 'name': 'redpen', +\ 'executable': 'redpen', +\ 'command': 'redpen -f markdown -r json %t', +\ 'callback': 'ale#handlers#redpen#HandleRedpenOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/markdown/remark_lint.vim b/pack/acp/start/ale/ale_linters/markdown/remark_lint.vim new file mode 100644 index 0000000..ed87d1a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/markdown/remark_lint.vim @@ -0,0 +1,48 @@ +scriptencoding utf-8 +" Author rhysd https://rhysd.github.io/, Dirk Roorda (dirkroorda), Adrián González Rus (@adrigzr) +" Description: remark-lint for Markdown files +call ale#Set('markdown_remark_lint_executable', 'remark') +call ale#Set('markdown_remark_lint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('markdown_remark_lint_options', '') + +function! ale_linters#markdown#remark_lint#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'markdown_remark_lint_options') + + return '%e' . ale#Pad(l:options) . ' --no-stdout --no-color' +endfunction + +function! ale_linters#markdown#remark_lint#Handle(buffer, lines) abort + " matches: ' 1:4 warning Incorrect list-item indent: add 1 space list-item-indent remark-lint' + " matches: ' 18:71-19:1 error Missing new line after list item list-item-spacing remark-lint', + let l:pattern = '^ \+\(\d\+\):\(\d\+\)\(-\(\d\+\):\(\d\+\)\)\? \(warning\|error\) \(.\+\)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:match[6] is# 'error' ? 'E' : 'W', + \ 'text': l:match[7], + \} + + if l:match[3] isnot# '' + let l:item.end_lnum = l:match[4] + 0 + let l:item.end_col = l:match[5] + 0 + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('markdown', { +\ 'name': 'remark_lint', +\ 'aliases': ['remark-lint'], +\ 'executable': {b -> ale#node#FindExecutable(b, 'markdown_remark_lint', [ +\ 'node_modules/.bin/remark', +\ ])}, +\ 'command': function('ale_linters#markdown#remark_lint#GetCommand'), +\ 'callback': 'ale_linters#markdown#remark_lint#Handle', +\ 'output_stream': 'stderr', +\}) diff --git a/pack/acp/start/ale/ale_linters/markdown/textlint.vim b/pack/acp/start/ale/ale_linters/markdown/textlint.vim new file mode 100644 index 0000000..613c841 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/markdown/textlint.vim @@ -0,0 +1,9 @@ +" Author: tokida https://rouger.info, Yasuhiro Kiyota +" Description: textlint, a proofreading tool (https://textlint.github.io/) + +call ale#linter#Define('markdown', { +\ 'name': 'textlint', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), +\ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/markdown/vale.vim b/pack/acp/start/ale/ale_linters/markdown/vale.vim new file mode 100644 index 0000000..838c4db --- /dev/null +++ b/pack/acp/start/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=JSON %t', +\ 'callback': 'ale#handlers#vale#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/markdown/writegood.vim b/pack/acp/start/ale/ale_linters/markdown/writegood.vim new file mode 100644 index 0000000..7108e7a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/markdown/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for Markdown files + +call ale#handlers#writegood#DefineLinter('markdown') diff --git a/pack/acp/start/ale/ale_linters/matlab/mlint.vim b/pack/acp/start/ale/ale_linters/matlab/mlint.vim new file mode 100644 index 0000000..f58f8b6 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/matlab/mlint.vim @@ -0,0 +1,44 @@ +" Author: awlayton +" Description: mlint for MATLAB files + +call ale#Set('matlab_mlint_executable', 'mlint') + +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': {b -> ale#Var(b, 'matlab_mlint_executable')}, +\ 'command': '%e -id %t', +\ 'output_stream': 'stderr', +\ 'callback': 'ale_linters#matlab#mlint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/mercury/mmc.vim b/pack/acp/start/ale/ale_linters/mercury/mmc.vim new file mode 100644 index 0000000..8a9ccc0 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/mercury/mmc.vim @@ -0,0 +1,40 @@ +" Author: stewy33 +" Description: Lints mercury files using mmc + +call ale#Set('mercury_mmc_executable', 'mmc') +call ale#Set('mercury_mmc_options', '--make --output-compile-error-lines 100') + +function! ale_linters#mercury#mmc#GetCommand(buffer) abort + let l:module_name = expand('#' . a:buffer . ':t:r') + + return ale#path#BufferCdString(a:buffer) + \ . '%e --errorcheck-only ' + \ . ale#Var(a:buffer, 'mercury_mmc_options') + \ . ' ' . l:module_name +endfunction + +function! ale_linters#mercury#mmc#Handle(buffer, lines) abort + " output format + " :: : + let l:pattern = '\v^\w+\.m:(\d+):\s+([W|w]arning|.*[E|e]rror.*): (.*)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': substitute(l:match[1], '\v^0*', '', '') + 0, + \ 'type': l:match[2][0] =~? 'W' ? 'W' : 'E', + \ 'text': l:match[2] . ': ' . l:match[3] + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('mercury', { +\ 'name': 'mmc', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'mercury_mmc_executable')}, +\ 'command': function('ale_linters#mercury#mmc#GetCommand'), +\ 'callback': 'ale_linters#mercury#mmc#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/nasm/nasm.vim b/pack/acp/start/ale/ale_linters/nasm/nasm.vim new file mode 100644 index 0000000..347abc1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/nasm/nasm.vim @@ -0,0 +1,42 @@ +" Author: Oyvind Ingvaldsen +" Description: NASM linter for asmsyntax nasm. + +call ale#Set('nasm_nasm_executable', 'nasm') +call ale#Set('nasm_nasm_options', '') + +function! ale_linters#nasm#nasm#GetCommand(buffer) abort + " Note that NASM requires a trailing slash for the -I option. + let l:separator = has('win32') ? '\' : '/' + let l:path = fnamemodify(bufname(a:buffer), ':p:h') . l:separator + let l:output_null = has('win32') ? 'NUL' : '/dev/null' + + return '%e -X gnu -I ' . ale#Escape(l:path) + \ . ale#Pad(ale#Var(a:buffer, 'nasm_nasm_options')) + \ . ' %s' + \ . ' -o ' . l:output_null +endfunction + +function! ale_linters#nasm#nasm#Handle(buffer, lines) abort + " Note that we treat 'fatal' as errors. + let l:pattern = '^.\+:\(\d\+\): \([^:]\+\): \(.\+\)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'type': l:match[2] =~? 'error\|fatal' ? 'E' : 'W', + \ 'text': l:match[3], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('nasm', { +\ 'name': 'nasm', +\ 'output_stream': 'stderr', +\ 'lint_file': 1, +\ 'executable': {b -> ale#Var(b, 'nasm_nasm_executable')}, +\ 'command': function('ale_linters#nasm#nasm#GetCommand'), +\ 'callback': 'ale_linters#nasm#nasm#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/nim/nimcheck.vim b/pack/acp/start/ale/ale_linters/nim/nimcheck.vim new file mode 100644 index 0000000..b5796dc --- /dev/null +++ b/pack/acp/start/ale/ale_linters/nim/nimcheck.vim @@ -0,0 +1,65 @@ +" 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:item = { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[4], + \ 'type': 'W', + \} + + " Extract error type from message of type 'Error: Some error message' + let l:error_match = matchlist(l:item.text, '^\(.\{-}\): \(.\+\)$') + + if !empty(l:error_match) + if l:error_match[1] is# 'Error' + let l:item.type = 'E' + let l:item.text = l:error_match[2] + elseif l:error_match[1] is# 'Warning' + \|| l:error_match[1] is# 'Hint' + let l:item.text = l:error_match[2] + endif + endif + + let l:code_match = matchlist(l:item.text, '\v^(.+) \[([^ \[]+)\]$') + + if !empty(l:code_match) + let l:item.text = l:code_match[1] + let l:item.code = l:code_match[2] + endif + + call add(l:output, l:item) + 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': function('ale_linters#nim#nimcheck#GetCommand'), +\ 'callback': 'ale_linters#nim#nimcheck#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/nix/nix.vim b/pack/acp/start/ale/ale_linters/nix/nix.vim new file mode 100644 index 0000000..0a0c5c3 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/nroff/alex.vim b/pack/acp/start/ale/ale_linters/nroff/alex.vim new file mode 100644 index 0000000..3f06af2 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/nroff/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for nroff files + +call ale#handlers#alex#DefineLinter('nroff', '--text') diff --git a/pack/acp/start/ale/ale_linters/nroff/proselint.vim b/pack/acp/start/ale/ale_linters/nroff/proselint.vim new file mode 100644 index 0000000..a23e56b --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/nroff/writegood.vim b/pack/acp/start/ale/ale_linters/nroff/writegood.vim new file mode 100644 index 0000000..bcf344f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/nroff/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for nroff files + +call ale#handlers#writegood#DefineLinter('nroff') diff --git a/pack/acp/start/ale/ale_linters/objc/ccls.vim b/pack/acp/start/ale/ale_linters/objc/ccls.vim new file mode 100644 index 0000000..51ecf05 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/objc/ccls.vim @@ -0,0 +1,14 @@ +" Author: Ye Jingchen , Ben Falconer , jtalowell +" Description: A language server for Objective-C + +call ale#Set('objc_ccls_executable', 'ccls') +call ale#Set('objc_ccls_init_options', {}) + +call ale#linter#Define('objc', { +\ 'name': 'ccls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'objc_ccls_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale#handlers#ccls#GetProjectRoot'), +\ 'initialization_options': {b -> ale#Var(b, 'objc_ccls_init_options')}, +\}) diff --git a/pack/acp/start/ale/ale_linters/objc/clang.vim b/pack/acp/start/ale/ale_linters/objc/clang.vim new file mode 100644 index 0000000..7873dcc --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#objc#clang#GetCommand'), +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/pack/acp/start/ale/ale_linters/objc/clangd.vim b/pack/acp/start/ale/ale_linters/objc/clangd.vim new file mode 100644 index 0000000..318d85b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/objc/clangd.vim @@ -0,0 +1,17 @@ +" Author: Andrey Melentyev +" Description: Clangd language server + +call ale#Set('objc_clangd_executable', 'clangd') +call ale#Set('objc_clangd_options', '') + +function! ale_linters#objc#clangd#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options')) +endfunction + +call ale#linter#Define('objc', { +\ 'name': 'clangd', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'objc_clangd_executable')}, +\ 'command': function('ale_linters#objc#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/objcpp/clang.vim b/pack/acp/start/ale/ale_linters/objcpp/clang.vim new file mode 100644 index 0000000..4dbe55b --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#objcpp#clang#GetCommand'), +\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', +\}) diff --git a/pack/acp/start/ale/ale_linters/objcpp/clangd.vim b/pack/acp/start/ale/ale_linters/objcpp/clangd.vim new file mode 100644 index 0000000..2945532 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/objcpp/clangd.vim @@ -0,0 +1,17 @@ +" Author: Andrey Melentyev +" Description: Clangd language server + +call ale#Set('objcpp_clangd_executable', 'clangd') +call ale#Set('objcpp_clangd_options', '') + +function! ale_linters#objcpp#clangd#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options')) +endfunction + +call ale#linter#Define('objcpp', { +\ 'name': 'clangd', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')}, +\ 'command': function('ale_linters#objcpp#clangd#GetCommand'), +\ 'project_root': function('ale#c#FindProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/ocaml/merlin.vim b/pack/acp/start/ale/ale_linters/ocaml/merlin.vim new file mode 100644 index 0000000..cfec996 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/ocaml/ols.vim b/pack/acp/start/ale/ale_linters/ocaml/ols.vim new file mode 100644 index 0000000..d8208c5 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ocaml/ols.vim @@ -0,0 +1,14 @@ +" Author: Michael Jungo +" Description: A language server for OCaml + +call ale#Set('ocaml_ols_executable', 'ocaml-language-server') +call ale#Set('ocaml_ols_use_global', get(g:, 'ale_use_global_executables', 0)) + +call ale#linter#Define('ocaml', { +\ 'name': 'ols', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#ols#GetExecutable'), +\ 'command': function('ale#handlers#ols#GetCommand'), +\ 'language_callback': 'ale#handlers#ols#GetLanguage', +\ 'project_root': function('ale#handlers#ols#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/perl/perl.vim b/pack/acp/start/ale/ale_linters/perl/perl.vim new file mode 100644 index 0000000..0f06528 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/perl/perl.vim @@ -0,0 +1,64 @@ +" Author: Vincent Lequertier +" Description: This file adds support for checking perl syntax + +call ale#Set('perl_perl_executable', 'perl') +call ale#Set('perl_perl_options', '-c -Mwarnings -Ilib') + +function! ale_linters#perl#perl#GetCommand(buffer) abort + return '%e' . ale#Pad(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 + if empty(a:lines) + return [] + endif + + let l:pattern = '\(..\{-}\) at \(..\{-}\) line \(\d\+\)' + let l:output = [] + let l:basename = expand('#' . a:buffer . ':t') + + let l:type = 'E' + + if a:lines[-1] =~# 'syntax OK' + let l:type = 'W' + endif + + let l:seen = {} + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:line = l:match[3] + let l:file = l:match[2] + let l:text = l:match[1] + + if ale#path#IsBufferPath(a:buffer, l:file) + \ && !has_key(l:seen,l:line) + \ && ( + \ 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, + \}) + + let l:seen[l:line] = 1 + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('perl', { +\ 'name': 'perl', +\ 'executable': {b -> ale#Var(b, 'perl_perl_executable')}, +\ 'output_stream': 'both', +\ 'command': function('ale_linters#perl#perl#GetCommand'), +\ 'callback': 'ale_linters#perl#perl#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/perl/perlcritic.vim b/pack/acp/start/ale/ale_linters/perl/perlcritic.vim new file mode 100644 index 0000000..f3154c0 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/perl/perlcritic.vim @@ -0,0 +1,61 @@ +" Author: Vincent Lequertier , Chris Weyl +" Description: This file adds support for checking perl with perl critic + +call ale#Set('perl_perlcritic_executable', 'perlcritic') +call ale#Set('perl_perlcritic_profile', '.perlcriticrc') +call ale#Set('perl_perlcritic_options', '') +call ale#Set('perl_perlcritic_showrules', 0) + +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') + + return '%e' + \ . ' --verbose ' . ale#Escape(l:critic_verbosity) + \ . ' --nocolor' + \ . (!empty(l:profile) ? ' --profile ' . ale#Escape(l:profile) : '') + \ . ale#Pad(l:options) +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], + \ 'type': 'W' + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('perl', { +\ 'name': 'perlcritic', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'perl_perlcritic_executable')}, +\ 'command': function('ale_linters#perl#perlcritic#GetCommand'), +\ 'callback': 'ale_linters#perl#perlcritic#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/perl6/perl6.vim b/pack/acp/start/ale/ale_linters/perl6/perl6.vim new file mode 100644 index 0000000..68ef476 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/perl6/perl6.vim @@ -0,0 +1,166 @@ +" Author:Travis Gibson +" Description: This file adds support for checking perl6 syntax + +let g:ale_perl6_perl6_executable = +\ get(g:, 'ale_perl6_perl6_executable', 'perl6') + +let g:ale_perl6_perl6_options = +\ get(g:, 'ale_perl6_perl6_options', '-c -Ilib') + +let $PERL6_EXCEPTIONS_HANDLER = 'JSON' + +let $RAKUDO_ERROR_COLOR = 0 + +function! ale_linters#perl6#perl6#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'perl6_perl6_executable') +endfunction + +function! ale_linters#perl6#perl6#GetCommand(buffer) abort + return ale_linters#perl6#perl6#GetExecutable(a:buffer) + \ . ' ' . ale#Var(a:buffer, 'perl6_perl6_options') + \ . ' %t' +endfunction + +function! ale_linters#perl6#perl6#ExtractError(dict, item, type, buffer) abort + let l:file = '' + let l:line = 1 + let l:column = '' + let l:text = '' + let l:pre = '' + let l:counter = 2 + let l:end_line = '' + let l:linepatternmessage = 'at\s\+line\s\+\(\d\+\)' + + if has_key(a:dict[a:item], 'filename') && !empty(a:dict[a:item]['filename']) + let l:file = a:dict[a:item]['filename'] + endif + + if has_key(a:dict[a:item], 'line') && !empty(a:dict[a:item]['line']) + let l:line = a:dict[a:item]['line'] + let l:counter -= 1 + endif + + if has_key(a:dict[a:item], 'column') && !empty(a:dict[a:item]['column']) + let l:column = a:dict[a:item]['column'] + endif + + if has_key(a:dict[a:item], 'message') && !empty(a:dict[a:item]['message']) + let l:text = substitute(a:dict[a:item]['message'], '\s*\n\s*', ' ', 'g') + let l:counter -= 1 + endif + + if has_key(a:dict[a:item], 'line-real') && !empty(a:dict[a:item]['line-real']) + let l:end_line = l:line + let l:line = a:dict[a:item]['line-real'] + endif + + for l:match in ale#util#GetMatches(l:text, l:linepatternmessage) + let l:line = l:match[1] + let l:counter -= 1 + endfor + +" Currently, filenames and line numbers are not always given in the error output + if l:counter < 2 + \&& ( ale#path#IsBufferPath(a:buffer, l:file) || l:file is# '' ) + return { + \ 'lnum': '' . l:line, + \ 'text': l:text, + \ 'type': a:type, + \ 'col': l:column, + \ 'end_lnum': l:end_line, + \ 'code': a:item, + \} + endif + + return '' +endfunction + +function! ale_linters#perl6#perl6#Handle(buffer, lines) abort + let l:output = [] + + if empty(a:lines) + return l:output + endif + + if a:lines[0] is# 'Syntax OK' + return l:output + endif + + try + let l:json = json_decode(join(a:lines, '')) + catch /E474/ + call add(l:output, { + \ 'lnum': '1', + \ 'text': 'Received output in the default Perl6 error format. See :ALEDetail for details', + \ 'detail': join(a:lines, "\n"), + \ 'type': 'W', + \ }) + + return l:output + endtry + + if type(l:json) is v:t_dict + for l:key in keys(l:json) + if has_key(l:json[l:key], 'sorrows') + \&& has_key(l:json[l:key], 'worries') + if !empty(l:json[l:key]['sorrows']) + for l:dictionary in get(l:json[l:key], 'sorrows') + for l:item in keys(l:dictionary) + let l:result = + \ ale_linters#perl6#perl6#ExtractError( + \ l:dictionary, + \ l:item, + \ 'E', + \ a:buffer, + \ ) + + if l:result isnot# '' + call add(l:output, l:result) + endif + endfor + endfor + endif + + if !empty(l:json[l:key]['worries']) + for l:dictionary in get(l:json[l:key], 'worries') + for l:item in keys(l:dictionary) + let l:result = + \ ale_linters#perl6#perl6#ExtractError( + \ l:dictionary, + \ l:item, + \ 'W', + \ a:buffer, + \ ) + + if l:result isnot# '' + call add(l:output, l:result) + endif + endfor + endfor + endif + else + let l:result = ale_linters#perl6#perl6#ExtractError( + \ l:json, + \ l:key, + \ 'E', + \ a:buffer, + \ ) + + if l:result isnot# '' + call add(l:output, l:result) + endif + endif + endfor + endif + + return l:output +endfunction + +call ale#linter#Define('perl6', { +\ 'name': 'perl6', +\ 'executable': function('ale_linters#perl6#perl6#GetExecutable'), +\ 'output_stream': 'both', +\ 'command': function('ale_linters#perl6#perl6#GetCommand'), +\ 'callback': 'ale_linters#perl6#perl6#Handle', +\}) + diff --git a/pack/acp/start/ale/ale_linters/php/langserver.vim b/pack/acp/start/ale/ale_linters/php/langserver.vim new file mode 100644 index 0000000..fdd1bf2 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/php/langserver.vim @@ -0,0 +1,27 @@ +" 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', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#php#langserver#GetProjectRoot(buffer) abort + let l:composer_path = ale#path#FindNearestFile(a:buffer, 'composer.json') + + if (!empty(l:composer_path)) + return fnamemodify(l:composer_path, ':h') + endif + + 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': {b -> ale#node#FindExecutable(b, 'php_langserver', [ +\ 'vendor/bin/php-language-server.php', +\ ])}, +\ 'command': 'php %e', +\ 'project_root': function('ale_linters#php#langserver#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/php/phan.vim b/pack/acp/start/ale/ale_linters/php/phan.vim new file mode 100644 index 0000000..53cb1ea --- /dev/null +++ b/pack/acp/start/ale/ale_linters/php/phan.vim @@ -0,0 +1,73 @@ +" Author: diegoholiveira , haginaga +" Description: static analyzer for PHP + +" Define the minimum severity +let g:ale_php_phan_minimum_severity = get(g:, 'ale_php_phan_minimum_severity', 0) + +let g:ale_php_phan_executable = get(g:, 'ale_php_phan_executable', 'phan') +let g:ale_php_phan_use_client = get(g:, 'ale_php_phan_use_client', 0) + +function! ale_linters#php#phan#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'php_phan_executable') + + if ale#Var(a:buffer, 'php_phan_use_client') == 1 && l:executable is# 'phan' + let l:executable = 'phan_client' + endif + + return l:executable +endfunction + +function! ale_linters#php#phan#GetCommand(buffer) abort + if ale#Var(a:buffer, 'php_phan_use_client') == 1 + let l:args = '-l ' + \ . ' %s' + else + let l:args = '-y ' + \ . ale#Var(a:buffer, 'php_phan_minimum_severity') + \ . ' %s' + endif + + let l:executable = ale_linters#php#phan#GetExecutable(a:buffer) + + return ale#Escape(l:executable) . ' ' . l:args +endfunction + +function! ale_linters#php#phan#Handle(buffer, lines) abort + " Matches against lines like the following: + if ale#Var(a:buffer, 'php_phan_use_client') == 1 + " Phan error: ERRORTYPE: message in /path/to/some-filename.php on line nnn + let l:pattern = '^Phan error: \(\w\+\): \(.\+\) in \(.\+\) on line \(\d\+\)$' + else + " /path/to/some-filename.php:18 ERRORTYPE message + let l:pattern = '^.*:\(\d\+\)\s\(\w\+\)\s\(.\+\)$' + endif + + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + if ale#Var(a:buffer, 'php_phan_use_client') == 1 + let l:dict = { + \ 'lnum': l:match[4] + 0, + \ 'text': l:match[2], + \ 'type': 'W', + \} + else + let l:dict = { + \ 'lnum': l:match[1] + 0, + \ 'text': l:match[3], + \ 'type': 'W', + \} + endif + + call add(l:output, l:dict) + endfor + + return l:output +endfunction + +call ale#linter#Define('php', { +\ 'name': 'phan', +\ 'executable': function('ale_linters#php#phan#GetExecutable'), +\ 'command': function('ale_linters#php#phan#GetCommand'), +\ 'callback': 'ale_linters#php#phan#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/php/php.vim b/pack/acp/start/ale/ale_linters/php/php.vim new file mode 100644 index 0000000..51a109b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/php/php.vim @@ -0,0 +1,39 @@ +" Author: Spencer Wood , Adriaan Zonnenberg +" Description: This file adds support for checking PHP with php-cli + +call ale#Set('php_php_executable', 'php') + +function! ale_linters#php#php#Handle(buffer, lines) abort + " Matches patterns like the following: + " + " PHP 7.1<= - Parse error: syntax error, unexpected ';', expecting ']' in - on line 15 + " PHP 7.2>= - Parse error: syntax error, unexpected ';', expecting ']' in Standard input code on line 15 + let l:pattern = '\v^%(Fatal|Parse) error:\s+(.+unexpected ''(.+)%(expecting.+)@ ale#Var(b, 'php_php_executable')}, +\ 'output_stream': 'stdout', +\ 'command': '%e -l -d error_reporting=E_ALL -d display_errors=1 -d log_errors=0 --', +\ 'callback': 'ale_linters#php#php#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/php/phpcs.vim b/pack/acp/start/ale/ale_linters/php/phpcs.vim new file mode 100644 index 0000000..11b81e8 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/php/phpcs.vim @@ -0,0 +1,54 @@ +" Author: jwilliams108 , Eric Stern +" Description: phpcs for PHP files + +let g:ale_php_phpcs_standard = get(g:, 'ale_php_phpcs_standard', '') + +call ale#Set('php_phpcs_options', '') +call ale#Set('php_phpcs_executable', 'phpcs') +call ale#Set('php_phpcs_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#php#phpcs#GetCommand(buffer) abort + let l:standard = ale#Var(a:buffer, 'php_phpcs_standard') + let l:standard_option = !empty(l:standard) + \ ? '--standard=' . ale#Escape(l:standard) + \ : '' + + return ale#path#BufferCdString(a:buffer) + \ . '%e -s --report=emacs --stdin-path=%s' + \ . ale#Pad(l:standard_option) + \ . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options')) +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:code = l:match[5] + let l:text = l:match[4] . ' (' . l:code . ')' + 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', + \ 'sub_type': 'style', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('php', { +\ 'name': 'phpcs', +\ 'executable': {b -> ale#node#FindExecutable(b, 'php_phpcs', [ +\ 'vendor/bin/phpcs', +\ 'phpcs' +\ ])}, +\ 'command': function('ale_linters#php#phpcs#GetCommand'), +\ 'callback': 'ale_linters#php#phpcs#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/php/phpmd.vim b/pack/acp/start/ale/ale_linters/php/phpmd.vim new file mode 100644 index 0000000..9b1d1e4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/php/phpmd.vim @@ -0,0 +1,38 @@ +" Author: medains , David Sierra +" Description: phpmd for PHP files + +let g:ale_php_phpmd_executable = get(g:, 'ale_php_phpmd_executable', 'phpmd') + +" 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 '%e %s text' + \ . ale#Pad(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\+\)\s\+\(.\+\)$' + 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': {b -> ale#Var(b, 'php_phpmd_executable')}, +\ 'command': function('ale_linters#php#phpmd#GetCommand'), +\ 'callback': 'ale_linters#php#phpmd#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/php/phpstan.vim b/pack/acp/start/ale/ale_linters/php/phpstan.vim new file mode 100644 index 0000000..78f7dd1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/php/phpstan.vim @@ -0,0 +1,74 @@ +" 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', '') +let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '') +let g:ale_php_phpstan_autoload = get(g:, 'ale_php_phpstan_autoload', '') + +function! ale_linters#php#phpstan#GetCommand(buffer, version) abort + let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration') + let l:configuration_option = !empty(l:configuration) + \ ? ' -c ' . ale#Escape(l:configuration) + \ : '' + + let l:autoload = ale#Var(a:buffer, 'php_phpstan_autoload') + let l:autoload_option = !empty(l:autoload) + \ ? ' -a ' . ale#Escape(l:autoload) + \ : '' + + let l:level = ale#Var(a:buffer, 'php_phpstan_level') + let l:config_file_exists = ale#path#FindNearestFile(a:buffer, 'phpstan.neon') + + if empty(l:level) && empty(l:config_file_exists) + " if no configuration file is found, then use 4 as a default level + let l:level = '4' + endif + + let l:level_option = !empty(l:level) + \ ? ' -l ' . ale#Escape(l:level) + \ : '' + + let l:error_format = ale#semver#GTE(a:version, [0, 10, 3]) + \ ? ' --error-format raw' + \ : ' --errorFormat raw' + + return '%e analyze --no-progress' + \ . l:error_format + \ . l:configuration_option + \ . l:autoload_option + \ . l:level_option + \ . ' %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': 'E', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('php', { +\ 'name': 'phpstan', +\ 'executable': {b -> ale#Var(b, 'php_phpstan_executable')}, +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale#Var(buffer, 'php_phpstan_executable'), +\ '%e --version', +\ function('ale_linters#php#phpstan#GetCommand'), +\ )}, +\ 'callback': 'ale_linters#php#phpstan#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/php/psalm.vim b/pack/acp/start/ale/ale_linters/php/psalm.vim new file mode 100644 index 0000000..3cdb026 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/php/psalm.vim @@ -0,0 +1,21 @@ +" Author: Matt Brown +" Description: plugin for Psalm, static analyzer for PHP + +call ale#Set('psalm_langserver_executable', 'psalm-language-server') +call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#php#psalm#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': 'psalm', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#node#FindExecutable(b, 'psalm_langserver', [ +\ 'vendor/bin/psalm-language-server', +\ ])}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#php#psalm#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/po/alex.vim b/pack/acp/start/ale/ale_linters/po/alex.vim new file mode 100644 index 0000000..05c67f1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/po/alex.vim @@ -0,0 +1,4 @@ +" Author: Cian Butler https://github.com/butlerx +" Description: alex for PO files + +call ale#handlers#alex#DefineLinter('po', '--text') diff --git a/pack/acp/start/ale/ale_linters/po/msgfmt.vim b/pack/acp/start/ale/ale_linters/po/msgfmt.vim new file mode 100644 index 0000000..8279ccd --- /dev/null +++ b/pack/acp/start/ale/ale_linters/po/msgfmt.vim @@ -0,0 +1,30 @@ +" Author: Cian Butler https://github.com/butlerx +" Description: msgfmt for PO files + +function! ale_linters#po#msgfmt#Handle(buffer, lines) abort + let l:results = ale#handlers#unix#HandleAsWarning(a:buffer, a:lines) + let l:index = 0 + + for l:item in l:results + if l:index > 0 && l:item.text =~? 'this is the location of the first definition' + let l:last_item = l:results[l:index - 1] + + if l:last_item.text =~? 'duplicate message definition' + let l:last_item.text = 'duplicate of message at line ' . l:item.lnum + let l:item.text = 'first location of duplicate of message at line ' . l:last_item.lnum + endif + endif + + let l:index += 1 + endfor + + return l:results +endfunction + +call ale#linter#Define('po', { +\ 'name': 'msgfmt', +\ 'executable': 'msgfmt', +\ 'output_stream': 'stderr', +\ 'command': 'msgfmt --statistics --output-file=- %t', +\ 'callback': 'ale_linters#po#msgfmt#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/po/proselint.vim b/pack/acp/start/ale/ale_linters/po/proselint.vim new file mode 100644 index 0000000..ce13250 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/po/proselint.vim @@ -0,0 +1,9 @@ +" Author: Cian Butler https://github.com/butlerx +" Description: proselint for PO files + +call ale#linter#Define('po', { +\ 'name': 'proselint', +\ 'executable': 'proselint', +\ 'command': 'proselint %t', +\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\}) diff --git a/pack/acp/start/ale/ale_linters/po/writegood.vim b/pack/acp/start/ale/ale_linters/po/writegood.vim new file mode 100644 index 0000000..1468647 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/po/writegood.vim @@ -0,0 +1,4 @@ +" Author: Cian Butler https://github.com/butlerx +" Description: write-good for PO files + +call ale#handlers#writegood#DefineLinter('po') diff --git a/pack/acp/start/ale/ale_linters/pod/alex.vim b/pack/acp/start/ale/ale_linters/pod/alex.vim new file mode 100644 index 0000000..c89f833 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/pod/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for pod files + +call ale#handlers#alex#DefineLinter('pod', '--text') diff --git a/pack/acp/start/ale/ale_linters/pod/proselint.vim b/pack/acp/start/ale/ale_linters/pod/proselint.vim new file mode 100644 index 0000000..2eb83f5 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/pod/writegood.vim b/pack/acp/start/ale/ale_linters/pod/writegood.vim new file mode 100644 index 0000000..9f5461e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/pod/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for Pod files + +call ale#handlers#writegood#DefineLinter('pod') diff --git a/pack/acp/start/ale/ale_linters/pony/ponyc.vim b/pack/acp/start/ale/ale_linters/pony/ponyc.vim new file mode 100644 index 0000000..6d4594f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/pony/ponyc.vim @@ -0,0 +1,16 @@ +" Description: ponyc linter for pony files + +call ale#Set('pony_ponyc_executable', 'ponyc') +call ale#Set('pony_ponyc_options', '--pass paint') + +function! ale_linters#pony#ponyc#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'pony_ponyc_options')) +endfunction + +call ale#linter#Define('pony', { +\ 'name': 'ponyc', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'pony_ponyc_executable')}, +\ 'command': function('ale_linters#pony#ponyc#GetCommand'), +\ 'callback': 'ale#handlers#pony#HandlePonycFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/powershell/powershell.vim b/pack/acp/start/ale/ale_linters/powershell/powershell.vim new file mode 100755 index 0000000..51ded71 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/powershell/powershell.vim @@ -0,0 +1,91 @@ +" Author: Jesse Harris - https://github.com/zigford +" Description: This file adds support for powershell scripts synatax errors + +call ale#Set('powershell_powershell_executable', 'pwsh') + +function! ale_linters#powershell#powershell#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'powershell_powershell_executable') +endfunction + +" Some powershell magic to show syntax errors without executing the script +" thanks to keith hill: +" https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/ +function! ale_linters#powershell#powershell#GetCommand(buffer) abort + let l:script = ['Param($Script); + \ trap {$_;continue} & { + \ $Contents = Get-Content -Path $Script; + \ $Contents = [string]::Join([Environment]::NewLine, $Contents); + \ [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Contents); + \ };'] + + return ale#powershell#RunPowerShell( + \ a:buffer, 'powershell_powershell', l:script) +endfunction + +" Parse powershell error output using regex into a list of dicts +function! ale_linters#powershell#powershell#Handle(buffer, lines) abort + let l:output = [] + " Our 3 patterns we need to scrape the data for the dicts + let l:patterns = [ + \ '\v^At line:(\d+) char:(\d+)', + \ '\v^(At|\+| )@!.*', + \ '\vFullyQualifiedErrorId : (\w+)', + \] + + let l:matchcount = 0 + + for l:match in ale#util#GetMatches(a:lines, l:patterns) + " We want to work with 3 matches per syntax error + let l:matchcount = l:matchcount + 1 + + if l:matchcount == 1 || str2nr(l:match[1]) + " First match consists of 2 capture groups, and + " can capture the line and col + if exists('l:item') + " We may be here because the last syntax + " didn't emit a code, and so only had 2 + " matches + call add(l:output, l:item) + let l:matchcount = 1 + endif + + let l:item = { + \ 'lnum': str2nr(l:match[1]), + \ 'col': str2nr(l:match[2]), + \ 'type': 'E', + \} + elseif l:matchcount == 2 + " Second match[0] grabs the full line in order + " to handles the text + let l:item['text'] = l:match[0] + else + " Final match handles the code, however + " powershell only emits 1 code for all errors + " so, we get the final code on the last error + " and loop over the previously added items to + " append the code we now know + call add(l:output, l:item) + unlet l:item + + if len(l:match[1]) > 0 + for l:i in l:output + let l:i['code'] = l:match[1] + endfor + endif + + " Reset the matchcount so we can begin gathering + " matches for the next syntax error + let l:matchcount = 0 + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('powershell', { +\ 'name': 'powershell', +\ 'executable_callback': 'ale_linters#powershell#powershell#GetExecutable', +\ 'command_callback': 'ale_linters#powershell#powershell#GetCommand', +\ 'output_stream': 'stdout', +\ 'callback': 'ale_linters#powershell#powershell#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/powershell/psscriptanalyzer.vim b/pack/acp/start/ale/ale_linters/powershell/psscriptanalyzer.vim new file mode 100644 index 0000000..4794d9d --- /dev/null +++ b/pack/acp/start/ale/ale_linters/powershell/psscriptanalyzer.vim @@ -0,0 +1,76 @@ +" Author: Jesse Harris - https://github.com/zigford +" Description: This file adds support for lintng powershell scripts +" using the PSScriptAnalyzer module. + +" let g:ale_powershell_psscriptanalyzer_exclusions = +" \ 'PSAvoidUsingWriteHost,PSAvoidGlobalVars' +call ale#Set('powershell_psscriptanalyzer_exclusions', '') +call ale#Set('powershell_psscriptanalyzer_executable', 'pwsh') +call ale#Set('powershell_psscriptanalyzer_module', +\ 'psscriptanalyzer') + +function! ale_linters#powershell#psscriptanalyzer#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'powershell_psscriptanalyzer_executable') +endfunction + +" Run Invoke-ScriptAnalyzer and output each linting message as 4 seperate lines +" for each parsing +function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort + let l:exclude_option = ale#Var( + \ a:buffer, 'powershell_psscriptanalyzer_exclusions') + let l:module = ale#Var( + \ a:buffer, 'powershell_psscriptanalyzer_module') + let l:script = ['Param($Script); + \ Invoke-ScriptAnalyzer "$Script" ' + \ . (!empty(l:exclude_option) ? '-Exclude ' . l:exclude_option : '') + \ . '| ForEach-Object { + \ $_.Line; + \ $_.Severity; + \ $_.Message; + \ $_.RuleName}'] + + return ale#powershell#RunPowerShell( + \ a:buffer, + \ 'powershell_psscriptanalyzer', + \ l:script) +endfunction + +" add every 4 lines to an item(Dict) and every item to a list +" return the list +function! ale_linters#powershell#psscriptanalyzer#Handle(buffer, lines) abort + let l:output = [] + let l:lcount = 0 + + for l:line in a:lines + if l:lcount is# 0 + " the very first line + let l:item = {'lnum': str2nr(l:line)} + elseif l:lcount is# 1 + if l:line is# 'Error' + let l:item['type'] = 'E' + elseif l:line is# 'Information' + let l:item['type'] = 'I' + else + let l:item['type'] = 'W' + endif + elseif l:lcount is# 2 + let l:item['text'] = l:line + elseif l:lcount is# 3 + let l:item['code'] = l:line + call add(l:output, l:item) + let l:lcount = -1 + endif + + let l:lcount = l:lcount + 1 + endfor + + return l:output +endfunction + +call ale#linter#Define('powershell', { +\ 'name': 'psscriptanalyzer', +\ 'executable': function('ale_linters#powershell#psscriptanalyzer#GetExecutable'), +\ 'command': function('ale_linters#powershell#psscriptanalyzer#GetCommand'), +\ 'output_stream': 'stdout', +\ 'callback': 'ale_linters#powershell#psscriptanalyzer#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/prolog/swipl.vim b/pack/acp/start/ale/ale_linters/prolog/swipl.vim new file mode 100644 index 0000000..5c601c4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/prolog/swipl.vim @@ -0,0 +1,100 @@ +" Author: Takuya Fujiwara +" Description: swipl syntax / semantic check for Prolog files + +call ale#Set('prolog_swipl_executable', 'swipl') +call ale#Set('prolog_swipl_load', 'current_prolog_flag(argv, [File]), load_files(File, [sandboxed(true)]), halt.') +call ale#Set('prolog_swipl_timeout', 3) +call ale#Set('prolog_swipl_alarm', 'alarm(%t, (%h), _, [])') +call ale#Set('prolog_swipl_alarm_handler', 'writeln(user_error, "ERROR: Exceeded %t seconds, Please change g:prolog_swipl_timeout to modify the limit."), halt(1)') + +function! ale_linters#prolog#swipl#GetCommand(buffer) abort + let l:goals = ale#Var(a:buffer, 'prolog_swipl_load') + let l:goals = l:goals =~# '^\s*$' ? 'halt' : l:goals + let l:timeout = ale#Var(a:buffer, 'prolog_swipl_timeout') + 0 + + if l:timeout > 0 + let l:goals = s:GetAlarm(a:buffer, l:timeout) . ', ' . l:goals + endif + + return '%e -g ' . ale#Escape(l:goals) . ' -- %s' +endfunction + +function! s:GetAlarm(buffer, timeout) abort + let l:handler = ale#Var(a:buffer, 'prolog_swipl_alarm_handler') + let l:handler = s:Subst(l:handler, {'t': a:timeout}) + let l:alarm = ale#Var(a:buffer, 'prolog_swipl_alarm') + let l:alarm = s:Subst(l:alarm, {'t': a:timeout, 'h': l:handler}) + + return l:alarm +endfunction + +function! s:Subst(format, vars) abort + let l:vars = extend(copy(a:vars), {'%': '%'}) + + return substitute(a:format, '%\(.\)', '\=get(l:vars, submatch(1), "")', 'g') +endfunction + +function! ale_linters#prolog#swipl#Handle(buffer, lines) abort + let l:pattern = '\v^(ERROR|Warning)+%(:\s*[^:]+:(\d+)%(:(\d+))?)?:\s*(.*)$' + let l:output = [] + let l:i = 0 + + while l:i < len(a:lines) + let l:match = matchlist(a:lines[l:i], l:pattern) + + if empty(l:match) + let l:i += 1 + continue + endif + + let [l:i, l:text] = s:GetErrMsg(l:i, a:lines, l:match[4]) + let l:item = { + \ 'lnum': (l:match[2] + 0 ? l:match[2] + 0 : 1), + \ 'col': l:match[3] + 0, + \ 'text': l:text, + \ 'type': (l:match[1] is# 'ERROR' ? 'E' : 'W'), + \} + + if !s:Ignore(l:item) + call add(l:output, l:item) + endif + endwhile + + return l:output +endfunction + +" This returns [, ] +function! s:GetErrMsg(i, lines, text) abort + if a:text !~# '^\s*$' + return [a:i + 1, a:text] + endif + + let l:i = a:i + 1 + let l:text = [] + + while l:i < len(a:lines) && a:lines[l:i] =~# '^\s' + call add(l:text, s:Trim(a:lines[l:i])) + let l:i += 1 + endwhile + + return [l:i, join(l:text, '. ')] +endfunction + +function! s:Trim(str) abort + return substitute(a:str, '\v^\s+|\s+$', '', 'g') +endfunction + +" Skip sandbox error which is caused by directives +" because what we want is syntactic or semantic check. +function! s:Ignore(item) abort + return a:item.type is# 'E' + \ && a:item.text =~# '\vNo permission to (call|directive|assert) sandboxed' +endfunction + +call ale#linter#Define('prolog', { +\ 'name': 'swipl', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'prolog_swipl_executable')}, +\ 'command': function('ale_linters#prolog#swipl#GetCommand'), +\ 'callback': 'ale_linters#prolog#swipl#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/proto/protoc_gen_lint.vim b/pack/acp/start/ale/ale_linters/proto/protoc_gen_lint.vim new file mode 100644 index 0000000..c3d1093 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/proto/protoc_gen_lint.vim @@ -0,0 +1,27 @@ +" Author: Jeff Willette +" Description: run the protoc-gen-lint plugin for the protoc binary + +call ale#Set('proto_protoc_gen_lint_options', '') + +function! ale_linters#proto#protoc_gen_lint#GetCommand(buffer) abort + let l:dirname = expand('#' . a:buffer . ':p:h') + + let l:options = ['-I ' . ale#Escape(l:dirname)] + + if !empty(ale#Var(a:buffer, 'proto_protoc_gen_lint_options')) + let l:options += [ale#Var(a:buffer, 'proto_protoc_gen_lint_options')] + endif + + let l:options += ['--lint_out=. ' . '%s'] + + return 'protoc' . ' ' . join(l:options) +endfunction + +call ale#linter#Define('proto', { +\ 'name': 'protoc-gen-lint', +\ 'lint_file': 1, +\ 'output_stream': 'stderr', +\ 'executable': 'protoc', +\ 'command': function('ale_linters#proto#protoc_gen_lint#GetCommand'), +\ 'callback': 'ale#handlers#unix#HandleAsError', +\}) diff --git a/pack/acp/start/ale/ale_linters/pug/puglint.vim b/pack/acp/start/ale/ale_linters/pug/puglint.vim new file mode 100644 index 0000000..c819cc4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/pug/puglint.vim @@ -0,0 +1,56 @@ +" 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', get(g:, 'ale_use_global_executables', 0)) + +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:options = ale#Var(a:buffer, 'pug_puglint_options') + let l:config = s:FindConfig(a:buffer) + + return '%e' . ale#Pad(l:options) + \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') + \ . ' -r inline %t' +endfunction + +function! ale_linters#pug#puglint#Handle(buffer, lines) abort + for l:line in a:lines[:10] + if l:line =~# '^SyntaxError: ' + return [{ + \ 'lnum': 1, + \ 'text': 'puglint configuration error (type :ALEDetail for more information)', + \ 'detail': join(a:lines, "\n"), + \}] + endif + endfor + + return ale#handlers#unix#HandleAsError(a:buffer, a:lines) +endfunction + +call ale#linter#Define('pug', { +\ 'name': 'puglint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [ +\ 'node_modules/.bin/pug-lint', +\ ])}, +\ 'output_stream': 'stderr', +\ 'command': function('ale_linters#pug#puglint#GetCommand'), +\ 'callback': 'ale_linters#pug#puglint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/puppet/languageserver.vim b/pack/acp/start/ale/ale_linters/puppet/languageserver.vim new file mode 100644 index 0000000..2078695 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/puppet/languageserver.vim @@ -0,0 +1,37 @@ +" Author: Alexander Olofsson +" Description: Puppet Language Server integration for ALE + +call ale#Set('puppet_languageserver_executable', 'puppet-languageserver') + +function! ale_linters#puppet#languageserver#GetProjectRoot(buffer) abort + " Note: The metadata.json file is recommended for Puppet 4+ modules, but + " there's no requirement to have it, so fall back to the other possible + " Puppet module directories + let l:root_path = ale#path#FindNearestFile(a:buffer, 'metadata.json') + + if !empty(l:root_path) + return fnamemodify(l:root_path, ':h') + endif + + for l:test_path in [ + \ 'manifests', + \ 'templates', + \] + let l:root_path = ale#path#FindNearestDirectory(a:buffer, l:test_path) + + if !empty(l:root_path) + return fnamemodify(l:root_path, ':h:h') + endif + endfor + + return '' +endfunction + +call ale#linter#Define('puppet', { +\ 'name': 'languageserver', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'puppet_languageserver_executable')}, +\ 'command': '%e --stdio', +\ 'language': 'puppet', +\ 'project_root': function('ale_linters#puppet#languageserver#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/puppet/puppet.vim b/pack/acp/start/ale/ale_linters/puppet/puppet.vim new file mode 100644 index 0000000..ae64861 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/puppet/puppet.vim @@ -0,0 +1,37 @@ +" Author: Alexander Olofsson + +call ale#Set('puppet_puppet_executable', 'puppet') +call ale#Set('puppet_puppet_options', '') + +function! ale_linters#puppet#puppet#Handle(buffer, lines) abort + " Matches patterns like the following: + " Error: Could not parse for environment production: Syntax error at ':' at /root/puppetcode/modules/nginx/manifests/init.pp:43:12 + " Error: Could not parse for environment production: Syntax error at '='; expected '}' at /root/puppetcode/modules/pancakes/manifests/init.pp:5" + " Error: Could not parse for environment production: Syntax error at 'parameter1' (file: /tmp/modules/mariadb/manifests/slave.pp, line: 4, column: 5) + let l:pattern = '^Error: .*: \(.\+\) \((file:\|at\) .\+\.pp\(, line: \|:\)\(\d\+\)\(, column: \|:\)\=\(\d*\)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[4] + 0, + \ 'col': l:match[6] + 0, + \ 'text': l:match[1], + \}) + endfor + + return l:output +endfunction + +function! ale_linters#puppet#puppet#GetCommand(buffer) abort + return '%e parser validate --color=false ' + \ . ale#Pad(ale#Var(a:buffer, 'puppet_puppet_options')) + \ . ' %t' +endfunction + +call ale#linter#Define('puppet', { +\ 'name': 'puppet', +\ 'executable': {b -> ale#Var(b, 'puppet_puppet_executable')}, +\ 'output_stream': 'stderr', +\ 'command': function('ale_linters#puppet#puppet#GetCommand'), +\ 'callback': 'ale_linters#puppet#puppet#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/puppet/puppetlint.vim b/pack/acp/start/ale/ale_linters/puppet/puppetlint.vim new file mode 100644 index 0000000..985d6a4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/puppet/puppetlint.vim @@ -0,0 +1,18 @@ +" Author: Alexander Olofsson , Robert Flechtner +" Description: puppet-lint for puppet files + +call ale#Set('puppet_puppetlint_executable', 'puppet-lint') +call ale#Set('puppet_puppetlint_options', '--no-autoloader_layout-check') + +function! ale_linters#puppet#puppetlint#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'puppet_puppetlint_options')) + \ . ' --log-format "-:%{line}:%{column}: %{kind}: [%{check}] %{message}"' + \ . ' %t' +endfunction + +call ale#linter#Define('puppet', { +\ 'name': 'puppetlint', +\ 'executable': {b -> ale#Var(b, 'puppet_puppetlint_executable')}, +\ 'command': function('ale_linters#puppet#puppetlint#GetCommand'), +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/pyrex/cython.vim b/pack/acp/start/ale/ale_linters/pyrex/cython.vim new file mode 100644 index 0000000..84382ba --- /dev/null +++ b/pack/acp/start/ale/ale_linters/pyrex/cython.vim @@ -0,0 +1,38 @@ +" Author: w0rp , +" Nicolas Pauss +" Description: cython syntax checking for cython files. + +call ale#Set('pyrex_cython_executable', 'cython') +call ale#Set('pyrex_cython_options', '--warning-extra') + +function! ale_linters#pyrex#cython#GetCommand(buffer) abort + let l:local_dir = ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + + return '%e --working ' . l:local_dir . ' --include-dir ' . l:local_dir + \ . ale#Pad(ale#Var(a:buffer, 'pyrex_cython_options')) + \ . ' --output-file ' . g:ale#util#nul_file . ' %t' +endfunction + +function! ale_linters#pyrex#cython#Handle(buffer, lines) abort + let l:pattern = '\v^(\w+: )?[^:]+:(\d+):?(\d+)?:? ?(.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[4], + \ 'type': l:match[1][0] is# 'w' ? 'W' : 'E', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('pyrex', { +\ 'name': 'cython', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'pyrex_cython_executable')}, +\ 'command': function('ale_linters#pyrex#cython#GetCommand'), +\ 'callback': 'ale_linters#pyrex#cython#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/python/bandit.vim b/pack/acp/start/ale/ale_linters/python/bandit.vim new file mode 100644 index 0000000..554f500 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/bandit.vim @@ -0,0 +1,68 @@ +" Author: Martino Pilia +" Description: bandit linting for python files + +call ale#Set('python_bandit_executable', 'bandit') +call ale#Set('python_bandit_options', '') +call ale#Set('python_bandit_use_config', 1) +call ale#Set('python_bandit_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_bandit_auto_pipenv', 0) + +function! ale_linters#python#bandit#GetExecutable(buffer) abort + if ( + \ ale#Var(a:buffer, 'python_auto_pipenv') + \ || ale#Var(a:buffer, 'python_bandit_auto_pipenv') + \) && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_bandit', ['bandit']) +endfunction + +function! ale_linters#python#bandit#GetCommand(buffer) abort + let l:executable = ale_linters#python#bandit#GetExecutable(a:buffer) + let l:flags = ' --format custom' + \ . ' --msg-template "{line}:{test_id}:{severity}:{msg}" ' + + if ale#Var(a:buffer, 'python_bandit_use_config') + let l:config_path = ale#path#FindNearestFile(a:buffer, '.bandit') + + if !empty(l:config_path) + let l:flags = ' --ini ' . ale#Escape(l:config_path) . l:flags + endif + endif + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run bandit' + \ : '' + + return ale#Escape(l:executable) . l:exec_args + \ . l:flags + \ . ale#Pad(ale#Var(a:buffer, 'python_bandit_options')) + \ . ' -' +endfunction + +function! ale_linters#python#bandit#Handle(buffer, lines) abort + " Custom format defined in GetCommand via --msg-template + let l:pattern = '\v^([0-9]+):(B[0-9]+):([A-Z]+):(.*)$' + let l:severity = {'LOW': 'I', 'MEDIUM': 'W', 'HIGH': 'E'} + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': str2nr(l:match[1]), + \ 'code': l:match[2], + \ 'type': l:severity[l:match[3]], + \ 'text': l:match[4], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('python', { +\ 'name': 'bandit', +\ 'executable': function('ale_linters#python#bandit#GetExecutable'), +\ 'command': function('ale_linters#python#bandit#GetCommand'), +\ 'callback': 'ale_linters#python#bandit#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/python/flake8.vim b/pack/acp/start/ale/ale_linters/python/flake8.vim new file mode 100644 index 0000000..e2e7b74 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/flake8.vim @@ -0,0 +1,146 @@ +" Author: w0rp +" Description: flake8 for python files + +call ale#Set('python_flake8_executable', 'flake8') +call ale#Set('python_flake8_options', '') +call ale#Set('python_flake8_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_flake8_change_directory', 1) +call ale#Set('python_flake8_auto_pipenv', 0) + +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 (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_flake8_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + 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#RunWithVersionCheck(buffer) abort + let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) + + let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : '' + let l:command = ale#Escape(l:executable) . l:module_string . ' --version' + + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ l:executable, + \ l:command, + \ function('ale_linters#python#flake8#GetCommand'), + \) +endfunction + +function! ale_linters#python#flake8#GetCommand(buffer, version) abort + let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory') + \ ? ale#path#BufferCdString(a:buffer) + \ : '' + let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run flake8' + \ : '' + + " Only include the --stdin-display-name argument if we can parse the + " flake8 version, and it is recent enough to support it. + let l:display_name_args = ale#semver#GTE(a:version, [3, 0, 0]) + \ ? ' --stdin-display-name %s' + \ : '' + + let l:options = ale#Var(a:buffer, 'python_flake8_options') + + return l:cd_string + \ . ale#Escape(l:executable) . l:exec_args + \ . (!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 + let l:output = ale#python#HandleTraceback(a:lines, 10) + + if !empty(l:output) + return l:output + endif + + " 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:]]+):? (.*)$' + + 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 + + if l:code is# 'W391' + \&& !ale#Var(a:buffer, 'warn_about_trailing_blank_lines') + " Skip warnings for trailing blank lines if the option is off + continue + endif + + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'vcol': 1, + \ 'text': l:match[4], + \ 'code': l:code, + \ 'type': 'W', + \} + + if l:code[:0] is# 'F' + if l:code isnot# 'F401' + let l:item.type = 'E' + endif + elseif l:code[:0] is# 'E' + let l:item.type = 'E' + + if l:code isnot# 'E999' && l:code isnot# 'E112' + let l:item.sub_type = 'style' + endif + 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': function('ale_linters#python#flake8#GetExecutable'), +\ 'command': function('ale_linters#python#flake8#RunWithVersionCheck'), +\ 'callback': 'ale_linters#python#flake8#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/python/mypy.vim b/pack/acp/start/ale/ale_linters/python/mypy.vim new file mode 100644 index 0000000..c4c6507 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/mypy.vim @@ -0,0 +1,81 @@ +" Author: Keith Smiley , w0rp +" Description: mypy support for optional python typechecking + +call ale#Set('python_mypy_executable', 'mypy') +call ale#Set('python_mypy_ignore_invalid_syntax', 0) +call ale#Set('python_mypy_options', '') +call ale#Set('python_mypy_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_mypy_auto_pipenv', 0) + +function! ale_linters#python#mypy#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_mypy_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + 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) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run mypy' + \ : '' + + " We have to always switch to an explicit directory for a command so + " we can know with certainty the base path for the 'filename' keys below. + return ale#path#CdString(l:dir) + \ . ale#Escape(l:executable) . l:exec_args + \ . ' --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) + " Skip invalid syntax errors if the option is on. + if l:match[5] is# 'invalid syntax' + \&& ale#Var(a:buffer, 'python_mypy_ignore_invalid_syntax') + continue + endif + + 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': function('ale_linters#python#mypy#GetExecutable'), +\ 'command': function('ale_linters#python#mypy#GetCommand'), +\ 'callback': 'ale_linters#python#mypy#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/python/prospector.vim b/pack/acp/start/ale/ale_linters/python/prospector.vim new file mode 100644 index 0000000..ee47012 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/prospector.vim @@ -0,0 +1,100 @@ +" Author: chocoelho +" Description: prospector linter python files + +call ale#Set('python_prospector_auto_pipenv', 0) + +let g:ale_python_prospector_executable = +\ get(g:, 'ale_python_prospector_executable', 'prospector') + +let g:ale_python_prospector_options = +\ get(g:, 'ale_python_prospector_options', '') + +let g:ale_python_prospector_use_global = get(g:, 'ale_python_prospector_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#python#prospector#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_prospector_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_prospector', ['prospector']) +endfunction + +function! ale_linters#python#prospector#GetCommand(buffer) abort + let l:executable = ale_linters#python#prospector#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run prospector' + \ : '' + + return ale#Escape(l:executable) + \ . l:exec_args + \ . ' ' . ale#Var(a:buffer, 'python_prospector_options') + \ . ' --messages-only --absolute-paths --zero-exit --output-format json' + \ . ' %s' +endfunction + +function! ale_linters#python#prospector#Handle(buffer, lines) abort + let l:output = [] + + if empty(a:lines) + return [] + endif + + let l:prospector_error = json_decode(join(a:lines, '')) + + for l:error in l:prospector_error.messages + if (l:error.code is# 'W291' || l:error.code is# 'W293' || l:error.code is# 'trailing-whitespace') + \ && !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + " Skip warnings for trailing whitespace if the option is off. + continue + endif + + if l:error.code is# 'W391' + \&& !ale#Var(a:buffer, 'warn_about_trailing_blank_lines') + " Skip warnings for trailing blank lines if the option is off + continue + endif + + if l:error.source =~# '\v\[%(dodgy|mccabe|pep8|pep257|pyroma)\]$' + let l:sub_type = 'style' + else + let l:sub_type = '' + endif + + if l:error.source =~# '\v\[pylint\]$' + let l:type = l:error.code =~? '\m^[CRW]' ? 'W' : 'E' + elseif l:error.source =~# '\v\[%(frosted|pep8)\]$' + let l:type = l:error.code =~? '\m^W' ? 'W' : 'E' + elseif l:error.source =~# '\v\[%(dodgy|pyroma|vulture)\]$' + let l:type = 'W' + else + let l:type = 'E' + endif + + let l:item = { + \ 'lnum': l:error.location.line, + \ 'col': l:error.location.character + 1, + \ 'text': l:error.message, + \ 'code': printf('(%s) %s', l:error.source, l:error.code), + \ 'type': l:type, + \ 'sub_type': l:sub_type, + \} + + if l:sub_type is# '' + unlet l:item.sub_type + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('python', { +\ 'name': 'prospector', +\ 'executable': function('ale_linters#python#prospector#GetExecutable'), +\ 'command': function('ale_linters#python#prospector#GetCommand'), +\ 'callback': 'ale_linters#python#prospector#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/python/pycodestyle.vim b/pack/acp/start/ale/ale_linters/python/pycodestyle.vim new file mode 100644 index 0000000..fb521bc --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/pycodestyle.vim @@ -0,0 +1,75 @@ +" 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', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pycodestyle_auto_pipenv', 0) + +function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pycodestyle_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pycodestyle', ['pycodestyle']) +endfunction + +function! ale_linters#python#pycodestyle#GetCommand(buffer) abort + let l:executable = ale_linters#python#pycodestyle#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pycodestyle' + \ : '' + + return ale#Escape(l:executable) . l:exec_args + \ . ' ' + \ . 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) + if(l:match[4] is# 'W291' || l:match[4] is# 'W293') + \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + " Skip warnings for trailing whitespace if the option is off. + continue + endif + + if l:match[4] is# 'W391' + \&& !ale#Var(a:buffer, 'warn_about_trailing_blank_lines') + " Skip warnings for trailing blank lines if the option is off + continue + endif + + let l:item = { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'type': l:match[4][0], + \ 'sub_type': 'style', + \ 'text': l:match[5], + \ 'code': l:match[4], + \} + + " E999 and E112 are syntax errors. + if l:match[4] is# 'E999' || l:match[4] is# 'E112' + unlet l:item.sub_type + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pycodestyle', +\ 'executable': function('ale_linters#python#pycodestyle#GetExecutable'), +\ 'command': function('ale_linters#python#pycodestyle#GetCommand'), +\ 'callback': 'ale_linters#python#pycodestyle#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/python/pydocstyle.vim b/pack/acp/start/ale/ale_linters/python/pydocstyle.vim new file mode 100644 index 0000000..3901db4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/pydocstyle.vim @@ -0,0 +1,73 @@ +" Author: Pablo Acosta +" Description: pydocstyle for python files + +call ale#Set('python_pydocstyle_executable', 'pydocstyle') +call ale#Set('python_pydocstyle_options', '') +call ale#Set('python_pydocstyle_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pydocstyle_auto_pipenv', 0) + +function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pydocstyle_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pydocstyle', ['pydocstyle']) +endfunction + +function! ale_linters#python#pydocstyle#GetCommand(buffer) abort + let l:dir = fnamemodify(bufname(a:buffer), ':p:h') + let l:executable = ale_linters#python#pydocstyle#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pydocstyle' + \ : '' + + return ale#path#CdString(l:dir) + \ . ale#Escape(l:executable) . l:exec_args + \ . ' ' . ale#Var(a:buffer, 'python_pydocstyle_options') + \ . ' ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:t')) +endfunction + +function! ale_linters#python#pydocstyle#Handle(buffer, lines) abort + " Matches patterns like the following: + " mydir/myfile.py:33 in public function `myfunction`: + " DXXX: Error description + let l:line1_pattern = '\v^.*:\s*(\d+)\s+.*$' + let l:line2_pattern = '\v^.*([a-zA-Z]\d+):\s*(.*)$' + let l:output = [] + + let l:num_lines = len(a:lines) + let l:index = 0 + + while l:index < l:num_lines + let l:lnum = matchlist(a:lines[l:index], l:line1_pattern) + + if !empty(l:lnum) && (l:index + 1 < l:num_lines) + let l:desc = matchlist(a:lines[l:index + 1], l:line2_pattern) + + if !empty(l:desc) + call add(l:output, { + \ 'lnum': l:lnum[1] + 0, + \ 'col': 1, + \ 'type': 'W', + \ 'text': l:desc[2], + \ 'code': l:desc[1], + \}) + endif + + let l:index = l:index + 2 + else + let l:index = l:index + 1 + endif + endwhile + + return l:output +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pydocstyle', +\ 'executable': function('ale_linters#python#pydocstyle#GetExecutable'), +\ 'command': function('ale_linters#python#pydocstyle#GetCommand'), +\ 'callback': 'ale_linters#python#pydocstyle#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/python/pyflakes.vim b/pack/acp/start/ale/ale_linters/python/pyflakes.vim new file mode 100644 index 0000000..b512702 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/pyflakes.vim @@ -0,0 +1,50 @@ +" Author: w0rp +" Description: pyflakes for python files + +call ale#Set('python_pyflakes_executable', 'pyflakes') +call ale#Set('python_pyflakes_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pyflakes_auto_pipenv', 0) + +function! ale_linters#python#pyflakes#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyflakes_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pyflakes', ['pyflakes']) +endfunction + +function! ale_linters#python#pyflakes#GetCommand(buffer) abort + let l:executable = ale_linters#python#pyflakes#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pyflakes' + \ : '' + + return ale#Escape(l:executable) + \ . l:exec_args + \ . ' %t' +endfunction + +function! ale_linters#python#pyflakes#Handle(buffer, lines) abort + let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\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], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pyflakes', +\ 'executable': function('ale_linters#python#pyflakes#GetExecutable'), +\ 'command': function('ale_linters#python#pyflakes#GetCommand'), +\ 'callback': 'ale_linters#python#pyflakes#Handle', +\ 'output_stream': 'both', +\}) diff --git a/pack/acp/start/ale/ale_linters/python/pylama.vim b/pack/acp/start/ale/ale_linters/python/pylama.vim new file mode 100644 index 0000000..38dd283 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/pylama.vim @@ -0,0 +1,92 @@ +" Author: Kevin Locke +" Description: pylama for python files + +call ale#Set('python_pylama_executable', 'pylama') +call ale#Set('python_pylama_options', '') +call ale#Set('python_pylama_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pylama_auto_pipenv', 0) +call ale#Set('python_pylama_change_directory', 1) + +function! ale_linters#python#pylama#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylama_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama']) +endfunction + +function! ale_linters#python#pylama#GetCommand(buffer) abort + let l:cd_string = '' + + if ale#Var(a:buffer, 'python_pylama_change_directory') + " Pylama loads its configuration from the current directory only, and + " applies file masks using paths relative to the current directory. + " Run from project root, if found, otherwise buffer dir. + let l:project_root = ale#python#FindProjectRoot(a:buffer) + let l:cd_string = l:project_root isnot# '' + \ ? ale#path#CdString(l:project_root) + \ : ale#path#BufferCdString(a:buffer) + endif + + let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer) + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pylama' + \ : '' + + " Note: Using %t to lint changes would be preferable, but many pylama + " checks use surrounding paths (e.g. C0103 module name, E0402 relative + " import beyond top, etc.). Neither is ideal. + return l:cd_string + \ . ale#Escape(l:executable) . l:exec_args + \ . ale#Pad(ale#Var(a:buffer, 'python_pylama_options')) + \ . ' %s' +endfunction + +function! ale_linters#python#pylama#Handle(buffer, lines) abort + if empty(a:lines) + return [] + endif + + let l:output = ale#python#HandleTraceback(a:lines, 1) + let l:pattern = '\v^.{-}:([0-9]+):([0-9]+): +%(([A-Z][0-9]+):? +)?(.*)$' + + " First letter of error code is a pylint-compatible message type + " http://pylint.pycqa.org/en/latest/user_guide/output.html#source-code-analysis-section + " D is for Documentation (pydocstyle) + let l:pylint_type_to_ale_type = { + \ 'I': 'I', + \ 'R': 'W', + \ 'C': 'W', + \ 'W': 'W', + \ 'E': 'E', + \ 'F': 'E', + \ 'D': 'W', + \} + let l:pylint_type_to_ale_sub_type = { + \ 'R': 'style', + \ 'C': 'style', + \ 'D': 'style', + \} + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': str2nr(l:match[1]), + \ 'col': str2nr(l:match[2]), + \ 'code': l:match[3], + \ 'type': get(l:pylint_type_to_ale_type, l:match[3][0], 'W'), + \ 'sub_type': get(l:pylint_type_to_ale_sub_type, l:match[3][0], ''), + \ 'text': l:match[4], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pylama', +\ 'executable': function('ale_linters#python#pylama#GetExecutable'), +\ 'command': function('ale_linters#python#pylama#GetCommand'), +\ 'callback': 'ale_linters#python#pylama#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/python/pylint.vim b/pack/acp/start/ale/ale_linters/python/pylint.vim new file mode 100644 index 0000000..b16d535 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/pylint.vim @@ -0,0 +1,92 @@ +" Author: keith +" Description: pylint for python files + +call ale#Set('python_pylint_executable', 'pylint') +call ale#Set('python_pylint_options', '') +call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pylint_change_directory', 1) +call ale#Set('python_pylint_auto_pipenv', 0) +call ale#Set('python_pylint_use_msg_id', 0) + +function! ale_linters#python#pylint#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylint_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint']) +endfunction + +function! ale_linters#python#pylint#GetCommand(buffer) abort + let l:cd_string = '' + + if ale#Var(a:buffer, 'python_pylint_change_directory') + " pylint only checks for pylintrc in the packages above its current + " directory before falling back to user and global pylintrc. + " Run from project root, if found, otherwise buffer dir. + let l:project_root = ale#python#FindProjectRoot(a:buffer) + let l:cd_string = l:project_root isnot# '' + \ ? ale#path#CdString(l:project_root) + \ : ale#path#BufferCdString(a:buffer) + endif + + let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pylint' + \ : '' + + return l:cd_string + \ . ale#Escape(l:executable) . l:exec_args + \ . ' ' . 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^[a-zA-Z]?:?[^:]+:(\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 + + if ale#Var(a:buffer, 'python_pylint_use_msg_id') is# 1 + let l:code_out = l:code + else + let l:code_out = l:match[4] + endif + + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 1, + \ 'text': l:match[5], + \ 'code': l:code_out, + \ 'type': l:code[:0] is# 'E' ? 'E' : 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pylint', +\ 'executable': function('ale_linters#python#pylint#GetExecutable'), +\ 'command': function('ale_linters#python#pylint#GetCommand'), +\ 'callback': 'ale_linters#python#pylint#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/python/pyls.vim b/pack/acp/start/ale/ale_linters/python/pyls.vim new file mode 100644 index 0000000..c7f9143 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/pyls.vim @@ -0,0 +1,36 @@ +" Author: aurieh +" Description: A language server for Python + +call ale#Set('python_pyls_executable', 'pyls') +call ale#Set('python_pyls_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pyls_auto_pipenv', 0) +call ale#Set('python_pyls_config', {}) + +function! ale_linters#python#pyls#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyls_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pyls', ['pyls']) +endfunction + +function! ale_linters#python#pyls#GetCommand(buffer) abort + let l:executable = ale_linters#python#pyls#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pyls' + \ : '' + + return ale#Escape(l:executable) . l:exec_args +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pyls', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#python#pyls#GetExecutable'), +\ 'command': function('ale_linters#python#pyls#GetCommand'), +\ 'project_root': function('ale#python#FindProjectRoot'), +\ 'completion_filter': 'ale#completion#python#CompletionItemFilter', +\ 'lsp_config': {b -> ale#Var(b, 'python_pyls_config')}, +\}) diff --git a/pack/acp/start/ale/ale_linters/python/pyre.vim b/pack/acp/start/ale/ale_linters/python/pyre.vim new file mode 100644 index 0000000..4edd80f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/pyre.vim @@ -0,0 +1,34 @@ +" Author: dsifford +" Description: A performant type-checker supporting LSP for Python 3 created by Facebook + +call ale#Set('python_pyre_executable', 'pyre') +call ale#Set('python_pyre_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pyre_auto_pipenv', 0) + +function! ale_linters#python#pyre#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyre_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pyre', ['pyre']) +endfunction + +function! ale_linters#python#pyre#GetCommand(buffer) abort + let l:executable = ale_linters#python#pyre#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pyre persistent' + \ : ' persistent' + + return ale#Escape(l:executable) . l:exec_args +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pyre', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#python#pyre#GetExecutable'), +\ 'command': function('ale_linters#python#pyre#GetCommand'), +\ 'project_root': function('ale#python#FindProjectRoot'), +\ 'completion_filter': 'ale#completion#python#CompletionItemFilter', +\}) diff --git a/pack/acp/start/ale/ale_linters/python/vulture.vim b/pack/acp/start/ale/ale_linters/python/vulture.vim new file mode 100644 index 0000000..d328d26 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/python/vulture.vim @@ -0,0 +1,80 @@ +" Author: Yauheni Kirylau +" Description: vulture linting for python files + +call ale#Set('python_vulture_executable', 'vulture') +call ale#Set('python_vulture_options', '') +call ale#Set('python_vulture_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_vulture_change_directory', 1) + + +" The directory to change to before running vulture +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#vulture#GetExecutable(buffer) abort + return ale#python#FindExecutable(a:buffer, 'python_vulture', ['vulture']) +endfunction + + +function! ale_linters#python#vulture#GetCommand(buffer) abort + let l:change_dir = ale#Var(a:buffer, 'python_vulture_change_directory') + \ ? ale#path#CdString(s:GetDir(a:buffer)) + \ : '' + + let l:executable = ale_linters#python#vulture#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run vulture' + \ : '' + + let l:lint_dest = ale#Var(a:buffer, 'python_vulture_change_directory') + \ ? ' .' + \ : ' %s' + + return l:change_dir + \ . ale#Escape(l:executable) . l:exec_args + \ . ' ' + \ . ale#Var(a:buffer, 'python_vulture_options') + \ . l:lint_dest +endfunction + + +function! ale_linters#python#vulture#Handle(buffer, lines) abort + let l:output = ale#python#HandleTraceback(a:lines, 10) + + if !empty(l:output) + return l:output + endif + + " Matches patterns line the following: + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+): (.*)$' + let l:dir = s:GetDir(a:buffer) + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:abspath = ale#path#GetAbsPath(l:dir, l:match[1]) + let l:item = { + \ 'filename': l:abspath, + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[3], + \ 'type': 'W', + \} + call add(l:output, l:item) + endfor + + return l:output +endfunction + + +call ale#linter#Define('python', { +\ 'name': 'vulture', +\ 'executable': function('ale_linters#python#vulture#GetExecutable'), +\ 'command': function('ale_linters#python#vulture#GetCommand'), +\ 'callback': 'ale_linters#python#vulture#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/qml/qmlfmt.vim b/pack/acp/start/ale/ale_linters/qml/qmlfmt.vim new file mode 100644 index 0000000..11cc941 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/qml/qmlfmt.vim @@ -0,0 +1,25 @@ +" Author: pylipp (www.github.com/pylipp) +" Description: qmlfmt for QML files + +call ale#Set('qml_qmlfmt_executable', 'qmlfmt') + +" Find lines like +" Error:11:1: Expected token `}' +function! ale_linters#qml#qmlfmt#Handle(buffer, lines) abort + let l:pattern = '\v^(Error|Warning):(\d+):(\d+): (.+)$' + + return map(ale#util#GetMatches(a:lines, l:pattern), "{ + \ 'lnum': v:val[2] + 0, + \ 'col': v:val[3] + 0, + \ 'text': v:val[4], + \ 'type': v:val[1] is# 'Warning' ? 'W' : 'E', + \}") +endfunction + +call ale#linter#Define('qml', { +\ 'name': 'qmlfmt', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'qml_qmlfmt_executable')}, +\ 'command': '%e -e', +\ 'callback': 'ale_linters#qml#qmlfmt#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/qml/qmllint.vim b/pack/acp/start/ale/ale_linters/qml/qmllint.vim new file mode 100644 index 0000000..c2258a1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/qml/qmllint.vim @@ -0,0 +1,29 @@ +" Author: pylipp (www.github.com/pylipp) +" Description: qmllint for QML files + +" Find lines like +" /home/foo_user42/code-base/qml/Screen.qml:11 : Expected token `}' +function! ale_linters#qml#qmllint#Handle(buffer, lines) abort + let l:pattern = '\v^[/_-a-zA-z0-9\. ]+:(\d+) : (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'col': 0, + \ 'text': l:match[2], + \ 'type': 'E', + \} + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('qml', { +\ 'name': 'qmllint', +\ 'output_stream': 'stderr', +\ 'executable': 'qmllint', +\ 'command': 'qmllint %t', +\ 'callback': 'ale_linters#qml#qmllint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/r/lintr.vim b/pack/acp/start/ale/ale_linters/r/lintr.vim new file mode 100644 index 0000000..3164c06 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/r/lintr.vim @@ -0,0 +1,35 @@ +" Author: Michel Lang , w0rp , +" Fenner Macrae +" Description: This file adds support for checking R code with lintr. + +let g:ale_r_lintr_options = get(g:, 'ale_r_lintr_options', 'with_defaults()') +" A reasonable alternative default: +" get(g:, 'ale_r_lintr_options', 'with_defaults(object_usage_linter = NULL)') + + +let g:ale_r_lintr_lint_package = get(g:, 'ale_r_lintr_lint_package', 0) + +function! ale_linters#r#lintr#GetCommand(buffer) abort + if ale#Var(a:buffer, 'r_lintr_lint_package') + let l:lint_cmd = 'lint_package(cache = FALSE, linters = ' + \ . ale#Var(a:buffer, 'r_lintr_options') . ')' + else + let l:lint_cmd = 'lint(cache = FALSE, commandArgs(TRUE), ' + \ . ale#Var(a:buffer, 'r_lintr_options') . ')' + endif + + let l:cmd_string = 'suppressPackageStartupMessages(library(lintr));' + \ . l:lint_cmd + + return ale#path#BufferCdString(a:buffer) + \ . 'Rscript --vanilla -e ' + \ . ale#Escape(l:cmd_string) . ' %t' +endfunction + +call ale#linter#Define('r', { +\ 'name': 'lintr', +\ 'executable': 'Rscript', +\ 'command': function('ale_linters#r#lintr#GetCommand'), +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\ 'output_stream': 'both', +\}) diff --git a/pack/acp/start/ale/ale_linters/racket/raco.vim b/pack/acp/start/ale/ale_linters/racket/raco.vim new file mode 100644 index 0000000..e5ee4fb --- /dev/null +++ b/pack/acp/start/ale/ale_linters/racket/raco.vim @@ -0,0 +1,33 @@ +" Author: aqui18 +" Description: This file adds support for checking Racket code with raco. +" This is the same form of syntax-checking used by DrRacket as well. The +" downside is that it will only catch the first error, but none of the +" subsequent ones. This is due to how evaluation in Racket works. + +function! ale_linters#racket#raco#Handle(buffer, lines) abort + " Matches patterns + " :: + " eg: + " info.rkt:4:0: infotab-module: not a well-formed definition + let l:pattern = '^\(\s\)\@!\(.\+\):\(\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, + \ 'type': 'E', + \ 'text': l:match[5], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('racket', { +\ 'name': 'raco', +\ 'executable': 'raco', +\ 'output_stream': 'stderr', +\ 'command': 'raco expand %s', +\ 'callback': 'ale_linters#racket#raco#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/reason/ls.vim b/pack/acp/start/ale/ale_linters/reason/ls.vim new file mode 100644 index 0000000..fb1114a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/reason/ls.vim @@ -0,0 +1,23 @@ +" Author: David Buchan-Swanson +" Description: Integrate ALE with reason-language-server. + +call ale#Set('reason_ls_executable', '') + +function! ale_linters#reason#ls#FindProjectRoot(buffer) abort + let l:reason_config = ale#path#FindNearestFile(a:buffer, 'bsconfig.json') + + if !empty(l:reason_config) + return fnamemodify(l:reason_config, ':h') + endif + + return '' +endfunction + +call ale#linter#Define('reason', { +\ 'name': 'reason-language-server', +\ 'lsp': 'stdio', +\ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#reason#ls#FindProjectRoot'), +\ 'language': 'reason', +\}) diff --git a/pack/acp/start/ale/ale_linters/reason/merlin.vim b/pack/acp/start/ale/ale_linters/reason/merlin.vim new file mode 100644 index 0000000..7bef7df --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/reason/ols.vim b/pack/acp/start/ale/ale_linters/reason/ols.vim new file mode 100644 index 0000000..66137e1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/reason/ols.vim @@ -0,0 +1,14 @@ +" Author: Michael Jungo +" Description: A language server for Reason + +call ale#Set('reason_ols_executable', 'ocaml-language-server') +call ale#Set('reason_ols_use_global', get(g:, 'ale_use_global_executables', 0)) + +call ale#linter#Define('reason', { +\ 'name': 'ols', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#ols#GetExecutable'), +\ 'command': function('ale#handlers#ols#GetCommand'), +\ 'language_callback': 'ale#handlers#ols#GetLanguage', +\ 'project_root': function('ale#handlers#ols#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/review/redpen.vim b/pack/acp/start/ale/ale_linters/review/redpen.vim new file mode 100644 index 0000000..0006cab --- /dev/null +++ b/pack/acp/start/ale/ale_linters/review/redpen.vim @@ -0,0 +1,9 @@ +" Author: rhysd https://rhysd.github.io +" Description: Redpen, a proofreading tool (http://redpen.cc) + +call ale#linter#Define('review', { +\ 'name': 'redpen', +\ 'executable': 'redpen', +\ 'command': 'redpen -f review -r json %t', +\ 'callback': 'ale#handlers#redpen#HandleRedpenOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/rst/alex.vim b/pack/acp/start/ale/ale_linters/rst/alex.vim new file mode 100644 index 0000000..e7ca6fa --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rst/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for rst files + +call ale#handlers#alex#DefineLinter('rst', '--text') diff --git a/pack/acp/start/ale/ale_linters/rst/proselint.vim b/pack/acp/start/ale/ale_linters/rst/proselint.vim new file mode 100644 index 0000000..018347a --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/rst/redpen.vim b/pack/acp/start/ale/ale_linters/rst/redpen.vim new file mode 100644 index 0000000..ac966c5 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rst/redpen.vim @@ -0,0 +1,9 @@ +" Author: rhysd https://rhysd.github.io +" Description: Redpen, a proofreading tool (http://redpen.cc) + +call ale#linter#Define('rst', { +\ 'name': 'redpen', +\ 'executable': 'redpen', +\ 'command': 'redpen -f rest -r json %t', +\ 'callback': 'ale#handlers#redpen#HandleRedpenOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/rst/rstcheck.vim b/pack/acp/start/ale/ale_linters/rst/rstcheck.vim new file mode 100644 index 0000000..39e11d6 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rst/rstcheck.vim @@ -0,0 +1,38 @@ +" Author: John Nduli https://github.com/jnduli +" Description: Rstcheck for reStructuredText files +" + +function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort + " matches: 'bad_rst.rst:1: (SEVERE/4) Title overline & underline + " mismatch.' + let l:pattern = '\v^(.+):(\d*): \(([a-zA-Z]*)/\d*\) (.+)$' + let l:dir = expand('#' . a:buffer . ':p:h') + 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': 0, + \ 'type': l:match[3] is# 'SEVERE' ? 'E' : 'W', + \ 'text': l:match[4], + \}) + endfor + + return l:output +endfunction + +function! ale_linters#rst#rstcheck#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) + \ . 'rstcheck' + \ . ' %t' +endfunction + + +call ale#linter#Define('rst', { +\ 'name': 'rstcheck', +\ 'executable': 'rstcheck', +\ 'command': function('ale_linters#rst#rstcheck#GetCommand'), +\ 'callback': 'ale_linters#rst#rstcheck#Handle', +\ 'output_stream': 'both', +\}) diff --git a/pack/acp/start/ale/ale_linters/rst/textlint.vim b/pack/acp/start/ale/ale_linters/rst/textlint.vim new file mode 100644 index 0000000..56dd8db --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rst/textlint.vim @@ -0,0 +1,9 @@ +" Author: hokorobi +" Description: textlint, a proofreading tool (https://textlint.github.io/) + +call ale#linter#Define('rst', { +\ 'name': 'textlint', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), +\ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/rst/vale.vim b/pack/acp/start/ale/ale_linters/rst/vale.vim new file mode 100644 index 0000000..2e654dc --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rst/vale.vim @@ -0,0 +1,9 @@ +" Author: chew-z https://github.com/chew-z +" Description: vale for RST files + +call ale#linter#Define('rst', { +\ 'name': 'vale', +\ 'executable': 'vale', +\ 'command': 'vale --output=JSON %t', +\ 'callback': 'ale#handlers#vale#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/rst/writegood.vim b/pack/acp/start/ale/ale_linters/rst/writegood.vim new file mode 100644 index 0000000..26b1152 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rst/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for reStructuredText files + +call ale#handlers#writegood#DefineLinter('rst') diff --git a/pack/acp/start/ale/ale_linters/ruby/brakeman.vim b/pack/acp/start/ale/ale_linters/ruby/brakeman.vim new file mode 100644 index 0000000..a808808 --- /dev/null +++ b/pack/acp/start/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 + +call ale#Set('ruby_brakeman_options', '') +call ale#Set('ruby_brakeman_executable', 'brakeman') +call ale#Set('ruby_brakeman_options', '') + +function! ale_linters#ruby#brakeman#Handle(buffer, lines) abort + let l:output = [] + let l:json = ale#util#FuzzyJSONDecode(a:lines, {}) + let l:sep = has('win32') ? '\' : '/' + " Brakeman always outputs paths relative to the Rails app root + let l:rails_root = ale#ruby#FindRailsRoot(a:buffer) + + for l:warning in get(l:json, 'warnings', []) + 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, { + \ 'filename': l:rails_root . l:sep . l:warning.file, + \ '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 + + let l:executable = ale#Var(a:buffer, 'ruby_brakeman_executable') + + return ale#handlers#ruby#EscapeExecutable(l:executable, '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': {b -> ale#Var(b, 'ruby_brakeman_executable')}, +\ 'command': function('ale_linters#ruby#brakeman#GetCommand'), +\ 'callback': 'ale_linters#ruby#brakeman#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/ruby/rails_best_practices.vim b/pack/acp/start/ale/ale_linters/ruby/rails_best_practices.vim new file mode 100644 index 0000000..a94fb67 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ruby/rails_best_practices.vim @@ -0,0 +1,49 @@ +" Author: Eddie Lebow https://github.com/elebow +" Description: rails_best_practices, a code metric tool for rails projects + +call ale#Set('ruby_rails_best_practices_options', '') +call ale#Set('ruby_rails_best_practices_executable', 'rails_best_practices') + +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:rails_root = ale#ruby#FindRailsRoot(a:buffer) + + if l:rails_root is? '' + return '' + endif + + let l:executable = ale#Var(a:buffer, 'ruby_rails_best_practices_executable') + let l:output_file = has('win32') ? '%t ' : '/dev/stdout ' + let l:cat_file = has('win32') ? '; type %t' : '' + + return ale#handlers#ruby#EscapeExecutable(l:executable, 'rails_best_practices') + \ . ' --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': {b -> ale#Var(b, 'ruby_rails_best_practices_executable')}, +\ 'command': function('ale_linters#ruby#rails_best_practices#GetCommand'), +\ 'callback': 'ale_linters#ruby#rails_best_practices#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/ruby/reek.vim b/pack/acp/start/ale/ale_linters/ruby/reek.vim new file mode 100644 index 0000000..e39e366 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ruby/reek.vim @@ -0,0 +1,65 @@ +" 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) +call ale#Set('ruby_reek_options', '') +call ale#Set('ruby_reek_executable', 'reek') + +function! ale_linters#ruby#reek#GetCommand(buffer, version) abort + let l:executable = ale#Var(a:buffer, 'ruby_reek_executable') + + " Tell reek what the filename is if the version of reek is new enough. + let l:display_name_args = ale#semver#GTE(a:version, [5, 0, 0]) + \ ? ' --stdin-filename %s' + \ : '' + + return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek') + \ . ' -f json --no-progress --no-color --force-exclusion' + \ . l:display_name_args +endfunction + +function! s:BuildText(buffer, error) abort + let l:parts = [] + + if ale#Var(a:buffer, 'ruby_reek_show_context') + call add(l:parts, a:error.context) + endif + + call add(l:parts, a:error.message) + + if ale#Var(a:buffer, 'ruby_reek_show_wiki_link') + call add(l:parts, '[' . a:error.wiki_link . ']') + endif + + return join(l:parts, ' ') +endfunction + +function! ale_linters#ruby#reek#Handle(buffer, lines) abort + let l:output = [] + + for l:error in ale#util#FuzzyJSONDecode(a:lines, []) + for l:location in l:error.lines + call add(l:output, { + \ 'lnum': l:location, + \ 'type': 'W', + \ 'text': s:BuildText(a:buffer, l:error), + \ 'code': l:error.smell_type, + \}) + endfor + endfor + + return l:output +endfunction + +call ale#linter#Define('ruby', { +\ 'name': 'reek', +\ 'executable': {b -> ale#Var(b, 'ruby_reek_executable')}, +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale#Var(buffer, 'ruby_reek_executable'), +\ '%e --version', +\ function('ale_linters#ruby#reek#GetCommand'), +\ )}, +\ 'callback': 'ale_linters#ruby#reek#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/ruby/rubocop.vim b/pack/acp/start/ale/ale_linters/ruby/rubocop.vim new file mode 100644 index 0000000..8b9e9c8 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ruby/rubocop.vim @@ -0,0 +1,31 @@ +" Author: ynonp - https://github.com/ynonp, Eddie Lebow https://github.com/elebow +" Description: RuboCop, a code style analyzer for Ruby files + +call ale#Set('ruby_rubocop_executable', 'rubocop') +call ale#Set('ruby_rubocop_options', '') + +function! ale_linters#ruby#rubocop#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable') + + return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop') + \ . ' --format json --force-exclusion ' + \ . ale#Var(a:buffer, 'ruby_rubocop_options') + \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) +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': {b -> ale#Var(b, 'ruby_rubocop_executable')}, +\ 'command': function('ale_linters#ruby#rubocop#GetCommand'), +\ 'callback': 'ale#ruby#HandleRubocopOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/ruby/ruby.vim b/pack/acp/start/ale/ale_linters/ruby/ruby.vim new file mode 100644 index 0000000..2dc55eb --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ruby/ruby.vim @@ -0,0 +1,12 @@ +" Author: Brandon Roehl - https://github.com/BrandonRoehl +" Description: Ruby MRI for Ruby files + +call ale#Set('ruby_ruby_executable', 'ruby') + +call ale#linter#Define('ruby', { +\ 'name': 'ruby', +\ 'executable': {b -> ale#Var(b, 'ruby_ruby_executable')}, +\ 'command': '%e -w -c -T1 %t', +\ 'output_stream': 'stderr', +\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', +\}) diff --git a/pack/acp/start/ale/ale_linters/ruby/solargraph.vim b/pack/acp/start/ale/ale_linters/ruby/solargraph.vim new file mode 100644 index 0000000..bf54a55 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ruby/solargraph.vim @@ -0,0 +1,22 @@ +" Author: Horacio Sanson - https://github.com/hsanson +" Description: Solargraph Language Server https://solargraph.org/ +" +" Author: Devon Meunier +" Description: updated to use stdio + +call ale#Set('ruby_solargraph_executable', 'solargraph') +call ale#Set('ruby_solargraph_options', {}) + +function! ale_linters#ruby#solargraph#GetCommand(buffer) abort + return '%e' . ale#Pad('stdio') +endfunction + +call ale#linter#Define('ruby', { +\ 'name': 'solargraph', +\ 'lsp': 'stdio', +\ 'language': 'ruby', +\ 'executable': {b -> ale#Var(b, 'ruby_solargraph_executable')}, +\ 'command': function('ale_linters#ruby#solargraph#GetCommand'), +\ 'project_root': function('ale#ruby#FindProjectRoot'), +\ 'initialization_options': {b -> ale#Var(b, 'ruby_solargraph_options')}, +\}) diff --git a/pack/acp/start/ale/ale_linters/ruby/standardrb.vim b/pack/acp/start/ale/ale_linters/ruby/standardrb.vim new file mode 100644 index 0000000..f075a7d --- /dev/null +++ b/pack/acp/start/ale/ale_linters/ruby/standardrb.vim @@ -0,0 +1,23 @@ +" Author: Justin Searls https://github.com/searls, ynonp - https://github.com/ynonp, Eddie Lebow https://github.com/elebow +" based on the ale rubocop linter +" Description: StandardRB - Ruby Style Guide, with linter & automatic code fixer + +call ale#Set('ruby_standardrb_executable', 'standardrb') +call ale#Set('ruby_standardrb_options', '') + +function! ale_linters#ruby#standardrb#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_standardrb_executable') + + return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb') + \ . ' --format json --force-exclusion ' + \ . ale#Var(a:buffer, 'ruby_standardrb_options') + \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) +endfunction + +" standardrb is based on RuboCop so the callback is the same +call ale#linter#Define('ruby', { +\ 'name': 'standardrb', +\ 'executable': {b -> ale#Var(b, 'ruby_standardrb_executable')}, +\ 'command': function('ale_linters#ruby#standardrb#GetCommand'), +\ 'callback': 'ale#ruby#HandleRubocopOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/rust/cargo.vim b/pack/acp/start/ale/ale_linters/rust/cargo.vim new file mode 100644 index 0000000..f98dee9 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rust/cargo.vim @@ -0,0 +1,98 @@ +" Author: Daniel Schemala , +" Ivan Petkov +" Description: rustc invoked by cargo for rust files + +call ale#Set('rust_cargo_use_check', 1) +call ale#Set('rust_cargo_check_all_targets', 0) +call ale#Set('rust_cargo_check_examples', 0) +call ale#Set('rust_cargo_check_tests', 0) +call ale#Set('rust_cargo_avoid_whole_workspace', 1) +call ale#Set('rust_cargo_default_feature_behavior', 'default') +call ale#Set('rust_cargo_include_features', '') +call ale#Set('rust_cargo_use_clippy', 0) +call ale#Set('rust_cargo_clippy_options', '') + +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, version) abort + let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check') + \ && ale#semver#GTE(a:version, [0, 17, 0]) + let l:use_all_targets = l:use_check + \ && ale#Var(a:buffer, 'rust_cargo_check_all_targets') + \ && ale#semver#GTE(a:version, [0, 22, 0]) + let l:use_examples = l:use_check + \ && ale#Var(a:buffer, 'rust_cargo_check_examples') + \ && ale#semver#GTE(a:version, [0, 22, 0]) + let l:use_tests = l:use_check + \ && ale#Var(a:buffer, 'rust_cargo_check_tests') + \ && ale#semver#GTE(a:version, [0, 22, 0]) + + let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features') + + if !empty(l:include_features) + let l:include_features = ' --features ' . ale#Escape(l:include_features) + endif + + let l:avoid_whole_workspace = ale#Var(a:buffer, 'rust_cargo_avoid_whole_workspace') + let l:nearest_cargo_prefix = '' + + if l:avoid_whole_workspace + let l:nearest_cargo = ale#path#FindNearestFile(a:buffer, 'Cargo.toml') + let l:nearest_cargo_dir = fnamemodify(l:nearest_cargo, ':h') + + if l:nearest_cargo_dir isnot# '.' + let l:nearest_cargo_prefix = 'cd '. ale#Escape(l:nearest_cargo_dir) .' && ' + endif + endif + + let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior') + + if l:default_feature_behavior is# 'all' + let l:include_features = '' + let l:default_feature = ' --all-features' + elseif l:default_feature_behavior is# 'none' + let l:default_feature = ' --no-default-features' + else + let l:default_feature = '' + endif + + let l:subcommand = l:use_check ? 'check' : 'build' + let l:clippy_options = '' + + if ale#Var(a:buffer, 'rust_cargo_use_clippy') + let l:subcommand = 'clippy' + let l:clippy_options = ' ' . ale#Var(a:buffer, 'rust_cargo_clippy_options') + endif + + return l:nearest_cargo_prefix . 'cargo ' + \ . l:subcommand + \ . (l:use_all_targets ? ' --all-targets' : '') + \ . (l:use_examples ? ' --examples' : '') + \ . (l:use_tests ? ' --tests' : '') + \ . ' --frozen --message-format=json -q' + \ . l:default_feature + \ . l:include_features + \ . l:clippy_options +endfunction + +call ale#linter#Define('rust', { +\ 'name': 'cargo', +\ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'), +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale_linters#rust#cargo#GetCargoExecutable(buffer), +\ '%e --version', +\ function('ale_linters#rust#cargo#GetCommand'), +\ )}, +\ 'callback': 'ale#handlers#rust#HandleRustErrors', +\ 'output_stream': 'both', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/rust/rls.vim b/pack/acp/start/ale/ale_linters/rust/rls.vim new file mode 100644 index 0000000..111d755 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rust/rls.vim @@ -0,0 +1,27 @@ +" Author: w0rp +" Description: A language server for Rust + +call ale#Set('rust_rls_executable', 'rls') +call ale#Set('rust_rls_toolchain', '') +call ale#Set('rust_rls_config', {}) + +function! ale_linters#rust#rls#GetCommand(buffer) abort + let l:toolchain = ale#Var(a:buffer, 'rust_rls_toolchain') + + return '%e' . (!empty(l:toolchain) ? ' +' . ale#Escape(l:toolchain) : '') +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', +\ 'lsp_config': {b -> ale#Var(b, 'rust_rls_config')}, +\ 'executable': {b -> ale#Var(b, 'rust_rls_executable')}, +\ 'command': function('ale_linters#rust#rls#GetCommand'), +\ 'project_root': function('ale_linters#rust#rls#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/rust/rustc.vim b/pack/acp/start/ale/ale_linters/rust/rustc.vim new file mode 100644 index 0000000..f140b58 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/rust/rustc.vim @@ -0,0 +1,33 @@ +" Author: Daniel Schemala +" Description: rustc for rust files + +call ale#Set('rust_rustc_options', '-Z no-codegen') + +function! ale_linters#rust#rustc#RustcCommand(buffer) 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, 'Cargo.toml') + + if l:cargo_file isnot# '' + let l:root = fnamemodify(l:cargo_file, ':h') + let l:dependencies = ' -L ' . ale#Escape(ale#path#GetAbsPath(l:root, 'target/debug/deps')) + \ . ' -L ' . ale#Escape(ale#path#GetAbsPath(l:root, 'target/release/deps')) + else + let l:dependencies = '' + endif + + let l:options = ale#Var(a:buffer, 'rust_rustc_options') + + return 'rustc --error-format=json' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . l:dependencies . ' -' +endfunction + +call ale#linter#Define('rust', { +\ 'name': 'rustc', +\ 'executable': 'rustc', +\ 'command': function('ale_linters#rust#rustc#RustcCommand'), +\ 'callback': 'ale#handlers#rust#HandleRustErrors', +\ 'output_stream': 'stderr', +\}) diff --git a/pack/acp/start/ale/ale_linters/sass/sasslint.vim b/pack/acp/start/ale/ale_linters/sass/sasslint.vim new file mode 100644 index 0000000..17cd366 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/sass/sasslint.vim @@ -0,0 +1,28 @@ +" Author: sQVe - https://github.com/sQVe + +call ale#Set('sass_sasslint_executable', 'sass-lint') +call ale#Set('sass_sasslint_options', '') +call ale#Set('sass_sasslint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#sass#sasslint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'sass_sasslint', [ + \ 'node_modules/sass-lint/bin/sass-lint.js', + \ 'node_modules/.bin/sass-lint', + \]) +endfunction + +function! ale_linters#sass#sasslint#GetCommand(buffer) abort + let l:executable = ale_linters#sass#sasslint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'sass_sasslint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -v -q -f compact %t' +endfunction + +call ale#linter#Define('sass', { +\ 'name': 'sasslint', +\ 'executable': function('ale_linters#sass#sasslint#GetExecutable'), +\ 'command': function('ale_linters#sass#sasslint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleCSSLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/sass/stylelint.vim b/pack/acp/start/ale/ale_linters/sass/stylelint.vim new file mode 100644 index 0000000..7b14c6b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/sass/stylelint.vim @@ -0,0 +1,13 @@ +" Author: diartyz + +call ale#Set('sass_stylelint_executable', 'stylelint') +call ale#Set('sass_stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) + +call ale#linter#Define('sass', { +\ 'name': 'stylelint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'sass_stylelint', [ +\ 'node_modules/.bin/stylelint', +\ ])}, +\ 'command': '%e --stdin-filename %s', +\ 'callback': 'ale#handlers#css#HandleStyleLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/scala/fsc.vim b/pack/acp/start/ale/ale_linters/scala/fsc.vim new file mode 100644 index 0000000..9413523 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/scala/fsc.vim @@ -0,0 +1,14 @@ +" Author: Nils Leuzinger - https://github.com/PawkyPenguin +" Description: Basic scala support using fsc + +function! s:IsSbt(buffer) abort + return index(split(getbufvar(a:buffer, '&filetype'), '\.'), 'sbt') >= 0 +endfunction + +call ale#linter#Define('scala', { +\ 'name': 'fsc', +\ 'executable': {buf -> s:IsSbt(buf) ? '' : 'fsc'}, +\ 'command': '%e -Ystop-after:parser %t', +\ 'callback': 'ale#handlers#scala#HandleScalacLintFormat', +\ 'output_stream': 'stderr', +\}) diff --git a/pack/acp/start/ale/ale_linters/scala/sbtserver.vim b/pack/acp/start/ale/ale_linters/scala/sbtserver.vim new file mode 100644 index 0000000..d4f137c --- /dev/null +++ b/pack/acp/start/ale/ale_linters/scala/sbtserver.vim @@ -0,0 +1,31 @@ +" Author: ophirr33 +" Description: TCP lsp client for sbt Server + +call ale#Set('scala_sbtserver_address', '127.0.0.1:4273') +call ale#Set('scala_sbtserver_project_root', '') + +function! ale_linters#scala#sbtserver#GetProjectRoot(buffer) abort + let l:project_root = ale#Var(a:buffer, 'scala_sbtserver_project_root') + + if l:project_root is? '' + let l:project_root = ale#path#FindNearestFile(a:buffer, 'build.sbt') + + return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' + endif + + return l:project_root +endfunction + +function! ale_linters#scala#sbtserver#GetAddress(buffer) abort + let l:address = ale#Var(a:buffer, 'scala_sbtserver_address') + + return l:address +endfunction + +call ale#linter#Define('scala', { +\ 'name': 'sbtserver', +\ 'lsp': 'socket', +\ 'address': function('ale_linters#scala#sbtserver#GetAddress'), +\ 'language': 'scala', +\ 'project_root': function('ale_linters#scala#sbtserver#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/scala/scalac.vim b/pack/acp/start/ale/ale_linters/scala/scalac.vim new file mode 100644 index 0000000..1dd579b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/scala/scalac.vim @@ -0,0 +1,15 @@ +" Author: Zoltan Kalmar - https://github.com/kalmiz, +" w0rp +" Description: Basic scala support using scalac + +function! s:IsSbt(buffer) abort + return index(split(getbufvar(a:buffer, '&filetype'), '\.'), 'sbt') >= 0 +endfunction + +call ale#linter#Define('scala', { +\ 'name': 'scalac', +\ 'executable': {buf -> s:IsSbt(buf) ? '' : 'scalac'}, +\ 'command': '%e -Ystop-after:parser %t', +\ 'callback': 'ale#handlers#scala#HandleScalacLintFormat', +\ 'output_stream': 'stderr', +\}) diff --git a/pack/acp/start/ale/ale_linters/scala/scalastyle.vim b/pack/acp/start/ale/ale_linters/scala/scalastyle.vim new file mode 100644 index 0000000..6e9e4c1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/scala/scalastyle.vim @@ -0,0 +1,86 @@ +" Author: Kevin Kays - https://github.com/okkays +" Description: Support for the scalastyle checker. + +call ale#Set('scala_scalastyle_options', '') +" TODO: Remove support for the old option name in ALE 3.0. +call ale#Set('scala_scalastyle_config', +\ get(g:, 'ale_scalastyle_config_loc', '') +\) + +function! ale_linters#scala#scalastyle#Handle(buffer, lines) abort + " Look for help output from scalastyle first, which indicates that no + " configuration file was found. + for l:line in a:lines[:10] + if l:line =~# '-c, --config' + return [{ + \ 'lnum': 1, + \ 'text': '(See :help ale-scala-scalastyle)' + \ . ' No scalastyle configuration file was found.', + \}] + endif + endfor + + " 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 = ale#Var(a:buffer, 'scala_scalastyle_config') + endif + + return 'scalastyle' + \ . (!empty(l:scalastyle_config) ? ' --config ' . ale#Escape(l:scalastyle_config) : '') + \ . ale#Pad(ale#Var(a:buffer, 'scala_scalastyle_options')) + \ . ' %t' +endfunction + +call ale#linter#Define('scala', { +\ 'name': 'scalastyle', +\ 'executable': 'scalastyle', +\ 'output_stream': 'stdout', +\ 'command': function('ale_linters#scala#scalastyle#GetCommand'), +\ 'callback': 'ale_linters#scala#scalastyle#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/scss/sasslint.vim b/pack/acp/start/ale/ale_linters/scss/sasslint.vim new file mode 100644 index 0000000..cf13546 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/scss/sasslint.vim @@ -0,0 +1,28 @@ +" Author: sQVe - https://github.com/sQVe + +call ale#Set('scss_sasslint_executable', 'sass-lint') +call ale#Set('scss_sasslint_options', '') +call ale#Set('scss_sasslint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#scss#sasslint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'scss_sasslint', [ + \ 'node_modules/sass-lint/bin/sass-lint.js', + \ 'node_modules/.bin/sass-lint', + \]) +endfunction + +function! ale_linters#scss#sasslint#GetCommand(buffer) abort + let l:executable = ale_linters#scss#sasslint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'scss_sasslint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -v -q -f compact %t' +endfunction + +call ale#linter#Define('scss', { +\ 'name': 'sasslint', +\ 'executable': function('ale_linters#scss#sasslint#GetExecutable'), +\ 'command': function('ale_linters#scss#sasslint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleCSSLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/scss/scsslint.vim b/pack/acp/start/ale/ale_linters/scss/scsslint.vim new file mode 100644 index 0000000..7ce5724 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/scss/stylelint.vim b/pack/acp/start/ale/ale_linters/scss/stylelint.vim new file mode 100644 index 0000000..b5b2153 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/scss/stylelint.vim @@ -0,0 +1,19 @@ +" Author: diartyz + +call ale#Set('scss_stylelint_executable', 'stylelint') +call ale#Set('scss_stylelint_options', '') +call ale#Set('scss_stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#scss#stylelint#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'scss_stylelint_options')) + \ . ' --stdin-filename %s' +endfunction + +call ale#linter#Define('scss', { +\ 'name': 'stylelint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'scss_stylelint', [ +\ 'node_modules/.bin/stylelint', +\ ])}, +\ 'command': function('ale_linters#scss#stylelint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleStyleLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/sh/language_server.vim b/pack/acp/start/ale/ale_linters/sh/language_server.vim new file mode 100644 index 0000000..5a3b0e9 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/sh/language_server.vim @@ -0,0 +1,32 @@ +" Author: Christian Höltje (https://docwhat.org/) +" Description: BASH Language server integration for ALE +scriptencoding utf-8 + +call ale#Set('sh_language_server_executable', 'bash-language-server') +call ale#Set('sh_language_server_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#sh#language_server#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'sh_language_server', [ + \ 'node_modules/.bin/bash-language-server', + \]) +endfunction + +function! ale_linters#sh#language_server#GetCommand(buffer) abort + let l:exe = ale#Escape(ale_linters#sh#language_server#GetExecutable(a:buffer)) + + return l:exe . ' start' +endfunction + +function! ale_linters#sh#language_server#GetProjectRoot(buffer) abort + let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git') + + return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : '' +endfunction + +call ale#linter#Define('sh', { +\ 'name': 'language_server', +\ 'lsp': 'stdio', +\ 'executable': function('ale_linters#sh#language_server#GetExecutable'), +\ 'command': function('ale_linters#sh#language_server#GetCommand'), +\ 'project_root': function('ale_linters#sh#language_server#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/sh/shell.vim b/pack/acp/start/ale/ale_linters/sh/shell.vim new file mode 100644 index 0000000..189dc21 --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#sh#shell#GetExecutable'), +\ 'command': function('ale_linters#sh#shell#GetCommand'), +\ 'callback': 'ale_linters#sh#shell#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/sh/shellcheck.vim b/pack/acp/start/ale/ale_linters/sh/shellcheck.vim new file mode 100644 index 0000000..1d8b609 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/sh/shellcheck.vim @@ -0,0 +1,107 @@ +" 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-separated error +" codes to exclude from shellcheck. For example: +" +" let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004' +call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_exclusions', '')) +call ale#Set('sh_shellcheck_executable', 'shellcheck') +call ale#Set('sh_shellcheck_dialect', 'auto') +call ale#Set('sh_shellcheck_options', '') +call ale#Set('sh_shellcheck_change_directory', 1) + +function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort + let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) + + if !empty(l:shell_type) + " Use the dash dialect for /bin/ash, etc. + if l:shell_type is# 'ash' + return 'dash' + endif + + return l:shell_type + endif + + " If there's no hashbang, try using Vim's buffer variables. + if getbufvar(a:buffer, 'is_bash', 0) + return 'bash' + elseif getbufvar(a:buffer, 'is_sh', 0) + return 'sh' + elseif getbufvar(a:buffer, 'is_kornshell', 0) + return 'ksh' + endif + + return '' +endfunction + +function! ale_linters#sh#shellcheck#GetCommand(buffer, version) 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#Var(a:buffer, 'sh_shellcheck_dialect') + let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : '' + let l:cd_string = ale#Var(a:buffer, 'sh_shellcheck_change_directory') + \ ? ale#path#BufferCdString(a:buffer) + \ : '' + + if l:dialect is# 'auto' + let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer) + endif + + return l:cd_string + \ . '%e' + \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') + \ . l:external_option + \ . ' -f gcc -' +endfunction + +function! ale_linters#sh#shellcheck#Handle(buffer, lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+) \[([^\]]+)\]$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + if l:match[4] is# 'error' + let l:type = 'E' + elseif l:match[4] is# 'note' + let l:type = 'I' + else + let l:type = 'W' + endif + + let l:item = { + \ 'lnum': str2nr(l:match[2]), + \ 'type': l:type, + \ 'text': l:match[5], + \ 'code': l:match[6], + \} + + if !empty(l:match[3]) + let l:item.col = str2nr(l:match[3]) + endif + + " If the filename is something like , or -, then + " this is an error for the file we checked. + if l:match[1] isnot# '-' && l:match[1][0] isnot# '<' + let l:item['filename'] = l:match[1] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('sh', { +\ 'name': 'shellcheck', +\ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')}, +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale#Var(buffer, 'sh_shellcheck_executable'), +\ '%e --version', +\ function('ale_linters#sh#shellcheck#GetCommand'), +\ )}, +\ 'callback': 'ale_linters#sh#shellcheck#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/slim/slimlint.vim b/pack/acp/start/ale/ale_linters/slim/slimlint.vim new file mode 100644 index 0000000..1b365e2 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/slim/slimlint.vim @@ -0,0 +1,55 @@ +" Author: Markus Doits - https://github.com/doits +" Description: slim-lint for Slim files + +function! ale_linters#slim#slimlint#GetCommand(buffer) abort + let l:command = 'slim-lint %t' + + let l:rubocop_config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml') + + " Set SLIM_LINT_RUBOCOP_CONF variable as it is needed for slim-lint to + " pick up the rubocop config. + " + " See https://github.com/sds/slim-lint/blob/master/lib/slim_lint/linter/README.md#rubocop + if !empty(l:rubocop_config) + if has('win32') + let l:command = 'set SLIM_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config) . ' && ' . l:command + else + let l:command = 'SLIM_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config) . ' ' . l:command + endif + endif + + return l:command +endfunction + +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) + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'type': l:match[2], + \ 'text': l:match[3] + \} + + let l:code_match = matchlist(l:item.text, '\v^([^:]+): (.+)$') + + if !empty(l:code_match) + let l:item.code = l:code_match[1] + let l:item.text = l:code_match[2] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('slim', { +\ 'name': 'slimlint', +\ 'executable': 'slim-lint', +\ 'command': function('ale_linters#slim#slimlint#GetCommand'), +\ 'callback': 'ale_linters#slim#slimlint#Handle' +\}) diff --git a/pack/acp/start/ale/ale_linters/sml/smlnj.vim b/pack/acp/start/ale/ale_linters/sml/smlnj.vim new file mode 100644 index 0000000..852ea17 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/sml/smlnj.vim @@ -0,0 +1,9 @@ +" Author: Paulo Alem , Jake Zimmerman +" Description: Single-file SML checking with SML/NJ compiler + +call ale#linter#Define('sml', { +\ 'name': 'smlnj', +\ 'executable': function('ale#handlers#sml#GetExecutableSmlnjFile'), +\ 'command': 'sml', +\ 'callback': 'ale#handlers#sml#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/sml/smlnj_cm.vim b/pack/acp/start/ale/ale_linters/sml/smlnj_cm.vim new file mode 100644 index 0000000..9ad24af --- /dev/null +++ b/pack/acp/start/ale/ale_linters/sml/smlnj_cm.vim @@ -0,0 +1,21 @@ +" Author: Jake Zimmerman +" Description: SML checking with SML/NJ Compilation Manager + +function! ale_linters#sml#smlnj_cm#GetCommand(buffer) abort + let l:cmfile = ale#handlers#sml#GetCmFile(a:buffer) + + return 'sml -m ' . l:cmfile . ' < /dev/null' +endfunction + +" Using CM requires that we set "lint_file: 1", since it reads the files +" from the disk itself. +call ale#linter#Define('sml', { +\ 'name': 'smlnj_cm', +\ 'aliases': ['smlnj-cm'], +\ 'executable': function('ale#handlers#sml#GetExecutableSmlnjCm'), +\ 'lint_file': 1, +\ 'command': function('ale_linters#sml#smlnj_cm#GetCommand'), +\ 'callback': 'ale#handlers#sml#Handle', +\}) + +" vim:ts=4:sts=4:sw=4 diff --git a/pack/acp/start/ale/ale_linters/solidity/solhint.vim b/pack/acp/start/ale/ale_linters/solidity/solhint.vim new file mode 100644 index 0000000..8ea33e0 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/solidity/solhint.vim @@ -0,0 +1,29 @@ +" Author: Franco Victorio - https://github.com/fvictorio +" Description: Report errors in Solidity code with solhint + +function! ale_linters#solidity#solhint#Handle(buffer, lines) abort + " Matches patterns like the following: + " /path/to/file/file.sol: line 1, col 10, Error - 'addOne' is defined but never used. (no-unused-vars) + let l:pattern = '\v^[^:]+: line (\d+), col (\d+), (Error|Warning) - (.*) \((.*)\)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:isError = l:match[3] is? 'error' + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[4], + \ 'code': l:match[5], + \ 'type': l:isError ? 'E' : 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('solidity', { +\ 'name': 'solhint', +\ 'executable': 'solhint', +\ 'command': 'solhint --formatter compact %t', +\ 'callback': 'ale_linters#solidity#solhint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/solidity/solium.vim b/pack/acp/start/ale/ale_linters/solidity/solium.vim new file mode 100644 index 0000000..61ab184 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/solidity/solium.vim @@ -0,0 +1,9 @@ +" Author: Jeff Sutherland - https://github.com/jdsutherland +" Description: Report errors in Solidity code with solium + +call ale#linter#Define('solidity', { +\ 'name': 'solium', +\ 'executable': 'solium', +\ 'command': 'solium --reporter gcc --file %t', +\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/spec/rpmlint.vim b/pack/acp/start/ale/ale_linters/spec/rpmlint.vim new file mode 100644 index 0000000..92ef4d6 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/spec/rpmlint.vim @@ -0,0 +1,78 @@ +" 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. + +call ale#Set('spec_rpmlint_executable', 'rpmlint') +call ale#Set('spec_rpmlint_options', '') + +function! ale_linters#spec#rpmlint#GetCommand(buffer) abort + return '%e' + \ . ale#Pad(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': {b -> ale#Var(b, 'spec_rpmlint_executable')}, +\ 'command': function('ale_linters#spec#rpmlint#GetCommand'), +\ 'callback': 'ale_linters#spec#rpmlint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/sql/sqlint.vim b/pack/acp/start/ale/ale_linters/sql/sqlint.vim new file mode 100644 index 0000000..ca89372 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/stylus/stylelint.vim b/pack/acp/start/ale/ale_linters/stylus/stylelint.vim new file mode 100644 index 0000000..ce6f942 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/stylus/stylelint.vim @@ -0,0 +1,20 @@ +" Author: diartyz , w0rp + +call ale#Set('stylus_stylelint_executable', 'stylelint') +call ale#Set('stylus_stylelint_options', '') +call ale#Set('stylus_stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#stylus#stylelint#GetCommand(buffer) abort + return '%e' + \ . ale#Pad(ale#Var(a:buffer, 'stylus_stylelint_options')) + \ . ' --stdin-filename %s' +endfunction + +call ale#linter#Define('stylus', { +\ 'name': 'stylelint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'stylus_stylelint', [ +\ 'node_modules/.bin/stylelint', +\ ])}, +\ 'command': function('ale_linters#stylus#stylelint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleStyleLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/sugarss/stylelint.vim b/pack/acp/start/ale/ale_linters/sugarss/stylelint.vim new file mode 100644 index 0000000..6c705e4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/sugarss/stylelint.vim @@ -0,0 +1,21 @@ +" Author: toastal +" Description: `stylelint` linter for SugarSS files + +call ale#Set('sugarss_stylelint_executable', 'stylelint') +call ale#Set('sugarss_stylelint_options', '') +call ale#Set('sugarss_stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#sugarss#stylelint#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'sugarss_stylelint_options')) + \ . ' --syntax=sugarss' + \ . ' --stdin-filename %s' +endfunction + +call ale#linter#Define('sugarss', { +\ 'name': 'stylelint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'sugarss_stylelint', [ +\ 'node_modules/.bin/stylelint', +\ ])}, +\ 'command': function('ale_linters#sugarss#stylelint#GetCommand'), +\ 'callback': 'ale#handlers#css#HandleStyleLintFormat', +\}) diff --git a/pack/acp/start/ale/ale_linters/swift/sourcekitlsp.vim b/pack/acp/start/ale/ale_linters/swift/sourcekitlsp.vim new file mode 100644 index 0000000..560893b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/swift/sourcekitlsp.vim @@ -0,0 +1,13 @@ +" Author: Dan Loman +" Description: Support for sourcekit-lsp https://github.com/apple/sourcekit-lsp + +call ale#Set('sourcekit_lsp_executable', 'sourcekit-lsp') + +call ale#linter#Define('swift', { +\ 'name': 'sourcekitlsp', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale#swift#FindProjectRoot'), +\ 'language': 'swift', +\}) diff --git a/pack/acp/start/ale/ale_linters/swift/swiftlint.vim b/pack/acp/start/ale/ale_linters/swift/swiftlint.vim new file mode 100644 index 0000000..237c45d --- /dev/null +++ b/pack/acp/start/ale/ale_linters/swift/swiftlint.vim @@ -0,0 +1,69 @@ +" Author: David Mohundro , Gordon Fontenot +" Description: swiftlint for swift files + +call ale#Set('swift_swiftlint_executable', 'swiftlint') +call ale#Set('swift_swiftlint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#swift#swiftlint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'swift_swiftlint', [ + \ 'Pods/SwiftLint/swiftlint', + \ 'ios/Pods/SwiftLint/swiftlint', + \ 'swiftlint', + \]) +endfunction + +function! ale_linters#swift#swiftlint#GetCommand(buffer) abort + let l:executable = ale_linters#swift#swiftlint#GetExecutable(a:buffer) + let l:args = 'lint --use-stdin' + + return ale#Escape(l:executable) + \ . ' ' .l:args +endfunction + +function! ale_linters#swift#swiftlint#Handle(buffer, lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': str2nr(l:match[2]), + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \ 'text': l:match[5], + \} + + if l:match[4] is# 'error' + let l:item.type = 'E' + elseif l:match[4] is# 'note' + let l:item.type = 'I' + endif + + if !empty(l:match[3]) + let l:item.col = str2nr(l:match[3]) + endif + + " If the filename is something like , or -, then + " this is an error for the file we checked. + if l:match[1] isnot# '-' && l:match[1][0] isnot# '<' + let l:item['filename'] = l:match[1] + endif + + " Parse the code if it's there. + let l:code_match = matchlist(l:item.text, '\v^(.+) \(([^ (]+)\)$') + + if !empty(l:code_match) + let l:item.text = l:code_match[1] + let l:item.code = l:code_match[2] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('swift', { +\ 'name': 'swiftlint', +\ 'executable': function('ale_linters#swift#swiftlint#GetExecutable'), +\ 'command': function('ale_linters#swift#swiftlint#GetCommand'), +\ 'callback': 'ale_linters#swift#swiftlint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/tcl/nagelfar.vim b/pack/acp/start/ale/ale_linters/tcl/nagelfar.vim new file mode 100644 index 0000000..5a4940e --- /dev/null +++ b/pack/acp/start/ale/ale_linters/tcl/nagelfar.vim @@ -0,0 +1,39 @@ +" 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#GetCommand(buffer) abort + let l:options = ale#Var(a:buffer, 'tcl_nagelfar_options') + + return '%e' . ale#Pad(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': {b -> ale#Var(b, 'tcl_nagelfar_executable')}, +\ 'command': function('ale_linters#tcl#nagelfar#GetCommand'), +\ 'callback': 'ale_linters#tcl#nagelfar#Handle', +\ 'lint_file': 1, +\}) diff --git a/pack/acp/start/ale/ale_linters/terraform/terraform.vim b/pack/acp/start/ale/ale_linters/terraform/terraform.vim new file mode 100755 index 0000000..0429cb7 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/terraform/terraform.vim @@ -0,0 +1,49 @@ +" Author: Keith Maxwell +" Description: terraform fmt to check for errors + +call ale#Set('terraform_terraform_executable', 'terraform') + +function! ale_linters#terraform#terraform#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'terraform_terraform_executable') +endfunction + +function! ale_linters#terraform#terraform#GetCommand(buffer) abort + return ale#Escape(ale_linters#terraform#terraform#GetExecutable(a:buffer)) + \ . ' fmt -no-color --check=true -' +endfunction + +function! ale_linters#terraform#terraform#Handle(buffer, lines) abort + let l:head = '^Error running fmt: In : ' + let l:output = [] + let l:patterns = [ + \ l:head.'At \(\d\+\):\(\d\+\): \(.*\)$', + \ l:head.'\(.*\)$' + \] + + for l:match in ale#util#GetMatches(a:lines, l:patterns) + if len(l:match[2]) > 0 + call add(l:output, { + \ 'lnum': str2nr(l:match[1]), + \ 'col': str2nr(l:match[2]), + \ 'text': l:match[3], + \ 'type': 'E', + \}) + else + call add(l:output, { + \ 'lnum': line('$'), + \ 'text': l:match[1], + \ 'type': 'E', + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('terraform', { +\ 'name': 'terraform', +\ 'output_stream': 'stderr', +\ 'executable': function('ale_linters#terraform#terraform#GetExecutable'), +\ 'command': function('ale_linters#terraform#terraform#GetCommand'), +\ 'callback': 'ale_linters#terraform#terraform#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/terraform/tflint.vim b/pack/acp/start/ale/ale_linters/terraform/tflint.vim new file mode 100644 index 0000000..6d54a8b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/terraform/tflint.vim @@ -0,0 +1,58 @@ +" Author: Nat Williams +" Description: tflint for Terraform files +" +" See: https://www.terraform.io/ +" https://github.com/wata727/tflint + +call ale#Set('terraform_tflint_options', '') +call ale#Set('terraform_tflint_executable', 'tflint') + +function! ale_linters#terraform#tflint#Handle(buffer, lines) abort + let l:output = [] + + for l:error in ale#util#FuzzyJSONDecode(a:lines, []) + if l:error.type is# 'ERROR' + let l:type = 'E' + elseif l:error.type is# 'NOTICE' + let l:type = 'I' + else + let l:type = 'W' + endif + + call add(l:output, { + \ 'lnum': l:error.line, + \ 'text': l:error.message, + \ 'type': l:type, + \ 'code': l:error.detector, + \}) + endfor + + return l:output +endfunction + +function! ale_linters#terraform#tflint#GetCommand(buffer) abort + let l:cmd = '%e' + + let l:config_file = ale#path#FindNearestFile(a:buffer, '.tflint.hcl') + + if !empty(l:config_file) + let l:cmd .= ' --config ' . ale#Escape(l:config_file) + endif + + let l:opts = ale#Var(a:buffer, 'terraform_tflint_options') + + if !empty(l:opts) + let l:cmd .= ' ' . l:opts + endif + + let l:cmd .= ' -f json %t' + + return l:cmd +endfunction + +call ale#linter#Define('terraform', { +\ 'name': 'tflint', +\ 'executable': {b -> ale#Var(b, 'terraform_tflint_executable')}, +\ 'command': function('ale_linters#terraform#tflint#GetCommand'), +\ 'callback': 'ale_linters#terraform#tflint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/testft/testlinter.vim b/pack/acp/start/ale/ale_linters/testft/testlinter.vim new file mode 100644 index 0000000..65e0b20 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/tex/alex.vim b/pack/acp/start/ale/ale_linters/tex/alex.vim new file mode 100644 index 0000000..5d9aec6 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/tex/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for TeX files + +call ale#handlers#alex#DefineLinter('tex', '--text') diff --git a/pack/acp/start/ale/ale_linters/tex/chktex.vim b/pack/acp/start/ale/ale_linters/tex/chktex.vim new file mode 100644 index 0000000..160baf0 --- /dev/null +++ b/pack/acp/start/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': function('ale_linters#tex#chktex#GetCommand'), +\ 'callback': 'ale_linters#tex#chktex#Handle' +\}) diff --git a/pack/acp/start/ale/ale_linters/tex/lacheck.vim b/pack/acp/start/ale/ale_linters/tex/lacheck.vim new file mode 100644 index 0000000..19d6940 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/tex/lacheck.vim @@ -0,0 +1,43 @@ +" Author: Andrew Balmos - +" Description: lacheck for LaTeX files + +call ale#Set('tex_lacheck_executable', 'lacheck') + +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[3], '^Could not open ".\+"$')) + continue + endif + + " lacheck follows `\input{}` commands. We are only interested in + " reporting errors for the current buffer only. + if empty(matchstr(fnamemodify(l:match[1], ':t'), fnamemodify(bufname(a:buffer), ':t'))) + continue + endif + + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'text': l:match[3], + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('tex', { +\ 'name': 'lacheck', +\ 'executable': {b -> ale#Var(b, 'tex_lacheck_executable')}, +\ 'command': '%e %t', +\ 'callback': 'ale_linters#tex#lacheck#Handle' +\}) diff --git a/pack/acp/start/ale/ale_linters/tex/proselint.vim b/pack/acp/start/ale/ale_linters/tex/proselint.vim new file mode 100644 index 0000000..35e764e --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/tex/redpen.vim b/pack/acp/start/ale/ale_linters/tex/redpen.vim new file mode 100644 index 0000000..952a600 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/tex/redpen.vim @@ -0,0 +1,9 @@ +" Author: rhysd https://rhysd.github.io +" Description: Redpen, a proofreading tool (http://redpen.cc) + +call ale#linter#Define('tex', { +\ 'name': 'redpen', +\ 'executable': 'redpen', +\ 'command': 'redpen -f latex -r json %t', +\ 'callback': 'ale#handlers#redpen#HandleRedpenOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/tex/texlab.vim b/pack/acp/start/ale/ale_linters/tex/texlab.vim new file mode 100644 index 0000000..5ead74b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/tex/texlab.vim @@ -0,0 +1,21 @@ +" Author: Ricardo Liang +" Description: Texlab language server (Rust rewrite) + +call ale#Set('tex_texlab_executable', 'texlab') +call ale#Set('tex_texlab_options', '') + +function! ale_linters#tex#texlab#GetProjectRoot(buffer) abort + return '' +endfunction + +function! ale_linters#tex#texlab#GetCommand(buffer) abort + return '%e' . ale#Pad(ale#Var(a:buffer, 'tex_texlab_options')) +endfunction + +call ale#linter#Define('tex', { +\ 'name': 'texlab', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'tex_texlab_executable')}, +\ 'command': function('ale_linters#tex#texlab#GetCommand'), +\ 'project_root': function('ale_linters#tex#texlab#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/tex/textlint.vim b/pack/acp/start/ale/ale_linters/tex/textlint.vim new file mode 100644 index 0000000..5edac46 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/tex/textlint.vim @@ -0,0 +1,9 @@ +" Author: TANIGUCHI Masaya +" Description: textlint for LaTeX files + +call ale#linter#Define('tex', { +\ 'name': 'textlint', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), +\ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/tex/vale.vim b/pack/acp/start/ale/ale_linters/tex/vale.vim new file mode 100644 index 0000000..f64e72a --- /dev/null +++ b/pack/acp/start/ale/ale_linters/tex/vale.vim @@ -0,0 +1,9 @@ +" Author: chew-z https://github.com/chew-z +" Description: vale for LaTeX files + +call ale#linter#Define('tex', { +\ 'name': 'vale', +\ 'executable': 'vale', +\ 'command': 'vale --output=JSON %t', +\ 'callback': 'ale#handlers#vale#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/tex/writegood.vim b/pack/acp/start/ale/ale_linters/tex/writegood.vim new file mode 100644 index 0000000..c1aeace --- /dev/null +++ b/pack/acp/start/ale/ale_linters/tex/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for TeX files + +call ale#handlers#writegood#DefineLinter('tex') diff --git a/pack/acp/start/ale/ale_linters/texinfo/alex.vim b/pack/acp/start/ale/ale_linters/texinfo/alex.vim new file mode 100644 index 0000000..4d24552 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/texinfo/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for texinfo files + +call ale#handlers#alex#DefineLinter('texinfo', '--text') diff --git a/pack/acp/start/ale/ale_linters/texinfo/proselint.vim b/pack/acp/start/ale/ale_linters/texinfo/proselint.vim new file mode 100644 index 0000000..003e3a0 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/texinfo/writegood.vim b/pack/acp/start/ale/ale_linters/texinfo/writegood.vim new file mode 100644 index 0000000..4427f05 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/texinfo/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for Texinfo files + +call ale#handlers#writegood#DefineLinter('texinfo') diff --git a/pack/acp/start/ale/ale_linters/text/alex.vim b/pack/acp/start/ale/ale_linters/text/alex.vim new file mode 100644 index 0000000..d87ed91 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/text/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for text files + +call ale#handlers#alex#DefineLinter('text', '--text') diff --git a/pack/acp/start/ale/ale_linters/text/languagetool.vim b/pack/acp/start/ale/ale_linters/text/languagetool.vim new file mode 100644 index 0000000..58c99ba --- /dev/null +++ b/pack/acp/start/ale/ale_linters/text/languagetool.vim @@ -0,0 +1,4 @@ +" Author: Vincent (wahrwolf [ät] wolfpit.net) +" Description: languagetool for text files + +call ale#handlers#languagetool#DefineLinter('text') diff --git a/pack/acp/start/ale/ale_linters/text/proselint.vim b/pack/acp/start/ale/ale_linters/text/proselint.vim new file mode 100644 index 0000000..281b4ff --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/text/redpen.vim b/pack/acp/start/ale/ale_linters/text/redpen.vim new file mode 100644 index 0000000..ec4433b --- /dev/null +++ b/pack/acp/start/ale/ale_linters/text/redpen.vim @@ -0,0 +1,9 @@ +" Author: rhysd https://rhysd.github.io +" Description: Redpen, a proofreading tool (http://redpen.cc) + +call ale#linter#Define('text', { +\ 'name': 'redpen', +\ 'executable': 'redpen', +\ 'command': 'redpen -f plain -r json %t', +\ 'callback': 'ale#handlers#redpen#HandleRedpenOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/text/textlint.vim b/pack/acp/start/ale/ale_linters/text/textlint.vim new file mode 100644 index 0000000..67c4e37 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/text/textlint.vim @@ -0,0 +1,9 @@ +" Author: Yasuhiro Kiyota +" Description: textlint, a proofreading tool (https://textlint.github.io/) + +call ale#linter#Define('text', { +\ 'name': 'textlint', +\ 'executable': function('ale#handlers#textlint#GetExecutable'), +\ 'command': function('ale#handlers#textlint#GetCommand'), +\ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', +\}) diff --git a/pack/acp/start/ale/ale_linters/text/vale.vim b/pack/acp/start/ale/ale_linters/text/vale.vim new file mode 100644 index 0000000..cf37c2f --- /dev/null +++ b/pack/acp/start/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=JSON %t', +\ 'callback': 'ale#handlers#vale#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/text/writegood.vim b/pack/acp/start/ale/ale_linters/text/writegood.vim new file mode 100644 index 0000000..81b935d --- /dev/null +++ b/pack/acp/start/ale/ale_linters/text/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for text files + +call ale#handlers#writegood#DefineLinter('text') diff --git a/pack/acp/start/ale/ale_linters/thrift/thrift.vim b/pack/acp/start/ale/ale_linters/thrift/thrift.vim new file mode 100644 index 0000000..345c7ab --- /dev/null +++ b/pack/acp/start/ale/ale_linters/thrift/thrift.vim @@ -0,0 +1,87 @@ +" Author: Jon Parise + +call ale#Set('thrift_thrift_executable', 'thrift') +call ale#Set('thrift_thrift_generators', ['cpp']) +call ale#Set('thrift_thrift_includes', ['.']) +call ale#Set('thrift_thrift_options', '-strict') + +function! ale_linters#thrift#thrift#GetCommand(buffer) abort + let l:generators = ale#Var(a:buffer, 'thrift_thrift_generators') + let l:includes = ale#Var(a:buffer, 'thrift_thrift_includes') + + " The thrift compiler requires at least one generator. If none are set, + " fall back to our default value to avoid silently failing. We could also + " `throw` here, but that seems even less helpful. + if empty(l:generators) + let l:generators = ['cpp'] + endif + + let l:output_dir = ale#command#CreateDirectory(a:buffer) + + return '%e' + \ . ale#Pad(join(map(copy(l:generators), "'--gen ' . v:val"))) + \ . ale#Pad(join(map(copy(l:includes), "'-I ' . v:val"))) + \ . ale#Pad(ale#Var(a:buffer, 'thrift_thrift_options')) + \ . ' -out ' . ale#Escape(l:output_dir) + \ . ' %t' +endfunction + +function! ale_linters#thrift#thrift#Handle(buffer, lines) abort + " Matches lines like the following: + " + " [SEVERITY:/path/filename.thrift:31] Message text + " [ERROR:/path/filename.thrift:31] (last token was ';') + let l:pattern = '\v^\[(\u+):(.*):(\d+)\] (.*)$' + + let l:index = 0 + let l:output = [] + + " Roll our own output-matching loop instead of using ale#util#GetMatches + " because we need to support error messages that span multiple lines. + while l:index < len(a:lines) + let l:line = a:lines[l:index] + + let l:match = matchlist(l:line, l:pattern) + + if empty(l:match) + let l:index += 1 + continue + endif + + let l:severity = l:match[1] + + if l:severity is# 'WARNING' + let l:type = 'W' + else + let l:type = 'E' + endif + + " If our text looks like "(last token was ';')", the *next* line + " should contain a more descriptive error message. + let l:text = l:match[4] + + if l:text =~# '\(last token was .*\)' + let l:index += 1 + let l:text = get(a:lines, l:index, 'Unknown error ' . l:text) + endif + + call add(l:output, { + \ 'lnum': l:match[3] + 0, + \ 'col': 0, + \ 'type': l:type, + \ 'text': l:text, + \}) + + let l:index += 1 + endwhile + + return l:output +endfunction + +call ale#linter#Define('thrift', { +\ 'name': 'thrift', +\ 'output_stream': 'both', +\ 'executable': {b -> ale#Var(b, 'thrift_thrift_executable')}, +\ 'command': function('ale_linters#thrift#thrift#GetCommand'), +\ 'callback': 'ale_linters#thrift#thrift#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/typescript/eslint.vim b/pack/acp/start/ale/ale_linters/typescript/eslint.vim new file mode 100644 index 0000000..33a2144 --- /dev/null +++ b/pack/acp/start/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': function('ale#handlers#eslint#GetExecutable'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', +\}) diff --git a/pack/acp/start/ale/ale_linters/typescript/tslint.vim b/pack/acp/start/ale/ale_linters/typescript/tslint.vim new file mode 100644 index 0000000..f70c2e4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/typescript/tslint.vim @@ -0,0 +1,75 @@ +" Author: Prashanth Chandra , Jonathan Clem +" Description: tslint for TypeScript files + +call ale#handlers#tslint#InitVariables() + +function! ale_linters#typescript#tslint#Handle(buffer, lines) abort + " Do not output any errors for empty files if the option is on. + if ale#Var(a:buffer, 'typescript_tslint_ignore_empty_files') + \&& getbufline(a:buffer, 1, '$') == [''] + return [] + endif + + let l:dir = expand('#' . a:buffer . ':p:h') + let l:output = [] + + for l:error in ale#util#FuzzyJSONDecode(a:lines, []) + if get(l:error, 'ruleName', '') is# 'no-implicit-dependencies' + continue + endif + + let l:item = { + \ 'type': (get(l:error, 'ruleSeverity', '') is# 'WARNING' ? 'W' : 'E'), + \ 'text': 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, + \} + + let l:filename = ale#path#GetAbsPath(l:dir, l:error.name) + + " Assume temporary files are this file. + if !ale#path#IsTempName(l:filename) + let l:item.filename = l:filename + endif + + if has_key(l:error, 'ruleName') + let l:item.code = l:error.ruleName + endif + + call add(l:output, l:item) + 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) + \ : '' + + let l:tslint_rules_dir = ale#Var(a:buffer, 'typescript_tslint_rules_dir') + let l:tslint_rules_option = !empty(l:tslint_rules_dir) + \ ? ' -r ' . ale#Escape(l:tslint_rules_dir) + \ : '' + + return ale#path#BufferCdString(a:buffer) + \ . ale#Escape(ale#handlers#tslint#GetExecutable(a:buffer)) + \ . ' --format json' + \ . l:tslint_config_option + \ . l:tslint_rules_option + \ . ' %t' +endfunction + +call ale#linter#Define('typescript', { +\ 'name': 'tslint', +\ 'executable': function('ale#handlers#tslint#GetExecutable'), +\ 'command': function('ale_linters#typescript#tslint#GetCommand'), +\ 'callback': 'ale_linters#typescript#tslint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/typescript/tsserver.vim b/pack/acp/start/ale/ale_linters/typescript/tsserver.vim new file mode 100644 index 0000000..840889f --- /dev/null +++ b/pack/acp/start/ale/ale_linters/typescript/tsserver.vim @@ -0,0 +1,17 @@ +" 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', get(g:, 'ale_use_global_executables', 0)) + +call ale#linter#Define('typescript', { +\ 'name': 'tsserver', +\ 'lsp': 'tsserver', +\ 'executable': {b -> ale#node#FindExecutable(b, 'typescript_tsserver', [ +\ 'node_modules/.bin/tsserver', +\ ])}, +\ 'command': '%e', +\ 'project_root': function('ale#handlers#tsserver#GetProjectRoot'), +\ 'language': '', +\}) diff --git a/pack/acp/start/ale/ale_linters/typescript/typecheck.vim b/pack/acp/start/ale/ale_linters/typescript/typecheck.vim new file mode 100644 index 0000000..2f18691 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/typescript/xo.vim b/pack/acp/start/ale/ale_linters/typescript/xo.vim new file mode 100644 index 0000000..0a3a717 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/typescript/xo.vim @@ -0,0 +1,23 @@ +call ale#Set('typescript_xo_executable', 'xo') +call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('typescript_xo_options', '') + +function! ale_linters#typescript#xo#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'typescript_xo', [ + \ 'node_modules/.bin/xo', + \]) +endfunction + +function! ale_linters#typescript#xo#GetCommand(buffer) abort + return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer)) + \ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options')) + \ . ' --reporter json --stdin --stdin-filename %s' +endfunction + +" xo uses eslint and the output format is the same +call ale#linter#Define('typescript', { +\ 'name': 'xo', +\ 'executable': function('ale_linters#typescript#xo#GetExecutable'), +\ 'command': function('ale_linters#typescript#xo#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', +\}) diff --git a/pack/acp/start/ale/ale_linters/verilog/iverilog.vim b/pack/acp/start/ale/ale_linters/verilog/iverilog.vim new file mode 100644 index 0000000..e081f33 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/verilog/iverilog.vim @@ -0,0 +1,43 @@ +" Author: Masahiro H https://github.com/mshr-h +" Description: iverilog for verilog files + +call ale#Set('verilog_iverilog_options', '') + +function! ale_linters#verilog#iverilog#GetCommand(buffer) abort + return 'iverilog -t null -Wall ' + \ . ale#Var(a:buffer, 'verilog_iverilog_options') + \ . ' %t' +endfunction + +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': function('ale_linters#verilog#iverilog#GetCommand'), +\ 'callback': 'ale_linters#verilog#iverilog#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/verilog/verilator.vim b/pack/acp/start/ale/ale_linters/verilog/verilator.vim new file mode 100644 index 0000000..64bb6e4 --- /dev/null +++ b/pack/acp/start/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 = ale#util#Tempname() . '_verilator_linted.v' + + " Create a special filename, so we can detect it in the handler. + call ale#command#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': function('ale_linters#verilog#verilator#GetCommand'), +\ 'callback': 'ale_linters#verilog#verilator#Handle', +\ 'read_buffer': 0, +\}) diff --git a/pack/acp/start/ale/ale_linters/verilog/vlog.vim b/pack/acp/start/ale/ale_linters/verilog/vlog.vim new file mode 100644 index 0000000..37d21c4 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/verilog/vlog.vim @@ -0,0 +1,36 @@ +" Author: John Gentile +" Description: Adds support for Mentor Graphics Questa/ModelSim `vlog` Verilog compiler/checker + +call ale#Set('verilog_vlog_executable', 'vlog') +" See `$ vlog -h` for more options +call ale#Set('verilog_vlog_options', '-quiet -lint') + +function! ale_linters#verilog#vlog#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'verilog_vlog_options')) . ' %t' +endfunction + +function! ale_linters#verilog#vlog#Handle(buffer, lines) abort + "Matches patterns like the following: + "** Warning: add.v(7): (vlog-2623) Undefined variable: C. + "** Error: file.v(1): (vlog-13294) Identifier must be declared with a port mode: C. + let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'type': l:match[1] is? 'Error' ? 'E' : 'W', + \ 'text': l:match[3], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('verilog', { +\ 'name': 'vlog', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'verilog_vlog_executable')}, +\ 'command': function('ale_linters#verilog#vlog#GetCommand'), +\ 'callback': 'ale_linters#verilog#vlog#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/verilog/xvlog.vim b/pack/acp/start/ale/ale_linters/verilog/xvlog.vim new file mode 100644 index 0000000..98b5aae --- /dev/null +++ b/pack/acp/start/ale/ale_linters/verilog/xvlog.vim @@ -0,0 +1,35 @@ +" Author: John Gentile +" Description: Adds support for Xilinx Vivado `xvlog` Verilog compiler/checker + +call ale#Set('verilog_xvlog_executable', 'xvlog') +call ale#Set('verilog_xvlog_options', '') + +function! ale_linters#verilog#xvlog#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'verilog_xvlog_options')) . ' %t' +endfunction + +function! ale_linters#verilog#xvlog#Handle(buffer, lines) abort + "Matches patterns like the following: + " ERROR: [VRFC 10-1412] syntax error near output [/path/to/file.v:5] + let l:pattern = '^ERROR:\s\+\(\[.*\)\[.*:\([0-9]\+\)\]' + let l:output = [] + + " NOTE: `xvlog` only prints 'INFO' and 'ERROR' messages + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'type': 'E', + \ 'text': l:match[1], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('verilog', { +\ 'name': 'xvlog', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'verilog_xvlog_executable')}, +\ 'command': function('ale_linters#verilog#xvlog#GetCommand'), +\ 'callback': 'ale_linters#verilog#xvlog#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/vhdl/ghdl.vim b/pack/acp/start/ale/ale_linters/vhdl/ghdl.vim new file mode 100644 index 0000000..b09e620 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/vhdl/ghdl.vim @@ -0,0 +1,37 @@ +" Author: John Gentile +" Description: Adds support for `ghdl` VHDL compiler/checker + +call ale#Set('vhdl_ghdl_executable', 'ghdl') +" Compile w/VHDL-2008 support +call ale#Set('vhdl_ghdl_options', '--std=08') + +function! ale_linters#vhdl#ghdl#GetCommand(buffer) abort + return '%e -s ' . ale#Pad(ale#Var(a:buffer, 'vhdl_ghdl_options')) . ' %t' +endfunction + +function! ale_linters#vhdl#ghdl#Handle(buffer, lines) abort + " Look for 'error' lines like the following: + " dff_en.vhd:41:5:error: 'begin' is expected instead of 'if' + " /path/to/file.vhdl:12:8: no declaration for "i0" + let l:pattern = '^[a-zA-Z0-9\-\.\_\/ ]\+:\(\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], + \ 'type': 'E', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('vhdl', { +\ 'name': 'ghdl', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'vhdl_ghdl_executable')}, +\ 'command': function('ale_linters#vhdl#ghdl#GetCommand'), +\ 'callback': 'ale_linters#vhdl#ghdl#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/vhdl/vcom.vim b/pack/acp/start/ale/ale_linters/vhdl/vcom.vim new file mode 100644 index 0000000..1914fd3 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/vhdl/vcom.vim @@ -0,0 +1,38 @@ +" Author: John Gentile +" Description: Adds support for Mentor Graphics Questa/ModelSim `vcom` VHDL compiler/checker + +call ale#Set('vhdl_vcom_executable', 'vcom') +" Use VHDL-2008. See `$ vcom -h` for more options +call ale#Set('vhdl_vcom_options', '-2008 -quiet -lint') + +function! ale_linters#vhdl#vcom#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'vhdl_vcom_options')) . ' %t' +endfunction + +function! ale_linters#vhdl#vcom#Handle(buffer, lines) abort + "Matches patterns like the following: + "** Warning: ../path/to/file.vhd(218): (vcom-1236) Shared variables must be of a protected type. + "** Error: tb_file.vhd(73): (vcom-1136) Unknown identifier "aresetn". + "** Error: tb_file.vhd(73): Bad resolution function (STD_LOGIC) for type (error). + "** Error: tb_file.vhd(73): near ":": (vcom-1576) expecting ';' or ')'. + let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'type': l:match[1] is? 'Error' ? 'E' : 'W', + \ 'text': l:match[3], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('vhdl', { +\ 'name': 'vcom', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'vhdl_vcom_executable')}, +\ 'command': function('ale_linters#vhdl#vcom#GetCommand'), +\ 'callback': 'ale_linters#vhdl#vcom#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/vhdl/xvhdl.vim b/pack/acp/start/ale/ale_linters/vhdl/xvhdl.vim new file mode 100644 index 0000000..8010ff1 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/vhdl/xvhdl.vim @@ -0,0 +1,37 @@ +" Author: John Gentile +" Description: Adds support for Xilinx Vivado `xvhdl` VHDL compiler/checker + +call ale#Set('vhdl_xvhdl_executable', 'xvhdl') +" Use VHDL-2008. See `$ xvhdl -h` for more options +call ale#Set('vhdl_xvhdl_options', '--2008') + +function! ale_linters#vhdl#xvhdl#GetCommand(buffer) abort + return '%e ' . ale#Pad(ale#Var(a:buffer, 'vhdl_xvhdl_options')) . ' %t' +endfunction + +function! ale_linters#vhdl#xvhdl#Handle(buffer, lines) abort + "Matches patterns like the following: + " ERROR: [VRFC 10-91] aresetn is not declared [/path/to/file.vhd:17] + " ERROR: [VRFC 10-91] m_axis_tx_tdata is not declared [/home/user/tx_data.vhd:128] + let l:pattern = '^ERROR:\s\+\(\[.*\)\[.*:\([0-9]\+\)\]' + let l:output = [] + + " NOTE: `xvhdl` only prints 'INFO' and 'ERROR' messages + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'type': 'E', + \ 'text': l:match[1], + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('vhdl', { +\ 'name': 'xvhdl', +\ 'output_stream': 'stdout', +\ 'executable': {b -> ale#Var(b, 'vhdl_xvhdl_executable')}, +\ 'command': function('ale_linters#vhdl#xvhdl#GetCommand'), +\ 'callback': 'ale_linters#vhdl#xvhdl#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/vim/ale_custom_linting_rules.vim b/pack/acp/start/ale/ale_linters/vim/ale_custom_linting_rules.vim new file mode 100644 index 0000000..822eb30 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/vim/ale_custom_linting_rules.vim @@ -0,0 +1,65 @@ +" Author: w0rp +" Description: A linter for checking ALE project code itself. + +function! ale_linters#vim#ale_custom_linting_rules#GetExecutable(buffer) abort + let l:filename = expand('#' . a:buffer . ':p') + let l:dir_list = [] + + for l:dir in split(&runtimepath, ',') + if l:filename[:len(l:dir) - 1] is# l:dir + call add(l:dir_list, l:dir) + endif + endfor + + return !empty(l:dir_list) + \ ? findfile('test/script/custom-linting-rules', join(l:dir_list, ',')) + \ : '' +endfunction + +function! s:GetALEProjectDir(buffer) abort + let l:executable = ale_linters#vim#ale_custom_linting_rules#GetExecutable(a:buffer) + + return ale#path#Dirname(ale#path#Dirname(ale#path#Dirname(l:executable))) +endfunction + +function! ale_linters#vim#ale_custom_linting_rules#GetCommand(buffer) abort + let l:dir = s:GetALEProjectDir(a:buffer) + + let l:temp_dir = ale#command#CreateDirectory(a:buffer) + let l:temp_file = l:temp_dir . '/example.vim' + + let l:lines = getbufline(a:buffer, 1, '$') + call ale#util#Writefile(a:buffer, l:lines, l:temp_file) + + return ale#path#CdString(l:dir) . '%e ' . ale#Escape(l:temp_dir) +endfunction + +function! ale_linters#vim#ale_custom_linting_rules#Handle(buffer, lines) abort + let l:dir = s:GetALEProjectDir(a:buffer) + let l:output = [] + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+) (.+)$' + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + " Ignore trailing whitespace errors if we've turned them off. + if !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + \&& l:match[3] is# 'Trailing whitespace' + continue + endif + + call add(l:output, { + \ 'lnum': l:match[2], + \ 'text': l:match[3], + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +call ale#linter#Define('vim', { +\ 'name': 'ale_custom_linting_rules', +\ 'executable': function('ale_linters#vim#ale_custom_linting_rules#GetExecutable'), +\ 'command': function('ale_linters#vim#ale_custom_linting_rules#GetCommand'), +\ 'callback': 'ale_linters#vim#ale_custom_linting_rules#Handle', +\ 'read_buffer': 0, +\}) diff --git a/pack/acp/start/ale/ale_linters/vim/vint.vim b/pack/acp/start/ale/ale_linters/vim/vint.vim new file mode 100644 index 0000000..65e1912 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/vim/vint.vim @@ -0,0 +1,60 @@ +" 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. +call ale#Set('vim_vint_show_style_issues', 1) +call ale#Set('vim_vint_executable', 'vint') +let s:enable_neovim = has('nvim') ? ' --enable-neovim' : '' +let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})"' + +function! ale_linters#vim#vint#GetCommand(buffer, version) abort + let l:can_use_no_color_flag = empty(a:version) + \ || ale#semver#GTE(a:version, [0, 3, 7]) + + let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w' + + return '%e' + \ . ' ' . 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': {buffer -> ale#Var(buffer, 'vim_vint_executable')}, +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale#Var(buffer, 'vim_vint_executable'), +\ '%e --version', +\ function('ale_linters#vim#vint#GetCommand'), +\ )}, +\ 'callback': 'ale_linters#vim#vint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/vue/vls.vim b/pack/acp/start/ale/ale_linters/vue/vls.vim new file mode 100644 index 0000000..ac451f3 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/vue/vls.vim @@ -0,0 +1,22 @@ +" Author: Alexander Olofsson +" Description: Vue vls Language Server integration for ALE + +call ale#Set('vue_vls_executable', 'vls') +call ale#Set('vue_vls_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#vue#vls#GetProjectRoot(buffer) abort + let l:package_path = ale#path#FindNearestFile(a:buffer, 'package.json') + + return !empty(l:package_path) ? fnamemodify(l:package_path, ':h') : '' +endfunction + +call ale#linter#Define('vue', { +\ 'name': 'vls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#node#FindExecutable(b, 'vue_vls', [ +\ 'node_modules/.bin/vls', +\ ])}, +\ 'command': '%e --stdio', +\ 'language': 'vue', +\ 'project_root': function('ale_linters#vue#vls#GetProjectRoot'), +\}) diff --git a/pack/acp/start/ale/ale_linters/xhtml/alex.vim b/pack/acp/start/ale/ale_linters/xhtml/alex.vim new file mode 100644 index 0000000..97f3b59 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/xhtml/alex.vim @@ -0,0 +1,4 @@ +" Author: Johannes Wienke +" Description: alex for XHTML files + +call ale#handlers#alex#DefineLinter('xhtml', '--text') diff --git a/pack/acp/start/ale/ale_linters/xhtml/proselint.vim b/pack/acp/start/ale/ale_linters/xhtml/proselint.vim new file mode 100644 index 0000000..dfad921 --- /dev/null +++ b/pack/acp/start/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/pack/acp/start/ale/ale_linters/xhtml/writegood.vim b/pack/acp/start/ale/ale_linters/xhtml/writegood.vim new file mode 100644 index 0000000..1fcba18 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/xhtml/writegood.vim @@ -0,0 +1,4 @@ +" Author: Sumner Evans +" Description: write-good for XHTML files + +call ale#handlers#writegood#DefineLinter('xhtml') diff --git a/pack/acp/start/ale/ale_linters/xml/xmllint.vim b/pack/acp/start/ale/ale_linters/xml/xmllint.vim new file mode 100644 index 0000000..553d088 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/xml/xmllint.vim @@ -0,0 +1,65 @@ +" 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#GetCommand(buffer) abort + return '%e' + \ . ale#Pad(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': {b -> ale#Var(b, 'xml_xmllint_executable')}, +\ 'command': function('ale_linters#xml#xmllint#GetCommand'), +\ 'callback': 'ale_linters#xml#xmllint#Handle', +\ }) diff --git a/pack/acp/start/ale/ale_linters/yaml/swaglint.vim b/pack/acp/start/ale/ale_linters/yaml/swaglint.vim new file mode 100644 index 0000000..1f140e3 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/yaml/swaglint.vim @@ -0,0 +1,40 @@ +" 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', get(g:, 'ale_use_global_executables', 0)) + +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], + \} + + " Parse the code if it's there. + let l:code_match = matchlist(l:obj.text, '\v^(.+) \(([^ (]+)\)$') + + if !empty(l:code_match) + let l:obj.text = l:code_match[1] + let l:obj.code = l:code_match[2] + endif + + call add(l:output, l:obj) + endfor + + return l:output +endfunction + +call ale#linter#Define('yaml', { +\ 'name': 'swaglint', +\ 'executable': {b -> ale#node#FindExecutable(b, 'yaml_swaglint', [ +\ 'node_modules/.bin/swaglint', +\ ])}, +\ 'command': '%e -r compact --stdin', +\ 'callback': 'ale_linters#yaml#swaglint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/yaml/yamllint.vim b/pack/acp/start/ale/ale_linters/yaml/yamllint.vim new file mode 100644 index 0000000..bedb7bf --- /dev/null +++ b/pack/acp/start/ale/ale_linters/yaml/yamllint.vim @@ -0,0 +1,50 @@ +" Author: KabbAmine + +call ale#Set('yaml_yamllint_executable', 'yamllint') +call ale#Set('yaml_yamllint_options', '') + +function! ale_linters#yaml#yamllint#GetCommand(buffer) abort + return '%e' . ale#Pad(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 = '\v^.*:(\d+):(\d+): \[(error|warning)\] (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[4], + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \} + + let l:code_match = matchlist(l:item.text, '\v^(.+) \(([^)]+)\)$') + + if !empty(l:code_match) + if l:code_match[2] is# 'trailing-spaces' + \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + " Skip warnings for trailing whitespace if the option is off. + continue + endif + + let l:item.text = l:code_match[1] + let l:item.code = l:code_match[2] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('yaml', { +\ 'name': 'yamllint', +\ 'executable': {b -> ale#Var(b, 'yaml_yamllint_executable')}, +\ 'command': function('ale_linters#yaml#yamllint#GetCommand'), +\ 'callback': 'ale_linters#yaml#yamllint#Handle', +\}) diff --git a/pack/acp/start/ale/ale_linters/yang/yang_lsp.vim b/pack/acp/start/ale/ale_linters/yang/yang_lsp.vim new file mode 100644 index 0000000..81fcaa0 --- /dev/null +++ b/pack/acp/start/ale/ale_linters/yang/yang_lsp.vim @@ -0,0 +1,15 @@ +call ale#Set('yang_lsp_executable', 'yang-language-server') + +function! ale_linters#yang#yang_lsp#GetProjectRoot(buffer) abort + let l:project_root = ale#path#FindNearestFile(a:buffer, 'yang.settings') + + return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' +endfunction + +call ale#linter#Define('yang', { +\ 'name': 'yang_lsp', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'yang_lsp_executable')}, +\ 'project_root': function('ale_linters#yang#yang_lsp#GetProjectRoot'), +\ 'command': '%e', +\}) diff --git a/pack/acp/start/ale/autoload/ale.vim b/pack/acp/start/ale/autoload/ale.vim new file mode 100644 index 0000000..3a4e79c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale.vim @@ -0,0 +1,261 @@ +" Author: w0rp , David Alexander +" Description: Primary code path for the plugin +" Manages execution of linters when requested by autocommands + +" Strings used for severity in the echoed message +let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error') +let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info') +let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning') +" Ignoring linters, for disabling some, or ignoring LSP diagnostics. +let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {}) +let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0) + +let s:lint_timer = -1 +let s:getcmdwintype_exists = exists('*getcmdwintype') + +" Return 1 if a file is too large for ALE to handle. +function! ale#FileTooLarge(buffer) abort + let l:max = getbufvar(a:buffer, 'ale_maximum_file_size', get(g:, 'ale_maximum_file_size', 0)) + + 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 + " The checks are split into separate if statements to make it possible to + " profile each check individually with Vim's profiling tools. + " + " Do nothing if ALE is disabled. + if !getbufvar(a:buffer, 'ale_enabled', get(g:, 'ale_enabled', 0)) + return 1 + endif + + " Don't perform any checks when newer NeoVim versions are exiting. + if get(v:, 'exiting', v:null) isnot v:null + return 1 + endif + + let l:filetype = getbufvar(a:buffer, '&filetype') + + " Do nothing when there's no filetype. + if l:filetype is# '' + return 1 + endif + + " Do nothing for diff buffers. + if getbufvar(a:buffer, '&diff') + return 1 + endif + + " Do nothing for blacklisted files. + if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0 + return 1 + endif + + " Do nothing if running from command mode. + if s:getcmdwintype_exists && !empty(getcmdwintype()) + return 1 + endif + + let l:filename = fnamemodify(bufname(a:buffer), ':t') + + " Do nothing for directories. + if l:filename is# '.' + return 1 + endif + + " Don't start linting and so on when an operator is pending. + if ale#util#Mode(1) is# 'no' + return 1 + endif + + " Do nothing if running in the sandbox. + if ale#util#InSandbox() + return 1 + endif + + " Do nothing if the file is too large. + if ale#FileTooLarge(a:buffer) + return 1 + endif + + " Do nothing from CtrlP buffers with CtrlP-funky. + if exists(':CtrlPFunky') is 2 + \&& getbufvar(a:buffer, '&l:statusline') =~# 'CtrlPMode.*funky' + return 1 + endif + + return 0 +endfunction + +function! s:Lint(buffer, should_lint_file, timer_id) abort + " Use the filetype from the buffer + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:linters = ale#linter#Get(l:filetype) + + " Apply ignore lists for linters only if needed. + let l:ignore_config = ale#Var(a:buffer, 'linters_ignore') + let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp') + let l:linters = !empty(l:ignore_config) || l:disable_lsp + \ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config, l:disable_lsp) + \ : l:linters + + " Tell other sources that they can start checking the buffer now. + let g:ale_want_results_buffer = a:buffer + silent doautocmd User ALEWantResults + unlet! g:ale_want_results_buffer + + " Don't set up buffer data and so on if there are no linters to run. + if !has_key(g:ale_buffer_info, a:buffer) && empty(l:linters) + return + endif + + " Clear lint_file linters, or only run them if the file exists. + let l:lint_file = empty(l:linters) + \ || (a:should_lint_file && filereadable(expand('#' . a:buffer . ':p'))) + + call ale#engine#RunLinters(a:buffer, l:linters, l:lint_file) +endfunction + +" (delay, [linting_flag, buffer_number]) +function! ale#Queue(delay, ...) abort + if a:0 > 2 + throw 'too many arguments!' + endif + + let l:buffer = get(a:000, 1, v:null) + + if l:buffer is v:null + let l:buffer = bufnr('') + endif + + if type(l:buffer) isnot v:t_number + throw 'buffer_number must be a Number' + endif + + if ale#ShouldDoNothing(l:buffer) + return + endif + + " Default linting_flag to '' + let l:should_lint_file = get(a:000, 0) is# 'lint_file' + + if s:lint_timer != -1 + call timer_stop(s:lint_timer) + let s:lint_timer = -1 + endif + + if a:delay > 0 + let s:lint_timer = timer_start( + \ a:delay, + \ function('s:Lint', [l:buffer, l:should_lint_file]) + \) + else + call s:Lint(l:buffer, l:should_lint_file, 0) + endif +endfunction + +let s:current_ale_version = [2, 5, 0] + +" A function used to check for ALE features in files outside of the project. +function! ale#Has(feature) abort + let l:match = matchlist(a:feature, '\c\v^ale-(\d+)\.(\d+)(\.(\d+))?$') + + if !empty(l:match) + let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0] + + return ale#semver#GTE(s:current_ale_version, l:version) + endif + + return 0 +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:full_name = 'ale_' . a:variable_name + let l:vars = getbufvar(str2nr(a:buffer), '', {}) + + 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 + + if !has_key(g:, l:full_name) + let g:[l:full_name] = a:default + endif +endfunction + +" Given a string for adding to a command, return the string padded with a +" space on the left if it is not empty. Otherwise return an empty string. +" +" This can be used for making command strings cleaner and easier to test. +function! ale#Pad(string) abort + return !empty(a:string) ? ' ' . a:string : '' +endfunction + +" Given a environment variable name and a value, produce part of a command for +" setting an environment variable before running a command. The syntax will be +" valid for cmd on Windows, or most shells on Unix. +function! ale#Env(variable_name, value) abort + if has('win32') + return 'set ' . a:variable_name . '=' . ale#Escape(a:value) . ' && ' + endif + + return a:variable_name . '=' . ale#Escape(a: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 + +" Get the loclist item message according to a given format string. +" +" See `:help g:ale_loclist_msg_format` and `:help g:ale_echo_msg_format` +function! ale#GetLocItemMessage(item, format_string) abort + let l:msg = a:format_string + let l:severity = g:ale_echo_msg_warning_str + let l:code = get(a:item, 'code', '') + let l:type = get(a:item, 'type', 'E') + let l:linter_name = get(a:item, 'linter_name', '') + let l:code_repl = !empty(l:code) ? '\=submatch(1) . l:code . submatch(2)' : '' + + if l:type is# 'E' + let l:severity = g:ale_echo_msg_error_str + elseif l:type is# 'I' + let l:severity = g:ale_echo_msg_info_str + endif + + " Replace special markers with certain information. + " \=l:variable is used to avoid escaping issues. + let l:msg = substitute(l:msg, '\V%severity%', '\=l:severity', 'g') + let l:msg = substitute(l:msg, '\V%linter%', '\=l:linter_name', 'g') + let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g') + " Replace %s with the text. + let l:msg = substitute(l:msg, '\V%s', '\=a:item.text', 'g') + + return l:msg +endfunction diff --git a/pack/acp/start/ale/autoload/ale/ant.vim b/pack/acp/start/ale/autoload/ale/ant.vim new file mode 100644 index 0000000..689b444 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/ant.vim @@ -0,0 +1,41 @@ +" Author: Andrew Lee . +" Inspired by ale/gradle.vim by Michael Pardo +" Description: Functions for working with Ant projects. + +" Given a buffer number, find an Ant project root +function! ale#ant#FindProjectRoot(buffer) abort + let l:build_xml_path = ale#path#FindNearestFile(a:buffer, 'build.xml') + + if !empty(l:build_xml_path) + return fnamemodify(l:build_xml_path, ':h') + endif + + return '' +endfunction + +" Given a buffer number, find the path to the `ant` executable. Returns an empty +" string if cannot find the executable. +function! ale#ant#FindExecutable(buffer) abort + if executable('ant') + return 'ant' + endif + + return '' +endfunction + +" Given a buffer number, build a command to print the classpath of the root +" project. Returns an empty string if cannot build the command. +function! ale#ant#BuildClasspathCommand(buffer) abort + let l:executable = ale#ant#FindExecutable(a:buffer) + let l:project_root = ale#ant#FindProjectRoot(a:buffer) + + if !empty(l:executable) && !empty(l:project_root) + return ale#path#CdString(l:project_root) + \ . ale#Escape(l:executable) + \ . ' classpath' + \ . ' -S' + \ . ' -q' + endif + + return '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/args.vim b/pack/acp/start/ale/autoload/ale/args.vim new file mode 100644 index 0000000..70afb2e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/args.vim @@ -0,0 +1,43 @@ +" Author: w0rp +" Description: This module implements a function for parsing arguments for +" commands. + +" Given a list of valid arguments like ['foo', 'bar'] and a string to parse, +" parse the arguments from the string and return [parsed_args, remainder]. +" +" Arguments must be prefixed in the string with a single minus (-), and a +" double minus (--) denotes the end of arguments. +function! ale#args#Parse(arg_list, string) abort + let l:parsed = {} + let l:end_of_args = 0 + let l:word_list = split(a:string, ' ') + let l:index = 0 + + while l:index < len(l:word_list) + let l:word = l:word_list[l:index] + + if l:word[:0] is# '-' + let l:index += 1 + + if l:word is# '--' + break + endif + + let l:arg = l:word[1:] + + if index(a:arg_list, l:arg) >= 0 + let l:parsed[l:arg] = '' + else + throw 'Invalid argument: ' . l:word + endif + elseif l:word is# '' + let l:index += 1 + else + break + endif + endwhile + + let l:new_string = join(l:word_list[l:index :], ' ') + + return [l:parsed, l:new_string] +endfunction diff --git a/pack/acp/start/ale/autoload/ale/assert.vim b/pack/acp/start/ale/autoload/ale/assert.vim new file mode 100644 index 0000000..dac5efb --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/assert.vim @@ -0,0 +1,331 @@ +let s:command_output = [] + +function! ale#assert#GivenCommandOutput(...) abort + let s:command_output = a:000 +endfunction + +function! s:GetLinter() abort + let l:linters = ale#linter#GetLintersLoaded() + let l:filetype_linters = get(values(l:linters), 0, []) + + if len(l:linters) is 0 || len(l:filetype_linters) is 0 + throw 'No linters were loaded' + endif + + if len(l:linters) > 1 || len(l:filetype_linters) > 1 + throw 'More than one linter was loaded' + endif + + return l:filetype_linters[0] +endfunction + +function! s:FormatExe(command, executable) abort + return substitute(a:command, '%e', '\=ale#Escape(a:executable)', 'g') +endfunction + +function! s:ProcessDeferredCommands(initial_result) abort + let l:result = a:initial_result + let l:command_index = 0 + let l:command = [] + + while ale#command#IsDeferred(l:result) + call add(l:command, s:FormatExe(l:result.command, l:result.executable)) + + if get(g:, 'ale_run_synchronously_emulate_commands') + " Don't run commands, but simulate the results. + let l:Callback = g:ale_run_synchronously_callbacks[0] + let l:output = get(s:command_output, l:command_index, []) + call l:Callback(0, l:output) + unlet g:ale_run_synchronously_callbacks + + let l:command_index += 1 + else + " Run the commands in the shell, synchronously. + call ale#test#FlushJobs() + endif + + let l:result = l:result.value + endwhile + + call add(l:command, l:result) + + return l:command +endfunction + +" Load the currently loaded linter for a test case, and check that the command +" matches the given string. +function! ale#assert#Linter(expected_executable, expected_command) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:executable = ale#linter#GetExecutable(l:buffer, l:linter) + + while ale#command#IsDeferred(l:executable) + call ale#test#FlushJobs() + let l:executable = l:executable.value + endwhile + + let l:command = s:ProcessDeferredCommands( + \ ale#linter#GetCommand(l:buffer, l:linter), + \) + + if type(a:expected_command) isnot v:t_list + let l:command = l:command[-1] + endif + + if type(l:command) is v:t_string + " Replace %e with the escaped executable, so tests keep passing after + " linters are changed to use %e. + let l:command = s:FormatExe(l:command, l:executable) + elseif type(l:command) is v:t_list + call map(l:command, 's:FormatExe(v:val, l:executable)') + endif + + AssertEqual + \ [a:expected_executable, a:expected_command], + \ [l:executable, l:command] +endfunction + +function! ale#assert#Fixer(expected_result) abort + let l:buffer = bufnr('') + let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer)) + + if type(a:expected_result) isnot v:t_list + let l:result = l:result[-1] + endif + + AssertEqual a:expected_result, l:result +endfunction + +function! ale#assert#FixerNotExecuted() abort + let l:buffer = bufnr('') + let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))[-1] + + Assert empty(l:result), "The fixer will be executed when it shouldn't be" +endfunction + +function! ale#assert#LinterNotExecuted() abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:executable = ale#linter#GetExecutable(l:buffer, l:linter) + + Assert empty(l:executable), "The linter will be executed when it shouldn't be" +endfunction + +function! ale#assert#LSPOptions(expected_options) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:initialization_options = ale#lsp_linter#GetOptions(l:buffer, l:linter) + + AssertEqual a:expected_options, l:initialization_options +endfunction + +function! ale#assert#LSPConfig(expected_config) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:config = ale#lsp_linter#GetConfig(l:buffer, l:linter) + + AssertEqual a:expected_config, l:config +endfunction + +function! ale#assert#LSPLanguage(expected_language) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:language = ale#util#GetFunction(l:linter.language_callback)(l:buffer) + + AssertEqual a:expected_language, l:language +endfunction + +function! ale#assert#LSPProject(expected_root) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:root = ale#lsp_linter#FindProjectRoot(l:buffer, l:linter) + + AssertEqual a:expected_root, l:root +endfunction + +function! ale#assert#LSPAddress(expected_address) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:address = ale#linter#GetAddress(l:buffer, l:linter) + + AssertEqual a:expected_address, l:address +endfunction + +function! ale#assert#SetUpLinterTestCommands() abort + command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput() + command! -nargs=+ AssertLinter :call ale#assert#Linter() + command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted() + command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions() + command! -nargs=+ AssertLSPConfig :call ale#assert#LSPConfig() + command! -nargs=+ AssertLSPLanguage :call ale#assert#LSPLanguage() + command! -nargs=+ AssertLSPProject :call ale#assert#LSPProject() + command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress() +endfunction + +function! ale#assert#SetUpFixerTestCommands() abort + command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput() + command! -nargs=+ AssertFixer :call ale#assert#Fixer() + command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted() +endfunction + +" A dummy function for making sure this module is loaded. +function! ale#assert#SetUpLinterTest(filetype, name) abort + " Set up a marker so ALE doesn't create real random temporary filenames. + let g:ale_create_dummy_temporary_file = 1 + + " Remove current linters. + call ale#linter#Reset() + call ale#linter#PreventLoading(a:filetype) + + let l:prefix = 'ale_' . a:filetype . '_' . a:name + let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix' + + Save g:ale_lsp_root + let g:ale_lsp_root = {} + + Save b:ale_lsp_root + unlet! b:ale_lsp_root + + Save g:ale_c_build_dir + unlet! g:ale_c_build_dir + + " Save and clear linter variables. + " We'll load the runtime file to reset them to defaults. + for l:key in filter(keys(g:), b:filter_expr) + execute 'Save g:' . l:key + unlet g:[l:key] + endfor + + unlet! b:ale_c_build_dir + + for l:key in filter(keys(b:), b:filter_expr) + unlet b:[l:key] + endfor + + execute 'runtime ale_linters/' . a:filetype . '/' . a:name . '.vim' + + if !exists('g:dir') + call ale#test#SetDirectory('/testplugin/test/command_callback') + endif + + call ale#assert#SetUpLinterTestCommands() + + let g:ale_run_synchronously = 1 + let g:ale_run_synchronously_emulate_commands = 1 +endfunction + +function! ale#assert#TearDownLinterTest() abort + unlet! g:ale_create_dummy_temporary_file + unlet! g:ale_run_synchronously + unlet! g:ale_run_synchronously_callbacks + unlet! g:ale_run_synchronously_emulate_commands + unlet! g:ale_run_synchronously_command_results + let s:command_output = [] + + if exists(':GivenCommandOutput') + delcommand GivenCommandOutput + endif + + if exists(':AssertLinter') + delcommand AssertLinter + endif + + if exists(':AssertLinterNotExecuted') + delcommand AssertLinterNotExecuted + endif + + if exists(':AssertLSPOptions') + delcommand AssertLSPOptions + endif + + if exists(':AssertLSPConfig') + delcommand AssertLSPConfig + endif + + if exists(':AssertLSPLanguage') + delcommand AssertLSPLanguage + endif + + if exists(':AssertLSPProject') + delcommand AssertLSPProject + endif + + if exists(':AssertLSPAddress') + delcommand AssertLSPAddress + endif + + if exists('g:dir') + call ale#test#RestoreDirectory() + endif + + Restore + + call ale#linter#Reset() + + if exists('*ale#semver#ResetVersionCache') + call ale#semver#ResetVersionCache() + endif +endfunction + +function! ale#assert#SetUpFixerTest(filetype, name) abort + " Set up a marker so ALE doesn't create real random temporary filenames. + let g:ale_create_dummy_temporary_file = 1 + + let l:function_name = ale#fix#registry#GetFunc(a:name) + let s:FixerFunction = function(l:function_name) + + let l:prefix = 'ale_' . a:filetype . '_' . a:name + let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix' + + for l:key in filter(keys(g:), b:filter_expr) + execute 'Save g:' . l:key + unlet g:[l:key] + endfor + + for l:key in filter(keys(b:), b:filter_expr) + unlet b:[l:key] + endfor + + execute 'runtime autoload/ale/fixers/' . a:name . '.vim' + + if !exists('g:dir') + call ale#test#SetDirectory('/testplugin/test/fixers') + endif + + call ale#assert#SetUpFixerTestCommands() + + let g:ale_run_synchronously = 1 + let g:ale_run_synchronously_emulate_commands = 1 +endfunction + +function! ale#assert#TearDownFixerTest() abort + unlet! g:ale_create_dummy_temporary_file + unlet! g:ale_run_synchronously + unlet! g:ale_run_synchronously_callbacks + unlet! g:ale_run_synchronously_emulate_commands + unlet! g:ale_run_synchronously_command_results + let s:command_output = [] + unlet! s:FixerFunction + + if exists('g:dir') + call ale#test#RestoreDirectory() + endif + + Restore + + if exists('*ale#semver#ResetVersionCache') + call ale#semver#ResetVersionCache() + endif + + if exists(':GivenCommandOutput') + delcommand GivenCommandOutput + endif + + if exists(':AssertFixer') + delcommand AssertFixer + endif + + if exists(':AssertFixerNotExecuted') + delcommand AssertFixerNotExecuted + endif +endfunction diff --git a/pack/acp/start/ale/autoload/ale/balloon.vim b/pack/acp/start/ale/autoload/ale/balloon.vim new file mode 100644 index 0000000..72f6b91 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/balloon.vim @@ -0,0 +1,58 @@ +" Author: w0rp +" Description: balloonexpr support for ALE. + +function! ale#balloon#MessageForPos(bufnr, lnum, col) abort + " Don't show balloons if they are disabled, or linting is disabled. + if !ale#Var(a:bufnr, 'set_balloons') + \|| !g:ale_enabled + \|| !getbufvar(a:bufnr, 'ale_enabled', 1) + return '' + endif + + let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist + let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col) + + " Show the diagnostics message if found, 'Hover' output otherwise + if l:index >= 0 + return l:loclist[l:index].text + elseif exists('*balloon_show') || getbufvar( + \ a:bufnr, + \ 'ale_set_balloons_legacy_echo', + \ get(g:, 'ale_set_balloons_legacy_echo', 0) + \) + " Request LSP/tsserver hover information, but only if this version of + " Vim supports the balloon_show function, or if we turned a legacy + " setting on. + call ale#hover#Show(a:bufnr, a:lnum, a:col, {'called_from_balloonexpr': 1}) + endif + + return '' +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 + if has('balloon_eval') + set noballooneval + set balloonexpr= + endif + + if has('balloon_eval_term') + set noballoonevalterm + set balloonexpr= + endif +endfunction + +function! ale#balloon#Enable() abort + if has('balloon_eval') + set ballooneval + set balloonexpr=ale#balloon#Expr() + endif + + if has('balloon_eval_term') + set balloonevalterm + set balloonexpr=ale#balloon#Expr() + endif +endfunction diff --git a/pack/acp/start/ale/autoload/ale/c.vim b/pack/acp/start/ale/autoload/ale/c.vim new file mode 100644 index 0000000..2d2083d --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/c.vim @@ -0,0 +1,395 @@ +" Author: gagbo , w0rp , roel0 +" Description: Functions for integrating with C-family linters. + +call ale#Set('c_parse_makefile', 0) +call ale#Set('c_parse_compile_commands', 0) +let s:sep = has('win32') ? '\' : '/' + +" Set just so tests can override it. +let g:__ale_c_project_filenames = ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt'] + +function! ale#c#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 + + let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer) + + return ale#path#Dirname(l:json_file) +endfunction + +function! ale#c#AreSpecialCharsBalanced(option) abort + " Escape \" + let l:option_escaped = substitute(a:option, '\\"', '', 'g') + + " Retain special chars only + let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g') + let l:special_chars = split(l:special_chars, '\zs') + + " Check if they are balanced + let l:stack = [] + + for l:char in l:special_chars + if l:char is# ')' + if len(l:stack) == 0 || get(l:stack, -1) isnot# '(' + return 0 + endif + + call remove(l:stack, -1) + elseif l:char is# '(' + call add(l:stack, l:char) + else + if len(l:stack) > 0 && get(l:stack, -1) is# l:char + call remove(l:stack, -1) + else + call add(l:stack, l:char) + endif + endif + endfor + + return len(l:stack) == 0 +endfunction + +function! ale#c#ParseCFlags(path_prefix, cflag_line) abort + let l:split_lines = split(a:cflag_line) + let l:option_index = 0 + + while l:option_index < len(l:split_lines) + let l:next_option_index = l:option_index + 1 + + " Join space-separated option + while l:next_option_index < len(l:split_lines) + \&& stridx(l:split_lines[l:next_option_index], '-') != 0 + let l:next_option_index += 1 + endwhile + + let l:option = join(l:split_lines[l:option_index : l:next_option_index-1], ' ') + call remove(l:split_lines, l:option_index, l:next_option_index-1) + call insert(l:split_lines, l:option, l:option_index) + + " Ignore invalid or conflicting options + if stridx(l:option, '-') != 0 + \|| stridx(l:option, '-o') == 0 + \|| stridx(l:option, '-c') == 0 + call remove(l:split_lines, l:option_index) + let l:option_index = l:option_index - 1 + " Fix relative path + elseif stridx(l:option, '-I') == 0 + if !(stridx(l:option, ':') == 2+1 || stridx(l:option, '/') == 2+0) + let l:option = '-I' . a:path_prefix . s:sep . l:option[2:] + call remove(l:split_lines, l:option_index) + call insert(l:split_lines, l:option, l:option_index) + endif + endif + + let l:option_index = l:option_index + 1 + endwhile + + call uniq(l:split_lines) + + return join(l:split_lines, ' ') +endfunction + +function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort + if !g:ale_c_parse_makefile + return v:null + endif + + let l:buffer_filename = expand('#' . a:buffer . ':t') + let l:cflag_line = '' + + " Find a line matching this buffer's filename in the make output. + for l:line in a:make_output + if stridx(l:line, l:buffer_filename) >= 0 + let l:cflag_line = l:line + break + endif + endfor + + let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile') + let l:makefile_dir = fnamemodify(l:makefile_path, ':p:h') + + return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line) +endfunction + +" Given a buffer number, find the project directory containing +" compile_commands.json, and the path to the compile_commands.json file. +" +" If compile_commands.json cannot be found, two empty strings will be +" returned. +function! ale#c#FindCompileCommands(buffer) abort + " Look above the current source file to find compile_commands.json + let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') + + if !empty(l:json_file) + return [fnamemodify(l:json_file, ':h'), l:json_file] + endif + + " Search in build directories if we can't find it in the project. + 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 . s:sep . l:dirname + let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json' + + if filereadable(l:json_file) + return [l:path, l:json_file] + endif + endfor + endfor + + return ['', ''] +endfunction + +" Find the project root for C/C++ projects. +" +" The location of compile_commands.json will be used to find project roots. +" +" If compile_commands.json cannot be found, other common configuration files +" will be used to detect the project root. +function! ale#c#FindProjectRoot(buffer) abort + let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer) + + " Fall back on detecting the project root based on other filenames. + if empty(l:root) + for l:project_filename in g:__ale_c_project_filenames + 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 + endif + + return l:root +endfunction + +" Cache compile_commands.json data in a Dictionary, so we don't need to read +" the same files over and over again. The key in the dictionary will include +" the last modified time of the file. +if !exists('s:compile_commands_cache') + let s:compile_commands_cache = {} +endif + +function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort + let l:empty = [{}, {}] + + if empty(a:compile_commands_file) + return l:empty + endif + + let l:time = getftime(a:compile_commands_file) + + if l:time < 0 + return l:empty + endif + + let l:key = a:compile_commands_file . ':' . l:time + + if has_key(s:compile_commands_cache, l:key) + return s:compile_commands_cache[l:key] + endif + + let l:raw_data = [] + silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), '')) + + if type(l:raw_data) isnot v:t_list + let l:raw_data = [] + endif + + let l:file_lookup = {} + let l:dir_lookup = {} + + for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : []) + let l:basename = tolower(fnamemodify(l:entry.file, ':t')) + let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry] + + let l:dirbasename = tolower(fnamemodify(l:entry.directory, ':p:h:t')) + let l:dir_lookup[l:dirbasename] = get(l:dir_lookup, l:dirbasename, []) + [l:entry] + endfor + + if !empty(l:file_lookup) && !empty(l:dir_lookup) + let l:result = [l:file_lookup, l:dir_lookup] + let s:compile_commands_cache[l:key] = l:result + + return l:result + endif + + return l:empty +endfunction + +function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort + " Search for an exact file match first. + let l:basename = tolower(expand('#' . a:buffer . ':t')) + let l:file_list = get(a:file_lookup, l:basename, []) + " A source file matching the header filename. + let l:source_file = '' + + if empty(l:file_list) && l:basename =~? '\.h$\|\.hpp$' + for l:suffix in ['.c', '.cpp'] + let l:key = fnamemodify(l:basename, ':r') . l:suffix + let l:file_list = get(a:file_lookup, l:key, []) + + if !empty(l:file_list) + let l:source_file = l:key + break + endif + endfor + endif + + for l:item in l:file_list + " Load the flags for this file, or for a source file matching the + " header file. + if has_key(l:item, 'command') + \&& ( + \ bufnr(l:item.file) is a:buffer + \ || ( + \ !empty(l:source_file) + \ && l:item.file[-len(l:source_file):] is? l:source_file + \ ) + \) + return ale#c#ParseCFlags(l:item.directory, l:item.command) + endif + endfor + + " Look for any file in the same directory if we can't find an exact match. + let l:dir = ale#path#Simplify(expand('#' . a:buffer . ':p:h')) + + let l:dirbasename = tolower(expand('#' . a:buffer . ':p:h:t')) + let l:dir_list = get(a:dir_lookup, l:dirbasename, []) + + for l:item in l:dir_list + if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir + \&& has_key(l:item, 'command') + return ale#c#ParseCFlags(l:item.directory, l:item.command) + endif + endfor + + return '' +endfunction + +function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort + let l:lookups = s:GetLookupFromCompileCommandsFile(a:compile_commands_file) + let l:file_lookup = l:lookups[0] + let l:dir_lookup = l:lookups[1] + + return ale#c#ParseCompileCommandsFlags(a:buffer, l:file_lookup, l:dir_lookup) +endfunction + +function! ale#c#GetCFlags(buffer, output) abort + let l:cflags = v:null + + if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output) + let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output) + endif + + if ale#Var(a:buffer, 'c_parse_compile_commands') + let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer) + + if !empty(l:json_file) + let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file) + endif + endif + + if l:cflags is v:null + let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer)) + endif + + return l:cflags isnot v:null ? l:cflags : '' +endfunction + +function! ale#c#GetMakeCommand(buffer) abort + if ale#Var(a:buffer, 'c_parse_makefile') + let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile') + + if !empty(l:makefile_path) + return 'cd '. fnamemodify(l:makefile_path, ':p:h') . ' && make -n' + endif + endif + + return '' +endfunction + +function! ale#c#RunMakeCommand(buffer, Callback) abort + let l:command = ale#c#GetMakeCommand(a:buffer) + + if empty(l:command) + return a:Callback(a:buffer, []) + endif + + return ale#command#Run( + \ a:buffer, + \ l:command, + \ {b, output -> a:Callback(a:buffer, output)}, + \) +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 . s:sep . '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', +\]) diff --git a/pack/acp/start/ale/autoload/ale/command.vim b/pack/acp/start/ale/autoload/ale/command.vim new file mode 100644 index 0000000..1bbc4f4 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/command.vim @@ -0,0 +1,379 @@ +" Author: w0rp +" Description: Functions for formatting command strings, running commands, and +" managing files during linting and fixing cycles. + +" This dictionary holds lists of files and directories to remove later. +if !exists('s:buffer_data') + let s:buffer_data = {} +endif + +" Used to get the data in tests. +function! ale#command#GetData() abort + return deepcopy(s:buffer_data) +endfunction + +function! ale#command#ClearData() abort + let s:buffer_data = {} +endfunction + +function! ale#command#InitData(buffer) abort + if !has_key(s:buffer_data, a:buffer) + let s:buffer_data[a:buffer] = { + \ 'jobs': {}, + \ 'file_list': [], + \ 'directory_list': [], + \} + endif +endfunction + +function! ale#command#ManageFile(buffer, file) abort + call ale#command#InitData(a:buffer) + call add(s:buffer_data[a:buffer].file_list, a:file) +endfunction + +function! ale#command#ManageDirectory(buffer, directory) abort + call ale#command#InitData(a:buffer) + call add(s:buffer_data[a:buffer].directory_list, a:directory) +endfunction + +function! ale#command#CreateFile(buffer) abort + " This variable can be set to 1 in tests to stub this out. + if get(g:, 'ale_create_dummy_temporary_file') + return 'TEMP' + endif + + let l:temporary_file = ale#util#Tempname() + call ale#command#ManageFile(a:buffer, l:temporary_file) + + return l:temporary_file +endfunction + +" Create a new temporary directory and manage it in one go. +function! ale#command#CreateDirectory(buffer) abort + " This variable can be set to 1 in tests to stub this out. + if get(g:, 'ale_create_dummy_temporary_file') + return 'TEMP_DIR' + endif + + let l:temporary_directory = ale#util#Tempname() + " Create the temporary directory for the file, unreadable by 'other' + " users. + call mkdir(l:temporary_directory, '', 0750) + call ale#command#ManageDirectory(a:buffer, l:temporary_directory) + + return l:temporary_directory +endfunction + +function! ale#command#RemoveManagedFiles(buffer) abort + let l:info = get(s:buffer_data, a:buffer, {}) + + if !empty(l:info) && empty(l:info.jobs) + " We can't delete anything in a sandbox, so wait until we escape from + " it to delete temporary files and directories. + if ale#util#InSandbox() + return + endif + + " Delete files with a call akin to a plan `rm` command. + for l:filename in l:info.file_list + call delete(l:filename) + endfor + + " Delete directories like `rm -rf`. + " Directories are handled differently from files, so paths that are + " intended to be single files can be set up for automatic deletion + " without accidentally deleting entire directories. + for l:directory in l:info.directory_list + call delete(l:directory, 'rf') + endfor + + call remove(s:buffer_data, a:buffer) + endif +endfunction + +function! ale#command#CreateTempFile(buffer, temporary_file, input) abort + if empty(a:temporary_file) + " There is no file, so we didn't create anything. + return 0 + endif + + " Use an existing list of lines of input if we have it, or get the lines + " from the file. + let l:lines = a:input isnot v:null ? a:input : getbufline(a:buffer, 1, '$') + + let l:temporary_directory = fnamemodify(a:temporary_file, ':h') + " Create the temporary directory for the file, unreadable by 'other' + " users. + call mkdir(l:temporary_directory, '', 0750) + " Automatically delete the directory later. + call ale#command#ManageDirectory(a:buffer, l:temporary_directory) + " Write the buffer out to a file. + call ale#util#Writefile(a:buffer, l:lines, a:temporary_file) + + return 1 +endfunction + +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 ale#util#Tempname() . (has('win32') ? '\' : '/') . l:filename +endfunction + +" Given part of a command, replace any % with %%, so that no characters in +" the string will be replaced with filenames, etc. +function! ale#command#EscapeCommandPart(command_part) abort + return substitute(a:command_part, '%', '%%', 'g') +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, executable, command, pipe_file_if_needed, input) 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 %e with the escaped executable, if available. + if !empty(a:executable) && l:command =~# '%e' + let l:command = substitute(l:command, '%e', '\=ale#Escape(a:executable)', 'g') + endif + + " Replace all %s occurrences 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 a:input isnot v:false && 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 + + let l:file_created = ale#command#CreateTempFile( + \ a:buffer, + \ l:temporary_file, + \ a:input, + \) + + return [l:temporary_file, l:command, l:file_created] +endfunction + +function! ale#command#StopJobs(buffer, job_type) abort + let l:info = get(s:buffer_data, a:buffer, {}) + + if !empty(l:info) + let l:new_map = {} + + for [l:job_id, l:job_type] in items(l:info.jobs) + let l:job_id = str2nr(l:job_id) + + if a:job_type is# 'all' || a:job_type is# l:job_type + call ale#job#Stop(l:job_id) + else + let l:new_map[l:job_id] = l:job_type + endif + endfor + + let l:info.jobs = l:new_map + endif +endfunction + +function! s:GatherOutput(line_list, job_id, line) abort + call add(a:line_list, a:line) +endfunction + +function! s:ExitCallback(buffer, line_list, Callback, data) abort + if !has_key(s:buffer_data, a:buffer) + return + endif + + let l:jobs = s:buffer_data[a:buffer].jobs + + if !has_key(l:jobs, a:data.job_id) + return + endif + + let l:job_type = remove(l:jobs, a:data.job_id) + + if g:ale_history_enabled + call ale#history#SetExitCode(a:buffer, a:data.job_id, a:data.exit_code) + + " Log the output of the command for ALEInfo if we should. + if g:ale_history_log_output && a:data.log_output is 1 + call ale#history#RememberOutput( + \ a:buffer, + \ a:data.job_id, + \ a:line_list[:] + \) + endif + endif + + " If the callback starts any new jobs, use the same job type for them. + call setbufvar(a:buffer, 'ale_job_type', l:job_type) + let l:value = a:Callback(a:buffer, a:line_list, { + \ 'exit_code': a:data.exit_code, + \ 'temporary_file': a:data.temporary_file, + \}) + + let l:result = a:data.result + let l:result.value = l:value + + if get(l:result, 'result_callback', v:null) isnot v:null + call call(l:result.result_callback, [l:value]) + endif +endfunction + +function! ale#command#Run(buffer, command, Callback, ...) abort + let l:options = get(a:000, 0, {}) + + if len(a:000) > 1 + throw 'Too many arguments!' + endif + + let l:output_stream = get(l:options, 'output_stream', 'stdout') + let l:line_list = [] + + let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand( + \ a:buffer, + \ get(l:options, 'executable', ''), + \ a:command, + \ get(l:options, 'read_buffer', 0), + \ get(l:options, 'input', v:null), + \) + let l:command = ale#job#PrepareCommand(a:buffer, l:command) + let l:job_options = { + \ 'exit_cb': {job_id, exit_code -> s:ExitCallback( + \ a:buffer, + \ l:line_list, + \ a:Callback, + \ { + \ 'job_id': job_id, + \ 'exit_code': exit_code, + \ 'temporary_file': l:temporary_file, + \ 'log_output': get(l:options, 'log_output', 1), + \ 'result': l:result, + \ } + \ )}, + \ 'mode': 'nl', + \} + + if l:output_stream is# 'stdout' + let l:job_options.out_cb = function('s:GatherOutput', [l:line_list]) + elseif l:output_stream is# 'stderr' + let l:job_options.err_cb = function('s:GatherOutput', [l:line_list]) + elseif l:output_stream is# 'both' + let l:job_options.out_cb = function('s:GatherOutput', [l:line_list]) + let l:job_options.err_cb = function('s:GatherOutput', [l:line_list]) + endif + + let l:status = 'failed' + + if get(g:, 'ale_run_synchronously') == 1 + if get(g:, 'ale_emulate_job_failure') == 1 + let l:job_id = 0 + else + " Generate a fake job ID for tests. + let s:fake_job_id = get(s:, 'fake_job_id', 0) + 1 + let l:job_id = s:fake_job_id + endif + elseif has('win32') + let l:job_id = ale#job#StartWithCmd(l:command, l:job_options) + else + let l:job_id = ale#job#Start(l:command, l:job_options) + endif + + if l:job_id + let l:status = 'started' + let l:job_type = getbufvar(a:buffer, 'ale_job_type', 'all') + + call ale#command#InitData(a:buffer) + let s:buffer_data[a:buffer].jobs[l:job_id] = l:job_type + endif + + if g:ale_history_enabled + call ale#history#Add(a:buffer, l:status, l:job_id, l:command) + endif + + if !l:job_id + return 0 + endif + + " We'll return this Dictionary. A `result_callback` can be assigned to it + " later for capturing the result of a:Callback. + " + " The `_deferred_job_id` is used for both checking the type of object, and + " for checking the job ID and status. + " + " The original command here is used in tests. + let l:result = { + \ '_deferred_job_id': l:job_id, + \ 'executable': get(l:options, 'executable', ''), + \ 'command': a:command, + \} + + if get(g:, 'ale_run_synchronously') == 1 && l:job_id + if !exists('g:ale_run_synchronously_callbacks') + let g:ale_run_synchronously_callbacks = [] + endif + + if get(g:, 'ale_run_synchronously_emulate_commands', 0) + call add( + \ g:ale_run_synchronously_callbacks, + \ {exit_code, output -> [ + \ extend(l:line_list, output), + \ l:job_options.exit_cb(l:job_id, exit_code), + \ ]} + \) + else + " Run a command synchronously if this test option is set. + call extend(l:line_list, systemlist( + \ type(l:command) is v:t_list + \ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2]) + \ : l:command + \)) + + " Don't capture output when the callbacks aren't set. + if !has_key(l:job_options, 'out_cb') + \&& !has_key(l:job_options, 'err_cb') + let l:line_list = [] + endif + + call add( + \ g:ale_run_synchronously_callbacks, + \ {-> l:job_options.exit_cb(l:job_id, v:shell_error)} + \) + endif + endif + + return l:result +endfunction + +function! ale#command#IsDeferred(value) abort + return type(a:value) is v:t_dict && has_key(a:value, '_deferred_job_id') +endfunction diff --git a/pack/acp/start/ale/autoload/ale/completion.vim b/pack/acp/start/ale/autoload/ale/completion.vim new file mode 100644 index 0000000..ee15605 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/completion.vim @@ -0,0 +1,697 @@ +" Author: w0rp +" Description: Completion support for LSP linters + +" The omnicompletion menu is shown through a special Plug mapping which is +" only valid in Insert mode. This way, feedkeys() won't send these keys if you +" quit Insert mode quickly enough. +inoremap (ale_show_completion_menu) +" If we hit the key sequence in normal mode, then we won't show the menu, so +" we should restore the old settings right away. +nnoremap (ale_show_completion_menu) :call ale#completion#RestoreCompletionOptions() +cnoremap (ale_show_completion_menu) +vnoremap (ale_show_completion_menu) +onoremap (ale_show_completion_menu) + +let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100) +let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', []) +let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50) + +let s:timer_id = -1 +let s:last_done_pos = [] + +" CompletionItemKind values from the LSP protocol. +let s:LSP_COMPLETION_TEXT_KIND = 1 +let s:LSP_COMPLETION_METHOD_KIND = 2 +let s:LSP_COMPLETION_FUNCTION_KIND = 3 +let s:LSP_COMPLETION_CONSTRUCTOR_KIND = 4 +let s:LSP_COMPLETION_FIELD_KIND = 5 +let s:LSP_COMPLETION_VARIABLE_KIND = 6 +let s:LSP_COMPLETION_CLASS_KIND = 7 +let s:LSP_COMPLETION_INTERFACE_KIND = 8 +let s:LSP_COMPLETION_MODULE_KIND = 9 +let s:LSP_COMPLETION_PROPERTY_KIND = 10 +let s:LSP_COMPLETION_UNIT_KIND = 11 +let s:LSP_COMPLETION_VALUE_KIND = 12 +let s:LSP_COMPLETION_ENUM_KIND = 13 +let s:LSP_COMPLETION_KEYWORD_KIND = 14 +let s:LSP_COMPLETION_SNIPPET_KIND = 15 +let s:LSP_COMPLETION_COLOR_KIND = 16 +let s:LSP_COMPLETION_FILE_KIND = 17 +let s:LSP_COMPLETION_REFERENCE_KIND = 18 + +let s:LSP_INSERT_TEXT_FORMAT_PLAIN = 1 +let s:LSP_INSERT_TEXT_FORMAT_SNIPPET = 2 + +let s:lisp_regex = '\v[a-zA-Z_\-][a-zA-Z_\-0-9]*$' + +" 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 = { +\ '': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$', +\ 'clojure': s:lisp_regex, +\ 'lisp': s:lisp_regex, +\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$', +\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$', +\} + +" Regular expressions for finding the start column to replace with completion. +let s:omni_start_map = { +\ '': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$', +\} + +" A map of exact characters for triggering LSP completions. +let s:trigger_character_map = { +\ '': ['.'], +\ 'typescript': ['.', '''', '"'], +\ 'rust': ['.', '::'], +\} + +function! s:GetFiletypeValue(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 + + " Use the default regex for other files. + return a:map[''] +endfunction + +" Check if we should look for completions for a language. +function! ale#completion#GetPrefix(filetype, line, column) abort + let l:regex = s:GetFiletypeValue(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 + +function! ale#completion#GetTriggerCharacter(filetype, prefix) abort + if empty(a:prefix) + return '' + endif + + let l:char_list = s:GetFiletypeValue(s:trigger_character_map, a:filetype) + + if index(l:char_list, a:prefix) >= 0 + return a:prefix + endif + + return '' +endfunction + +function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort + let l:excluded_words = ale#Var(a:buffer, 'completion_excluded_words') + + if empty(a:prefix) + let l:filtered_suggestions = a:suggestions + else + let l:triggers = s:GetFiletypeValue(s:trigger_character_map, a:filetype) + + " For completing... + " foo. + " ^ + " We need to include all of the given suggestions. + if index(l:triggers, a:prefix) >= 0 || empty(a:prefix) + let l:filtered_suggestions = a:suggestions + else + let l:filtered_suggestions = [] + + " Filter suggestions down to those starting with the prefix we + " used for finding suggestions in the first place. + " + " Some completion tools will include suggestions which don't even + " start with the characters we have already typed. + for l:item in a:suggestions + " A List of String values or a List of completion item + " Dictionaries is accepted here. + let l:word = type(l:item) is v:t_string ? 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 + endif + endif + + if !empty(l:excluded_words) + " Copy the List if needed. We don't want to modify the argument. + " We shouldn't make a copy if we don't need to. + if l:filtered_suggestions is a:suggestions + let l:filtered_suggestions = copy(a:suggestions) + endif + + " Remove suggestions with words in the exclusion List. + call filter( + \ l:filtered_suggestions, + \ 'index(l:excluded_words, type(v:val) is v:t_string ? v:val : v:val.word) < 0', + \) + endif + + return l:filtered_suggestions +endfunction + +function! s:ReplaceCompletionOptions() abort + let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '') + + if l:source is# 'ale-automatic' || l:source is# 'ale-manual' + " 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 + + let &l:omnifunc = 'ale#completion#AutomaticOmniFunc' + endif + + if l:source is# 'ale-automatic' + if !exists('b:ale_old_completeopt') + let b:ale_old_completeopt = &l:completeopt + endif + + if &l:completeopt =~# 'preview' + let &l:completeopt = 'menu,menuone,preview,noselect,noinsert' + else + let &l:completeopt = 'menu,menuone,noselect,noinsert' + endif + endif +endfunction + +function! ale#completion#RestoreCompletionOptions() abort + " Reset settings when completion is done. + if exists('b:ale_old_omnifunc') + if b:ale_old_omnifunc isnot# 'pythoncomplete#Complete' + let &l:omnifunc = b:ale_old_omnifunc + endif + + unlet b:ale_old_omnifunc + endif + + if exists('b:ale_old_completeopt') + let &l:completeopt = b:ale_old_completeopt + unlet b:ale_old_completeopt + endif +endfunction + +function! ale#completion#GetCompletionPosition() abort + if !exists('b:ale_completion_info') + return 0 + endif + + let l:line = b:ale_completion_info.line + let l:column = b:ale_completion_info.column + let l:regex = s:GetFiletypeValue(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 +endfunction + +function! ale#completion#GetCompletionResult() abort + if exists('b:ale_completion_result') + return b:ale_completion_result + endif + + return v:null +endfunction + +function! ale#completion#AutomaticOmniFunc(findstart, base) abort + if a:findstart + return ale#completion#GetCompletionPosition() + else + let l:result = ale#completion#GetCompletionResult() + + call s:ReplaceCompletionOptions() + + return l:result isnot v:null ? l:result : [] + endif +endfunction + +function! ale#completion#Show(result) abort + if ale#util#Mode() isnot# 'i' + return + endif + + " Set the list in the buffer, temporarily replace omnifunc with our + " function, and then start omni-completion. + let b:ale_completion_result = a:result + + " Don't try to open the completion menu if there's nothing to show. + if empty(b:ale_completion_result) + return + endif + + " Replace completion options shortly before opening the menu. + call s:ReplaceCompletionOptions() + + let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '') + + if l:source is# 'ale-automatic' || l:source is# 'ale-manual' + call timer_start( + \ 0, + \ {-> ale#util#FeedKeys("\(ale_show_completion_menu)")} + \) + endif +endfunction + +function! s:CompletionStillValid(request_id) abort + let [l:line, l:column] = getpos('.')[1:2] + + return ale#util#Mode() is# 'i' + \&& 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 + \ || b:ale_completion_info.source is# 'deoplete' + \ || b:ale_completion_info.source is# 'ale-omnifunc' + \) +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:buffer = bufnr('') + let l:results = [] + let l:names_with_details = [] + + 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# 'className' + 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 + + let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', []) + + if !empty(l:names) && len(l:names) != len(l:results) + let l:names_with_details = map(copy(l:results), 'v:val.word') + let l:missing_names = filter( + \ copy(l:names), + \ 'index(l:names_with_details, v:val) < 0', + \) + + for l:name in l:missing_names + call add(l:results, { + \ 'word': l:name, + \ 'kind': 'v', + \ 'icase': 1, + \ 'menu': '', + \ 'info': '', + \}) + endfor + endif + + return l:results +endfunction + +function! ale#completion#NullFilter(buffer, item) abort + return 1 +endfunction + +function! ale#completion#ParseLSPCompletions(response) abort + let l:buffer = bufnr('') + let l:info = get(b:, 'ale_completion_info', {}) + let l:Filter = get(l:info, 'completion_filter', v:null) + + if l:Filter is v:null + let l:Filter = function('ale#completion#NullFilter') + else + let l:Filter = ale#util#GetFunction(l:Filter) + endif + + let l:item_list = [] + + if type(get(a:response, 'result')) is v:t_list + let l:item_list = a:response.result + elseif type(get(a:response, 'result')) is v:t_dict + \&& type(get(a:response.result, 'items')) is v:t_list + let l:item_list = a:response.result.items + endif + + let l:results = [] + + for l:item in l:item_list + if !call(l:Filter, [l:buffer, l:item]) + continue + endif + + if get(l:item, 'insertTextFormat') is s:LSP_INSERT_TEXT_FORMAT_PLAIN + \&& type(get(l:item, 'textEdit')) is v:t_dict + let l:text = l:item.textEdit.newText + elseif type(get(l:item, 'insertText')) is v:t_string + let l:text = l:item.insertText + else + let l:text = l:item.label + endif + + let l:word = matchstr(l:text, '\v^[^(]+') + + if empty(l:word) + continue + endif + + " See :help complete-items for Vim completion kinds + if !has_key(l:item, 'kind') + let l:kind = 'v' + elseif l:item.kind is s:LSP_COMPLETION_METHOD_KIND + let l:kind = 'm' + elseif l:item.kind is s:LSP_COMPLETION_CONSTRUCTOR_KIND + let l:kind = 'm' + elseif l:item.kind is s:LSP_COMPLETION_FUNCTION_KIND + let l:kind = 'f' + elseif l:item.kind is s:LSP_COMPLETION_CLASS_KIND + let l:kind = 'f' + elseif l:item.kind is s:LSP_COMPLETION_INTERFACE_KIND + let l:kind = 'f' + else + let l:kind = 'v' + endif + + let l:doc = get(l:item, 'documentation', '') + + if type(l:doc) is v:t_dict && has_key(l:doc, 'value') + let l:doc = l:doc.value + endif + + call add(l:results, { + \ 'word': l:word, + \ 'kind': l:kind, + \ 'icase': 1, + \ 'menu': get(l:item, 'detail', ''), + \ 'info': (type(l:doc) is v:t_string ? l:doc : ''), + \}) + endfor + + if has_key(l:info, 'prefix') + let l:results = ale#completion#Filter(l:buffer, &filetype, l:results, l:info.prefix) + endif + + return l:results[: g:ale_completion_max_suggestions - 1] +endfunction + +function! ale#completion#HandleTSServerResponse(conn_id, response) abort + if !s:CompletionStillValid(get(a:response, 'request_seq')) + return + endif + + if !has_key(a:response, 'body') + return + endif + + let l:buffer = bufnr('') + let l:command = get(a:response, 'command', '') + + if l:command is# 'completions' + let l:names = ale#completion#Filter( + \ l:buffer, + \ &filetype, + \ ale#completion#ParseTSServerCompletions(a:response), + \ b:ale_completion_info.prefix, + \)[: g:ale_completion_max_suggestions - 1] + + " We need to remember some names for tsserver, as it doesn't send + " details back for everything we send. + call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names) + + if !empty(l:names) + let b:ale_completion_info.request_id = ale#lsp#Send( + \ b:ale_completion_info.conn_id, + \ ale#lsp#tsserver_message#CompletionEntryDetails( + \ l:buffer, + \ b:ale_completion_info.line, + \ b:ale_completion_info.column, + \ l:names, + \ ), + \) + endif + elseif l:command is# 'completionEntryDetails' + call ale#completion#Show( + \ ale#completion#ParseTSServerCompletionEntryDetails(a:response), + \) + endif +endfunction + + +function! ale#completion#HandleLSPResponse(conn_id, response) abort + if !s:CompletionStillValid(get(a:response, 'id')) + return + endif + + call ale#completion#Show( + \ ale#completion#ParseLSPCompletions(a:response), + \) +endfunction + +function! s:OnReady(linter, lsp_details) abort + let l:id = a:lsp_details.connection_id + + if !ale#lsp#HasCapability(l:id, 'completion') + return + endif + + let l:buffer = a:lsp_details.buffer + + " If we have sent a completion request already, don't send another. + if b:ale_completion_info.request_id + return + endif + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#completion#HandleTSServerResponse') + \ : function('ale#completion#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + 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, + \) + else + " Send a message saying the buffer has changed first, otherwise + " completions won't know what text is nearby. + call ale#lsp#NotifyForChanges(l:id, l:buffer) + + " For LSP completions, we need to clamp the column to the length of + " the line. python-language-server and perhaps others do not implement + " this correctly. + let l:message = ale#lsp#message#Completion( + \ l:buffer, + \ b:ale_completion_info.line, + \ b:ale_completion_info.column, + \ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix), + \) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message) + + if l:request_id + let b:ale_completion_info.conn_id = l:id + let b:ale_completion_info.request_id = l:request_id + + if has_key(a:linter, 'completion_filter') + let b:ale_completion_info.completion_filter = a:linter.completion_filter + endif + endif +endfunction + +" This function can be called to check if ALE can provide completion data for +" the current buffer. 1 will be returned if there's a potential source of +" completion data ALE can use, and 0 will be returned otherwise. +function! ale#completion#CanProvideCompletions() abort + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + return 1 + endif + endfor + + return 0 +endfunction + +" This function can be used to manually trigger autocomplete, even when +" g:ale_completion_enabled is set to false +function! ale#completion#GetCompletions(source) abort + let [l:line, l:column] = getpos('.')[1:2] + + let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column) + + if a:source is# 'ale-automatic' && empty(l:prefix) + return 0 + endif + + let l:line_length = len(getline('.')) + + let b:ale_completion_info = { + \ 'line': l:line, + \ 'line_length': l:line_length, + \ 'column': l:column, + \ 'prefix': l:prefix, + \ 'conn_id': 0, + \ 'request_id': 0, + \ 'source': a:source, + \} + unlet! b:ale_completion_result + + let l:buffer = bufnr('') + let l:Callback = function('s:OnReady') + + let l:started = 0 + + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) + let l:started = 1 + endif + endif + endfor + + return l:started +endfunction + +function! ale#completion#OmniFunc(findstart, base) abort + if a:findstart + let l:started = ale#completion#GetCompletions('ale-omnifunc') + + if !l:started + " This is the special value for cancelling completions silently. + " See :help complete-functions + return -3 + endif + + return ale#completion#GetCompletionPosition() + else + let l:result = ale#completion#GetCompletionResult() + + while l:result is v:null && !complete_check() + sleep 2ms + let l:result = ale#completion#GetCompletionResult() + endwhile + + return l:result isnot v:null ? l:result : [] + endif +endfunction + +function! s:TimerHandler(...) abort + if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled) + return + endif + + let s:timer_id = -1 + + let [l:line, l:column] = getpos('.')[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] && ale#util#Mode() is# 'i' + call ale#completion#GetCompletions('ale-automatic') + endif +endfunction + +" Stop any completion timer that is queued. This is useful for tests. +function! ale#completion#StopTimer() abort + if s:timer_id != -1 + call timer_stop(s:timer_id) + endif + + let s:timer_id = -1 +endfunction + +function! ale#completion#Queue() abort + if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled) + return + endif + + let s:timer_pos = getpos('.')[1:2] + + if s:timer_pos == s:last_done_pos + " Do not ask for completions if the cursor rests on the position we + " last completed on. + return + endif + + " 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 + + call ale#completion#StopTimer() + + let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler')) +endfunction + +function! ale#completion#Done() abort + silent! pclose + + call ale#completion#RestoreCompletionOptions() + + let s:last_done_pos = getpos('.')[1:2] +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/pack/acp/start/ale/autoload/ale/completion/python.vim b/pack/acp/start/ale/autoload/ale/completion/python.vim new file mode 100644 index 0000000..6b65c5b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/completion/python.vim @@ -0,0 +1,3 @@ +function! ale#completion#python#CompletionItemFilter(buffer, item) abort + return a:item.label !~# '\v^__[a-z_]+__' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/cursor.vim b/pack/acp/start/ale/autoload/ale/cursor.vim new file mode 100644 index 0000000..8c331c5 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/cursor.vim @@ -0,0 +1,167 @@ +scriptencoding utf-8 +" Author: w0rp +" Author: João Paulo S. de Souza +" Description: Echoes lint message for the current line, if any + +" Controls the milliseconds delay before echoing a message. +let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10) +" A string format for the echoed message. +let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s') + +let s:cursor_timer = -1 +let s:last_pos = [0, 0, 0] + +function! ale#cursor#TruncatedEcho(original_message) abort + let l:message = a:original_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') + + " We need to remember the setting for shortmess and reset it again. + let l:shortmess_options = &l:shortmess + + try + let l:cursor_position = getpos('.') + + " The message is truncated and saved to the history. + silent! setlocal shortmess+=T + + try + exec "norm! :echomsg l:message\n" + catch /^Vim\%((\a\+)\)\=:E523/ + " Fallback into manual truncate (#1987) + let l:winwidth = winwidth(0) + + if l:winwidth < strdisplaywidth(l:message) + " Truncate message longer than window width with trailing '...' + let l:message = l:message[:l:winwidth - 4] . '...' + endif + + exec 'echomsg l:message' + endtry + + " Reset the cursor position if we moved off the end of the line. + " Using :norm and :echomsg can move the cursor off the end of the + " line. + if l:cursor_position != getpos('.') + call setpos('.', l:cursor_position) + endif + finally + let &l:shortmess = l:shortmess_options + endtry +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 + let l:buffer = bufnr('') + + if !g:ale_echo_cursor && !g:ale_cursor_detail + return + endif + + " Only echo the warnings in normal mode, otherwise we will get problems. + if mode(1) isnot# 'n' + return + endif + + if ale#ShouldDoNothing(l:buffer) + return + endif + + let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer) + + if g:ale_echo_cursor + if !empty(l:loc) + let l:format = ale#Var(l:buffer, 'echo_msg_format') + let l:msg = ale#GetLocItemMessage(l:loc, l:format) + 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. + execute 'echo' + let l:info.echoed = 0 + endif + endif + + if g:ale_cursor_detail + if !empty(l:loc) + call s:ShowCursorDetailForItem(l:loc, {'stay_here': 1}) + else + call ale#preview#CloseIfTypeMatches('ale-preview') + endif + endif +endfunction + +function! ale#cursor#EchoCursorWarningWithDelay() abort + let l:buffer = bufnr('') + + if !g:ale_echo_cursor && !g:ale_cursor_detail + return + endif + + " Only echo the warnings in normal mode, otherwise we will get problems. + if mode(1) isnot# 'n' + return + endif + + call s:StopCursorTimer() + + let l:pos = getpos('.')[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 l:delay = ale#Var(l:buffer, 'echo_delay') + + let s:last_pos = l:pos + let s:cursor_timer = timer_start( + \ l:delay, + \ function('ale#cursor#EchoCursorWarning') + \) + endif +endfunction + +function! s:ShowCursorDetailForItem(loc, options) abort + let l:stay_here = get(a:options, 'stay_here', 0) + + let s:last_detailed_line = line('.') + let l:message = get(a:loc, 'detail', a:loc.text) + let l:lines = split(l:message, "\n") + call ale#preview#Show(l:lines, {'stay_here': l:stay_here}) + + " Clear the echo message if we manually displayed details. + if !l:stay_here + execute 'echo' + endif +endfunction + +function! ale#cursor#ShowCursorDetail() abort + let l:buffer = bufnr('') + + " Only echo the warnings in normal mode, otherwise we will get problems. + if mode() isnot# 'n' + return + endif + + if ale#ShouldDoNothing(l:buffer) + return + endif + + call s:StopCursorTimer() + + let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer) + + if !empty(l:loc) + call s:ShowCursorDetailForItem(l:loc, {'stay_here': 0}) + endif +endfunction diff --git a/pack/acp/start/ale/autoload/ale/d.vim b/pack/acp/start/ale/autoload/ale/d.vim new file mode 100644 index 0000000..0e23220 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/d.vim @@ -0,0 +1,16 @@ +" Author: Auri +" Description: Functions for integrating with D linters. + +function! ale#d#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 diff --git a/pack/acp/start/ale/autoload/ale/debugging.vim b/pack/acp/start/ale/autoload/ale/debugging.vim new file mode 100644 index 0000000..7cdbaba --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/debugging.vim @@ -0,0 +1,264 @@ +" Author: w0rp +" Description: This file implements debugging information for ALE + +let s:global_variable_list = [ +\ 'ale_cache_executable_check_failures', +\ 'ale_change_sign_column_color', +\ 'ale_command_wrapper', +\ 'ale_completion_delay', +\ 'ale_completion_enabled', +\ 'ale_completion_max_suggestions', +\ 'ale_echo_cursor', +\ 'ale_echo_msg_error_str', +\ 'ale_echo_msg_format', +\ 'ale_echo_msg_info_str', +\ 'ale_echo_msg_warning_str', +\ 'ale_enabled', +\ 'ale_fix_on_save', +\ 'ale_fixers', +\ 'ale_history_enabled', +\ 'ale_history_log_output', +\ 'ale_keep_list_window_open', +\ 'ale_lint_delay', +\ 'ale_lint_on_enter', +\ 'ale_lint_on_filetype_changed', +\ 'ale_lint_on_insert_leave', +\ 'ale_lint_on_save', +\ 'ale_lint_on_text_changed', +\ 'ale_linter_aliases', +\ 'ale_linters', +\ 'ale_linters_explicit', +\ 'ale_list_vertical', +\ 'ale_list_window_size', +\ 'ale_loclist_msg_format', +\ 'ale_lsp_root', +\ 'ale_max_buffer_history_size', +\ 'ale_max_signs', +\ 'ale_maximum_file_size', +\ 'ale_open_list', +\ 'ale_pattern_options', +\ 'ale_pattern_options_enabled', +\ 'ale_set_balloons', +\ 'ale_set_highlights', +\ 'ale_set_loclist', +\ 'ale_set_quickfix', +\ 'ale_set_signs', +\ 'ale_sign_column_always', +\ 'ale_sign_error', +\ 'ale_sign_info', +\ 'ale_sign_offset', +\ 'ale_sign_style_error', +\ 'ale_sign_style_warning', +\ 'ale_sign_warning', +\ 'ale_statusline_format', +\ 'ale_type_map', +\ 'ale_use_global_executables', +\ 'ale_virtualtext_cursor', +\ 'ale_warn_about_trailing_blank_lines', +\ 'ale_warn_about_trailing_whitespace', +\] + +function! s:Echo(message) abort + execute 'echo a:message' +endfunction + +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 + call s:Echo('let g:' . l:key . ' = ' . string(g:[l:key])) + + if has_key(b:, l:key) + call s:Echo('let b:' . l:key . ' = ' . string(b:[l:key])) + endif + endfor +endfunction + +function! s:EchoGlobalVariables() abort + for l:key in s:global_variable_list + call s:Echo('let g:' . l:key . ' = ' . string(get(g:, l:key, v:null))) + + if has_key(b:, l:key) + call s:Echo('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 + + call s:Echo('(' . l:status_message . ') ' . string(a:item.command)) + + if g:ale_history_log_output && has_key(a:item, 'output') + if empty(a:item.output) + call s:Echo('') + call s:Echo('<<>>') + call s:Echo('') + else + call s:Echo('') + call s:Echo('<<>>') + + for l:line in a:item.output + call s:Echo(l:line) + endfor + + call s:Echo('<<>>') + call s:Echo('') + endif + endif +endfunction + +" Echo the results of an executable check. +function! s:EchoExecutable(item) abort + call s:Echo(printf( + \ '(executable check - %s) %s', + \ a:item.status ? 'success' : 'failure', + \ a:item.command, + \)) +endfunction + +function! s:EchoCommandHistory() abort + let l:buffer = bufnr('%') + + for l:item in ale#history#Get(l:buffer) + if l:item.job_id is# 'executable' + call s:EchoExecutable(l:item) + else + call s:EchoCommand(l:item) + endif + endfor +endfunction + +function! s:EchoLinterAliases(all_linters) abort + let l:first = 1 + + for l:linter in a:all_linters + if !empty(l:linter.aliases) + if l:first + call s:Echo(' Linter Aliases:') + endif + + let l:first = 0 + + call s:Echo(string(l:linter.name) . ' -> ' . string(l:linter.aliases)) + endif + endfor +endfunction + +function! s:EchoLSPErrorMessages(all_linter_names) abort + let l:lsp_error_messages = get(g:, 'ale_lsp_error_messages', {}) + let l:header_echoed = 0 + + for l:linter_name in a:all_linter_names + let l:error_list = get(l:lsp_error_messages, l:linter_name, []) + + if !empty(l:error_list) + if !l:header_echoed + call s:Echo(' LSP Error Messages:') + call s:Echo('') + endif + + call s:Echo('(Errors for ' . l:linter_name . ')') + + for l:message in l:error_list + for l:line in split(l:message, "\n") + call s:Echo(l:line) + endfor + endfor + endif + endfor +endfunction + +function! ale#debugging#Info() abort + let l:filetype = &filetype + + " We get the list of enabled linters for free by the above function. + let l:enabled_linters = deepcopy(ale#linter#Get(l:filetype)) + + " But have to build the list of available linters ourselves. + let l:all_linters = [] + let l:linter_variable_list = [] + + for l:part in split(l:filetype, '\.') + let l:aliased_filetype = ale#linter#ResolveFiletype(l:part) + call extend(l:all_linters, ale#linter#GetAll(l:aliased_filetype)) + endfor + + let l:all_names = map(copy(l:all_linters), 'v:val[''name'']') + let l:enabled_names = map(copy(l:enabled_linters), 'v:val[''name'']') + + " Load linter variables to display + " This must be done after linters are loaded. + let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names) + + let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype) + let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1])) + let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '') + + call s:Echo(' Current Filetype: ' . l:filetype) + call s:Echo('Available Linters: ' . string(l:all_names)) + call s:EchoLinterAliases(l:all_linters) + call s:Echo(' Enabled Linters: ' . string(l:enabled_names)) + call s:Echo(' Suggested Fixers: ' . l:fixers_string) + call s:Echo(' Linter Variables:') + call s:Echo('') + call s:EchoLinterVariables(l:variable_list) + call s:Echo(' Global Variables:') + call s:Echo('') + call s:EchoGlobalVariables() + call s:EchoLSPErrorMessages(l:all_names) + call s:Echo(' Command History:') + call s:Echo('') + call s:EchoCommandHistory() +endfunction + +function! ale#debugging#InfoToClipboard() abort + if !has('clipboard') + call s:Echo('clipboard not available. Try :ALEInfoToFile instead.') + + return + endif + + redir => l:output + silent call ale#debugging#Info() + redir END + + let @+ = l:output + call s:Echo('ALEInfo copied to your clipboard') +endfunction + +function! ale#debugging#InfoToFile(filename) abort + let l:expanded_filename = expand(a:filename) + + redir => l:output + silent call ale#debugging#Info() + redir END + + call writefile(split(l:output, "\n"), l:expanded_filename) + call s:Echo('ALEInfo written to ' . l:expanded_filename) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/definition.vim b/pack/acp/start/ale/autoload/ale/definition.vim new file mode 100644 index 0000000..3915cac --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/definition.vim @@ -0,0 +1,156 @@ +" Author: w0rp +" Description: Go to definition support for LSP linters. + +let s:go_to_definition_map = {} + +" Enable automatic updates of the tagstack +let g:ale_update_tagstack = get(g:, 'ale_update_tagstack', 1) + +" Used to get the definition map in tests. +function! ale#definition#GetMap() abort + return deepcopy(s:go_to_definition_map) +endfunction + +" Used to set the definition map in tests. +function! ale#definition#SetMap(map) abort + let s:go_to_definition_map = a:map +endfunction + +function! ale#definition#ClearLSPData() abort + let s:go_to_definition_map = {} +endfunction + +function! ale#definition#UpdateTagStack() abort + let l:should_update_tagstack = exists('*gettagstack') && exists('*settagstack') && g:ale_update_tagstack + + if l:should_update_tagstack + " Grab the old location (to jump back to) and the word under the + " cursor (as a label for the tagstack) + let l:old_location = [bufnr('%'), line('.'), col('.'), 0] + let l:tagname = expand('') + let l:winid = win_getid() + call settagstack(l:winid, {'items': [{'from': l:old_location, 'tagname': l:tagname}]}, 'a') + call settagstack(l:winid, {'curidx': len(gettagstack(l:winid)['items']) + 1}) + endif +endfunction + +function! ale#definition#HandleTSServerResponse(conn_id, response) abort + if get(a:response, 'command', '') is# 'definition' + \&& has_key(s:go_to_definition_map, a:response.request_seq) + let l:options = remove(s:go_to_definition_map, a:response.request_seq) + + if get(a:response, 'success', v:false) is v:true && !empty(a:response.body) + let l:filename = a:response.body[0].file + let l:line = a:response.body[0].start.line + let l:column = a:response.body[0].start.offset + + call ale#definition#UpdateTagStack() + call ale#util#Open(l:filename, l:line, l:column, l:options) + endif + endif +endfunction + +function! ale#definition#HandleLSPResponse(conn_id, response) abort + if has_key(a:response, 'id') + \&& has_key(s:go_to_definition_map, a:response.id) + let l:options = remove(s:go_to_definition_map, a:response.id) + + " The result can be a Dictionary item, a List of the same, or null. + let l:result = get(a:response, 'result', v:null) + + if type(l:result) is v:t_dict + let l:result = [l:result] + elseif type(l:result) isnot v:t_list + let l:result = [] + endif + + for l:item in l:result + let l:filename = ale#path#FromURI(l:item.uri) + let l:line = l:item.range.start.line + 1 + let l:column = l:item.range.start.character + 1 + + call ale#definition#UpdateTagStack() + call ale#util#Open(l:filename, l:line, l:column, l:options) + break + endfor + endif +endfunction + +function! s:OnReady(line, column, options, capability, linter, lsp_details) abort + let l:id = a:lsp_details.connection_id + + if !ale#lsp#HasCapability(l:id, a:capability) + return + endif + + let l:buffer = a:lsp_details.buffer + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#definition#HandleTSServerResponse') + \ : function('ale#definition#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#Definition( + \ l:buffer, + \ a:line, + \ a:column + \) + else + " Send a message saying the buffer has changed first, or the + " definition position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:buffer) + + " For LSP completions, we need to clamp the column to the length of + " the line. python-language-server and perhaps others do not implement + " this correctly. + if a:capability is# 'definition' + let l:message = ale#lsp#message#Definition(l:buffer, a:line, a:column) + elseif a:capability is# 'typeDefinition' + let l:message = ale#lsp#message#TypeDefinition(l:buffer, a:line, a:column) + else + " XXX: log here? + return + endif + endif + + let l:request_id = ale#lsp#Send(l:id, l:message) + + let s:go_to_definition_map[l:request_id] = { + \ 'open_in': get(a:options, 'open_in', 'current-buffer'), + \} +endfunction + +function! s:GoToLSPDefinition(linter, options, capability) abort + let l:buffer = bufnr('') + let [l:line, l:column] = getpos('.')[1:2] + let l:column = min([l:column, len(getline(l:line))]) + + let l:Callback = function( + \ 's:OnReady', + \ [l:line, l:column, a:options, a:capability] + \) + call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) +endfunction + +function! ale#definition#GoTo(options) abort + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + call s:GoToLSPDefinition(l:linter, a:options, 'definition') + endif + endfor +endfunction + +function! ale#definition#GoToType(options) abort + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + " TODO: handle typeDefinition for tsserver if supported by the + " protocol + if l:linter.lsp is# 'tsserver' + continue + endif + + call s:GoToLSPDefinition(l:linter, a:options, 'typeDefinition') + endif + endfor +endfunction diff --git a/pack/acp/start/ale/autoload/ale/engine.vim b/pack/acp/start/ale/autoload/ale/engine.vim new file mode 100644 index 0000000..491d3c2 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/engine.vim @@ -0,0 +1,733 @@ +" Author: w0rp +" Description: Backend execution and job management +" Executes linters in the background, using NeoVim or Vim 8 jobs + +" Remapping of linter problems. +let g:ale_type_map = get(g:, 'ale_type_map', {}) + +if !has_key(s:, 'executable_cache_map') + let s:executable_cache_map = {} +endif + +function! ale#engine#CleanupEveryBuffer() abort + for l:key in keys(g:ale_buffer_info) + " The key could be a filename or a buffer number, so try and + " convert it to a number. We need a number for the other + " functions. + let l:buffer = str2nr(l:key) + + if l:buffer > 0 + " Stop all jobs and clear the results for everything, and delete + " all of the data we stored for the buffer. + call ale#engine#Cleanup(l:buffer) + endif + endfor +endfunction + +function! ale#engine#MarkLinterActive(info, linter) abort + let l:found = 0 + + for l:other_linter in a:info.active_linter_list + if l:other_linter.name is# a:linter.name + let l:found = 1 + break + endif + endfor + + if !l:found + call add(a:info.active_linter_list, a:linter) + endif +endfunction + +function! ale#engine#MarkLinterInactive(info, linter_name) abort + call filter(a:info.active_linter_list, 'v:val.name isnot# a:linter_name') +endfunction + +function! ale#engine#ResetExecutableCache() abort + let s:executable_cache_map = {} +endfunction + +" Check if files are executable, and if they are, remember that they are +" for subsequent calls. We'll keep checking until programs can be executed. +function! ale#engine#IsExecutable(buffer, executable) abort + if empty(a:executable) + " Don't log the executable check if the executable string is empty. + return 0 + endif + + " Check for a cached executable() check. + let l:result = get(s:executable_cache_map, a:executable, v:null) + + if l:result isnot v:null + return l:result + endif + + " Check if the file is executable, and convert -1 to 1. + let l:result = executable(a:executable) isnot 0 + + " Cache the executable check if we found it, or if the option to cache + " failing checks is on. + if l:result || get(g:, 'ale_cache_executable_check_failures', 0) + let s:executable_cache_map[a:executable] = l:result + endif + + if g:ale_history_enabled + call ale#history#Add(a:buffer, l:result, 'executable', a:executable) + endif + + return l:result +endfunction + +function! ale#engine#InitBufferInfo(buffer) abort + if !has_key(g:ale_buffer_info, a:buffer) + " active_linter_list will hold the list of active linter names + " loclist holds the loclist items after all jobs have completed. + let g:ale_buffer_info[a:buffer] = { + \ 'active_linter_list': [], + \ 'active_other_sources_list': [], + \ 'loclist': [], + \} + + return 1 + endif + + return 0 +endfunction + +" This function is documented and part of the public API. +" +" Return 1 if ALE is busy checking a given buffer +function! ale#engine#IsCheckingBuffer(buffer) abort + let l:info = get(g:ale_buffer_info, a:buffer, {}) + + return !empty(get(l:info, 'active_linter_list', [])) + \ || !empty(get(l:info, 'active_other_sources_list', [])) +endfunction + +" Register a temporary file to be managed with the ALE engine for +" a current job run. +function! ale#engine#ManageFile(buffer, filename) abort + if !get(g:, 'ale_ignore_2_4_warnings') + execute 'echom ''ale#engine#ManageFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' + endif + + call ale#command#ManageFile(a:buffer, a:filename) +endfunction + +" Same as the above, but manage an entire directory. +function! ale#engine#ManageDirectory(buffer, directory) abort + if !get(g:, 'ale_ignore_2_4_warnings') + execute 'echom ''ale#engine#ManageDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' + endif + + call ale#command#ManageDirectory(a:buffer, a:directory) +endfunction + +function! ale#engine#CreateFile(buffer) abort + if !get(g:, 'ale_ignore_2_4_warnings') + execute 'echom ''ale#engine#CreateFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' + endif + + return ale#command#CreateFile(a:buffer) +endfunction + +" Create a new temporary directory and manage it in one go. +function! ale#engine#CreateDirectory(buffer) abort + if !get(g:, 'ale_ignore_2_4_warnings') + execute 'echom ''ale#engine#CreateDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' + endif + + return ale#command#CreateDirectory(a:buffer) +endfunction + +function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort + let l:info = get(g:ale_buffer_info, a:buffer, {}) + + if empty(l:info) + return + endif + + if !a:from_other_source + " Remove this linter from the list of active linters. + " This may have already been done when the job exits. + call filter(l:info.active_linter_list, 'v:val.name isnot# a:linter_name') + endif + + " Make some adjustments to the loclists to fix common problems, and also + " to set default values for loclist items. + let l:linter_loclist = ale#engine#FixLocList( + \ a:buffer, + \ a:linter_name, + \ a:from_other_source, + \ a:loclist, + \) + + " Remove previous items for this linter. + call filter(l:info.loclist, 'v:val.linter_name isnot# a:linter_name') + + " We don't need to add items or sort the list when this list is empty. + if !empty(l:linter_loclist) + " Add the new items. + call extend(l:info.loclist, l:linter_loclist) + + " Sort the loclist again. + " We need a sorted list so we can run a binary search against it + " for efficient lookup of the messages in the cursor handler. + call sort(l:info.loclist, 'ale#util#LocItemCompare') + endif + + if ale#ShouldDoNothing(a:buffer) + return + endif + + call ale#engine#SetResults(a:buffer, l:info.loclist) +endfunction + +function! s:HandleExit(job_info, buffer, output, data) abort + let l:buffer_info = get(g:ale_buffer_info, a:buffer) + + if empty(l:buffer_info) + return + endif + + let l:linter = a:job_info.linter + let l:executable = a:job_info.executable + let l:next_chain_index = a:job_info.next_chain_index + + " Remove this job from the list. + call ale#engine#MarkLinterInactive(l:buffer_info, l:linter.name) + + " Stop here if we land in the handle for a job completing if we're in + " a sandbox. + if ale#util#InSandbox() + return + endif + + if has('nvim') && !empty(a:output) && empty(a:output[-1]) + call remove(a:output, -1) + endif + + if l:next_chain_index < len(get(l:linter, 'command_chain', [])) + let [l:command, l:options] = ale#engine#ProcessChain( + \ a:buffer, + \ l:executable, + \ l:linter, + \ l:next_chain_index, + \ a:output, + \) + + call s:RunJob(l:command, l:options) + + return + endif + + try + let l:loclist = ale#util#GetFunction(l:linter.callback)(a:buffer, a:output) + " Handle the function being unknown, or being deleted. + catch /E700/ + let l:loclist = [] + endtry + + call ale#engine#HandleLoclist(l:linter.name, a:buffer, l:loclist, 0) +endfunction + +function! ale#engine#SetResults(buffer, loclist) abort + let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer) + + " Set signs first. This could potentially fix some line numbers. + " The List could be sorted again here by SetSigns. + if g:ale_set_signs + call ale#sign#SetSigns(a:buffer, a:loclist) + endif + + if g:ale_set_quickfix || g:ale_set_loclist + call ale#list#SetLists(a:buffer, a:loclist) + endif + + if exists('*ale#statusline#Update') + " Don't load/run if not already loaded. + call ale#statusline#Update(a:buffer, a:loclist) + endif + + if g:ale_set_highlights + call ale#highlight#SetHighlights(a:buffer, a:loclist) + endif + + if l:linting_is_done + if g:ale_echo_cursor + " Try and echo the warning now. + " This will only do something meaningful if we're in normal mode. + call ale#cursor#EchoCursorWarning() + endif + + if g:ale_virtualtext_cursor + " Try and show the warning now. + " This will only do something meaningful if we're in normal mode. + call ale#virtualtext#ShowCursorWarning() + endif + + " Reset the save event marker, used for opening windows, etc. + call setbufvar(a:buffer, 'ale_save_event_fired', 0) + " Set a marker showing how many times a buffer has been checked. + call setbufvar( + \ a:buffer, + \ 'ale_linted', + \ getbufvar(a:buffer, 'ale_linted', 0) + 1 + \) + + " Automatically remove all managed temporary files and directories + " now that all jobs have completed. + call ale#command#RemoveManagedFiles(a:buffer) + + " Call user autocommands. This allows users to hook into ALE's lint cycle. + silent doautocmd User ALELintPost + endif +endfunction + +function! s:RemapItemTypes(type_map, loclist) abort + for l:item in a:loclist + let l:key = l:item.type + \ . (get(l:item, 'sub_type', '') is# 'style' ? 'S' : '') + let l:new_key = get(a:type_map, l:key, '') + + if l:new_key is# 'E' + \|| l:new_key is# 'ES' + \|| l:new_key is# 'W' + \|| l:new_key is# 'WS' + \|| l:new_key is# 'I' + let l:item.type = l:new_key[0] + + if l:new_key is# 'ES' || l:new_key is# 'WS' + let l:item.sub_type = 'style' + elseif has_key(l:item, 'sub_type') + call remove(l:item, 'sub_type') + endif + endif + endfor +endfunction + +function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist) abort + let l:bufnr_map = {} + let l:new_loclist = [] + + " Some errors have line numbers beyond the end of the file, + " so we need to adjust them so they set the error at the last line + " of the file instead. + let l:last_line_number = ale#util#GetLineCount(a:buffer) + + for l:old_item in a:loclist + " Copy the loclist item with some default values and corrections. + " + " line and column numbers will be converted to numbers. + " The buffer will default to the buffer being checked. + " The vcol setting will default to 0, a byte index. + " The error type will default to 'E' for errors. + " The error number will default to -1. + " + " The line number and text are the only required keys. + " + " The linter_name will be set on the errors so it can be used in + " output, filtering, etc.. + let l:item = { + \ 'bufnr': a:buffer, + \ 'text': l:old_item.text, + \ 'lnum': str2nr(l:old_item.lnum), + \ 'col': str2nr(get(l:old_item, 'col', 0)), + \ 'vcol': 0, + \ 'type': get(l:old_item, 'type', 'E'), + \ 'nr': get(l:old_item, 'nr', -1), + \ 'linter_name': a:linter_name, + \} + + if a:from_other_source + let l:item.from_other_source = 1 + endif + + if has_key(l:old_item, 'code') + let l:item.code = l:old_item.code + endif + + if has_key(l:old_item, 'filename') + \&& !ale#path#IsTempName(l:old_item.filename) + " Use the filename given. + " Temporary files are assumed to be for this buffer, + " and the filename is not included then, because it looks bad + " in the loclist window. + let l:filename = l:old_item.filename + let l:item.filename = l:filename + + if has_key(l:old_item, 'bufnr') + " If a buffer number is also given, include that too. + " If Vim detects that he buffer number is valid, it will + " be used instead of the filename. + let l:item.bufnr = l:old_item.bufnr + elseif has_key(l:bufnr_map, l:filename) + " Get the buffer number from the map, which can be faster. + let l:item.bufnr = l:bufnr_map[l:filename] + else + " Look up the buffer number. + let l:item.bufnr = bufnr(l:filename) + let l:bufnr_map[l:filename] = l:item.bufnr + endif + elseif has_key(l:old_item, 'bufnr') + let l:item.bufnr = l:old_item.bufnr + endif + + if has_key(l:old_item, 'detail') + let l:item.detail = l:old_item.detail + endif + + " Pass on a end_col key if set, used for highlights. + if has_key(l:old_item, 'end_col') + let l:item.end_col = str2nr(l:old_item.end_col) + endif + + if has_key(l:old_item, 'end_lnum') + let l:item.end_lnum = str2nr(l:old_item.end_lnum) + endif + + if has_key(l:old_item, 'sub_type') + let l:item.sub_type = l:old_item.sub_type + endif + + if l:item.lnum < 1 + " When errors appear before line 1, put them at line 1. + let l:item.lnum = 1 + elseif l:item.bufnr == a:buffer && l:item.lnum > l:last_line_number + " When errors go beyond the end of the file, put them at the end. + " This is only done for the current buffer. + let l:item.lnum = l:last_line_number + elseif get(l:old_item, 'vcol', 0) + " Convert virtual column positions to byte positions. + " The positions will be off if the buffer has changed recently. + let l:line = getbufline(a:buffer, l:item.lnum)[0] + + let l:item.col = ale#util#Col(l:line, l:item.col) + + if has_key(l:item, 'end_col') + let l:end_line = get(l:item, 'end_lnum', l:line) != l:line + \ ? getbufline(a:buffer, l:item.end_lnum)[0] + \ : l:line + + let l:item.end_col = ale#util#Col(l:end_line, l:item.end_col) + endif + endif + + call add(l:new_loclist, l:item) + endfor + + let l:type_map = get(ale#Var(a:buffer, 'type_map'), a:linter_name, {}) + + if !empty(l:type_map) + call s:RemapItemTypes(l:type_map, l:new_loclist) + endif + + return l:new_loclist +endfunction + +" Given part of a command, replace any % with %%, so that no characters in +" the string will be replaced with filenames, etc. +function! ale#engine#EscapeCommandPart(command_part) abort + " TODO: Emit deprecation warning here later. + return ale#command#EscapeCommandPart(a:command_part) +endfunction + +" Run a job. +" +" Returns 1 when a job was started successfully. +function! s:RunJob(command, options) abort + if ale#command#IsDeferred(a:command) + let a:command.result_callback = { + \ command -> s:RunJob(command, a:options) + \} + + return 1 + endif + + let l:command = a:command + + if empty(l:command) + return 0 + endif + + let l:executable = a:options.executable + let l:buffer = a:options.buffer + let l:linter = a:options.linter + let l:output_stream = a:options.output_stream + let l:next_chain_index = a:options.next_chain_index + let l:read_buffer = a:options.read_buffer + let l:info = g:ale_buffer_info[l:buffer] + + let l:Callback = function('s:HandleExit', [{ + \ 'linter': l:linter, + \ 'executable': l:executable, + \ 'next_chain_index': l:next_chain_index, + \}]) + let l:result = ale#command#Run(l:buffer, l:command, l:Callback, { + \ 'output_stream': l:output_stream, + \ 'executable': l:executable, + \ 'read_buffer': l:read_buffer, + \ 'log_output': l:next_chain_index >= len(get(l:linter, 'command_chain', [])), + \}) + + " Only proceed if the job is being run. + if empty(l:result) + return 0 + endif + + call ale#engine#MarkLinterActive(l:info, l:linter) + + silent doautocmd User ALEJobStarted + + return 1 +endfunction + +" Determine which commands to run for a link in a command chain, or +" just a regular command. +function! ale#engine#ProcessChain(buffer, executable, linter, chain_index, input) abort + let l:output_stream = get(a:linter, 'output_stream', 'stdout') + let l:read_buffer = a:linter.read_buffer + let l:chain_index = a:chain_index + let l:input = a:input + + while l:chain_index < len(a:linter.command_chain) + " Run a chain of commands, one asynchronous command after the other, + " so that many programs can be run in a sequence. + let l:chain_item = a:linter.command_chain[l:chain_index] + + if l:chain_index == 0 + " The first callback in the chain takes only a buffer number. + let l:command = ale#util#GetFunction(l:chain_item.callback)( + \ a:buffer + \) + else + " The second callback in the chain takes some input too. + let l:command = ale#util#GetFunction(l:chain_item.callback)( + \ a:buffer, + \ l:input + \) + endif + + " If we have a command to run, execute that. + if !empty(l:command) + " The chain item can override the output_stream option. + if has_key(l:chain_item, 'output_stream') + let l:output_stream = l:chain_item.output_stream + endif + + " The chain item can override the read_buffer option. + if has_key(l:chain_item, 'read_buffer') + let l:read_buffer = l:chain_item.read_buffer + elseif l:chain_index != len(a:linter.command_chain) - 1 + " Don't read the buffer for commands besides the last one + " in the chain by default. + let l:read_buffer = 0 + endif + + break + endif + + " Command chain items can return an empty string to indicate that + " a command should be skipped, so we should try the next item + " with no input. + let l:input = [] + let l:chain_index += 1 + endwhile + + return [l:command, { + \ 'executable': a:executable, + \ 'buffer': a:buffer, + \ 'linter': a:linter, + \ 'output_stream': l:output_stream, + \ 'next_chain_index': l:chain_index + 1, + \ 'read_buffer': l:read_buffer, + \}] +endfunction + +function! s:StopCurrentJobs(buffer, clear_lint_file_jobs) abort + let l:info = get(g:ale_buffer_info, a:buffer, {}) + call ale#command#StopJobs(a:buffer, 'linter') + + " Update the active linter list, clearing out anything not running. + if a:clear_lint_file_jobs + call ale#command#StopJobs(a:buffer, 'file_linter') + let l:info.active_linter_list = [] + else + " Keep jobs for linting files when we're only linting buffers. + call filter(l:info.active_linter_list, 'get(v:val, ''lint_file'')') + endif +endfunction + +function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort + " Figure out which linters are still enabled, and remove + " problems for linters which are no longer enabled. + " Problems from other sources will be kept. + let l:name_map = {} + + for l:linter in a:linters + let l:name_map[l:linter.name] = 1 + endfor + + call filter( + \ get(g:ale_buffer_info[a:buffer], 'loclist', []), + \ 'get(v:val, ''from_other_source'') || get(l:name_map, get(v:val, ''linter_name''))', + \) +endfunction + +function! s:AddProblemsFromOtherBuffers(buffer, linters) abort + let l:filename = expand('#' . a:buffer . ':p') + let l:loclist = [] + let l:name_map = {} + + " Build a map of the active linters. + for l:linter in a:linters + let l:name_map[l:linter.name] = 1 + endfor + + " Find the items from other buffers, for the linters that are enabled. + for l:info in values(g:ale_buffer_info) + for l:item in l:info.loclist + if has_key(l:item, 'filename') + \&& l:item.filename is# l:filename + \&& has_key(l:name_map, l:item.linter_name) + " Copy the items and set the buffer numbers to this one. + let l:new_item = copy(l:item) + let l:new_item.bufnr = a:buffer + call add(l:loclist, l:new_item) + endif + endfor + endfor + + if !empty(l:loclist) + call sort(l:loclist, function('ale#util#LocItemCompareWithText')) + call uniq(l:loclist, function('ale#util#LocItemCompareWithText')) + + " Set the loclist variable, used by some parts of ALE. + let g:ale_buffer_info[a:buffer].loclist = l:loclist + call ale#engine#SetResults(a:buffer, l:loclist) + endif +endfunction + +function! s:RunIfExecutable(buffer, linter, executable) abort + if ale#command#IsDeferred(a:executable) + let a:executable.result_callback = { + \ executable -> s:RunIfExecutable(a:buffer, a:linter, executable) + \} + + return 1 + endif + + if ale#engine#IsExecutable(a:buffer, a:executable) + " Use different job types for file or linter jobs. + let l:job_type = a:linter.lint_file ? 'file_linter' : 'linter' + call setbufvar(a:buffer, 'ale_job_type', l:job_type) + + if has_key(a:linter, 'command_chain') + let [l:command, l:options] = ale#engine#ProcessChain( + \ a:buffer, + \ a:executable, + \ a:linter, + \ 0, + \ [] + \) + + return s:RunJob(l:command, l:options) + endif + + let l:command = ale#linter#GetCommand(a:buffer, a:linter) + let l:options = { + \ 'executable': a:executable, + \ 'buffer': a:buffer, + \ 'linter': a:linter, + \ 'output_stream': get(a:linter, 'output_stream', 'stdout'), + \ 'next_chain_index': 1, + \ 'read_buffer': a:linter.read_buffer, + \} + + return s:RunJob(l:command, l:options) + endif + + return 0 +endfunction + +" Run a linter for a buffer. +" +" Returns 1 if the linter was successfully run. +function! s:RunLinter(buffer, linter) abort + if !empty(a:linter.lsp) + return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter) + else + let l:executable = ale#linter#GetExecutable(a:buffer, a:linter) + + return s:RunIfExecutable(a:buffer, a:linter, l:executable) + endif + + return 0 +endfunction + +function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort + " Initialise the buffer information if needed. + let l:new_buffer = ale#engine#InitBufferInfo(a:buffer) + call s:StopCurrentJobs(a:buffer, a:should_lint_file) + call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters) + + " We can only clear the results if we aren't checking the buffer. + let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer) + + silent doautocmd User ALELintPre + + for l:linter in a:linters + " Only run lint_file linters if we should. + if !l:linter.lint_file || a:should_lint_file + if s:RunLinter(a:buffer, l:linter) + " If a single linter ran, we shouldn't clear everything. + let l:can_clear_results = 0 + endif + else + " If we skipped running a lint_file linter still in the list, + " we shouldn't clear everything. + let l:can_clear_results = 0 + endif + endfor + + " Clear the results if we can. This needs to be done when linters are + " disabled, or ALE itself is disabled. + if l:can_clear_results + call ale#engine#SetResults(a:buffer, []) + elseif l:new_buffer + call s:AddProblemsFromOtherBuffers(a:buffer, a:linters) + endif +endfunction + +" Clean up a buffer. +" +" This function will stop all current jobs for the buffer, +" clear the state of everything, and remove the Dictionary for managing +" the buffer. +function! ale#engine#Cleanup(buffer) abort + " Don't bother with cleanup code when newer NeoVim versions are exiting. + if get(v:, 'exiting', v:null) isnot v:null + return + endif + + if exists('*ale#lsp#CloseDocument') + call ale#lsp#CloseDocument(a:buffer) + endif + + if !has_key(g:ale_buffer_info, a:buffer) + return + endif + + call ale#engine#RunLinters(a:buffer, [], 1) + + call remove(g:ale_buffer_info, a:buffer) +endfunction + +" Given a buffer number, return the warnings and errors for a given buffer. +function! ale#engine#GetLoclist(buffer) abort + if !has_key(g:ale_buffer_info, a:buffer) + return [] + endif + + return g:ale_buffer_info[a:buffer].loclist +endfunction diff --git a/pack/acp/start/ale/autoload/ale/engine/ignore.vim b/pack/acp/start/ale/autoload/ale/engine/ignore.vim new file mode 100644 index 0000000..8057465 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/engine/ignore.vim @@ -0,0 +1,50 @@ +" Author: w0rp +" Description: Code for ignoring linters. Only loaded and if configured. + +" Given a filetype and a configuration for ignoring linters, return a List of +" Strings for linter names to ignore. +function! ale#engine#ignore#GetList(filetype, config) abort + if type(a:config) is v:t_list + return a:config + endif + + if type(a:config) is v:t_dict + let l:names_to_remove = [] + + for l:part in split(a:filetype , '\.') + call extend(l:names_to_remove, get(a:config, l:part, [])) + endfor + + return l:names_to_remove + endif + + return [] +endfunction + +" Given a List of linter descriptions, exclude the linters to be ignored. +function! ale#engine#ignore#Exclude(filetype, all_linters, config, disable_lsp) abort + let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config) + let l:filtered_linters = [] + + for l:linter in a:all_linters + let l:name_list = [l:linter.name] + l:linter.aliases + let l:should_include = 1 + + for l:name in l:name_list + if index(l:names_to_remove, l:name) >= 0 + let l:should_include = 0 + break + endif + endfor + + if a:disable_lsp && has_key(l:linter, 'lsp') && l:linter.lsp isnot# '' + let l:should_include = 0 + endif + + if l:should_include + call add(l:filtered_linters, l:linter) + endif + endfor + + return l:filtered_linters +endfunction diff --git a/pack/acp/start/ale/autoload/ale/events.vim b/pack/acp/start/ale/autoload/ale/events.vim new file mode 100644 index 0000000..da554ef --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/events.vim @@ -0,0 +1,155 @@ +" Author: w0rp +" Description: ALE functions for autocmd events. + +" Get the number of milliseconds since some vague, but consistent, point in +" the past. +" +" This function can be used for timing execution, etc. +" +" The time will be returned as a Number. +function! ale#events#ClockMilliseconds() abort + return float2nr(reltimefloat(reltime()) * 1000) +endfunction + +function! ale#events#QuitEvent(buffer) abort + " Remember when ALE is quitting for BufWrite, etc. + call setbufvar(a:buffer, 'ale_quitting', ale#events#ClockMilliseconds()) +endfunction + +function! ale#events#QuitRecently(buffer) abort + let l:time = getbufvar(a:buffer, 'ale_quitting', 0) + + return l:time && ale#events#ClockMilliseconds() - l:time < 1000 +endfunction + +function! ale#events#SaveEvent(buffer) abort + let l:should_lint = ale#Var(a:buffer, 'enabled') && g:ale_lint_on_save + + if l:should_lint + call setbufvar(a:buffer, 'ale_save_event_fired', 1) + endif + + if ale#Var(a:buffer, 'fix_on_save') && !ale#events#QuitRecently(a:buffer) + let l:will_fix = ale#fix#Fix(a:buffer, 'save_file') + let l:should_lint = l:should_lint && !l:will_fix + endif + + if l:should_lint && !ale#events#QuitRecently(a:buffer) + call ale#Queue(0, 'lint_file', a:buffer) + endif +endfunction + +function! ale#events#LintOnEnter(buffer) abort + " Unmark a file as being changed outside of Vim after we try to check it. + call setbufvar(a:buffer, 'ale_file_changed', 0) + + if ale#Var(a:buffer, 'enabled') && g:ale_lint_on_enter + call ale#Queue(0, 'lint_file', a:buffer) + endif +endfunction + +function! ale#events#ReadOrEnterEvent(buffer) abort + " Apply pattern options if the variable is set. + if get(g:, 'ale_pattern_options_enabled', 1) + \&& !empty(get(g:, 'ale_pattern_options')) + call ale#pattern_options#SetOptions(a:buffer) + endif + + " When entering a buffer, we are no longer quitting it. + call setbufvar(a:buffer, 'ale_quitting', 0) + let l:filetype = getbufvar(a:buffer, '&filetype') + call setbufvar(a:buffer, 'ale_original_filetype', l:filetype) + + " If the file changed outside of Vim, check it on BufEnter,BufRead + if getbufvar(a:buffer, 'ale_file_changed') + call ale#events#LintOnEnter(a:buffer) + endif +endfunction + +function! ale#events#FileTypeEvent(buffer, new_filetype) abort + " The old filetype will be set to an empty string by the BuFEnter event, + " and not linting when the old filetype hasn't been set yet prevents + " buffers being checked when you enter them when linting on enter is off. + let l:old_filetype = getbufvar(a:buffer, 'ale_original_filetype', v:null) + + if l:old_filetype isnot v:null + \&& !empty(a:new_filetype) + \&& a:new_filetype isnot# l:old_filetype + " Remember what the new filetype is. + call setbufvar(a:buffer, 'ale_original_filetype', a:new_filetype) + + if g:ale_lint_on_filetype_changed + call ale#Queue(300, 'lint_file', a:buffer) + endif + endif +endfunction + +function! ale#events#FileChangedEvent(buffer) abort + call setbufvar(a:buffer, 'ale_file_changed', 1) + + if bufnr('') == a:buffer + call ale#events#LintOnEnter(a:buffer) + endif +endfunction + +function! ale#events#Init() abort + " This value used to be a Boolean as a Number, and is now a String. + let l:text_changed = '' . g:ale_lint_on_text_changed + + augroup ALEEvents + autocmd! + + " These events always need to be set up. + autocmd BufEnter,BufRead * call ale#events#ReadOrEnterEvent(str2nr(expand(''))) + autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand(''))) + + if g:ale_enabled + if l:text_changed is? 'always' || l:text_changed is# '1' + autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay) + elseif l:text_changed is? 'normal' + autocmd TextChanged * call ale#Queue(g:ale_lint_delay) + elseif l:text_changed is? 'insert' + autocmd TextChangedI * call ale#Queue(g:ale_lint_delay) + endif + + if g:ale_lint_on_enter + autocmd BufWinEnter * call ale#events#LintOnEnter(str2nr(expand(''))) + " Track when the file is changed outside of Vim. + autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand(''))) + endif + + if g:ale_lint_on_filetype_changed + " Only start linting if the FileType actually changes after + " opening a buffer. The FileType will fire when buffers are opened. + autocmd FileType * call ale#events#FileTypeEvent( + \ str2nr(expand('')), + \ expand('') + \) + endif + + if g:ale_lint_on_insert_leave + autocmd InsertLeave * if ale#Var(str2nr(expand('')), 'lint_on_insert_leave') | call ale#Queue(0) | endif + endif + + if g:ale_echo_cursor || g:ale_cursor_detail + autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif + " Look for a warning to echo as soon as we leave Insert mode. + " The script's position variable used when moving the cursor will + " not be changed here. + autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarning() | endif + endif + + if g:ale_virtualtext_cursor + autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarningWithDelay() | endif + " Look for a warning to echo as soon as we leave Insert mode. + " The script's position variable used when moving the cursor will + " not be changed here. + autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarning() | endif + endif + + if g:ale_close_preview_on_insert + autocmd InsertEnter * if exists('*ale#preview#CloseIfTypeMatches') | call ale#preview#CloseIfTypeMatches('ale-preview') | endif + endif + endif + augroup END +endfunction diff --git a/pack/acp/start/ale/autoload/ale/filetypes.vim b/pack/acp/start/ale/autoload/ale/filetypes.vim new file mode 100644 index 0000000..6cdc9ec --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/filetypes.vim @@ -0,0 +1,60 @@ +" Author: w0rp +" Description: This file handles guessing file extensions for filetypes, etc. + +function! ale#filetypes#LoadExtensionMap() abort + " Output includes: + " '*.erl setf erlang' + redir => l:output + silent exec 'autocmd' + redir end + + let l:map = {} + + for l:line in split(l:output, "\n") + " Parse filetypes, like so: + " + " *.erl setf erlang + " *.md set filetype=markdown + " *.snippet setlocal filetype=snippets + let l:match = matchlist(l:line, '\v^ *\*(\.[^ ]+).*set(f *| *filetype=|local *filetype=)([^ ]+)') + + if !empty(l:match) + let l:map[substitute(l:match[3], '^=', '', '')] = l:match[1] + endif + endfor + + return l:map +endfunction + +let s:cached_map = {} + +function! s:GetCachedExtensionMap() abort + if empty(s:cached_map) + let s:cached_map = ale#filetypes#LoadExtensionMap() + endif + + return s:cached_map +endfunction + +function! ale#filetypes#GuessExtension(filetype) abort + let l:map = s:GetCachedExtensionMap() + let l:ext = get(l:map, a:filetype, '') + + " If we have an exact match, like something for javascript.jsx, use that. + if !empty(l:ext) + return l:ext + endif + + " If we don't have an exact match, use the first filetype in the compound + " filetype. + for l:part in split(a:filetype, '\.') + let l:ext = get(l:map, l:part, '') + + if !empty(l:ext) + return l:ext + endif + endfor + + " Return an empty string if we don't find anything. + return '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fix.vim b/pack/acp/start/ale/autoload/ale/fix.vim new file mode 100644 index 0000000..9987fbd --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fix.vim @@ -0,0 +1,416 @@ +call ale#Set('fix_on_save_ignore', {}) + +" Apply fixes queued up for buffers which may be hidden. +" Vim doesn't let you modify hidden buffers. +function! ale#fix#ApplyQueuedFixes(buffer) abort + let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0}) + let l:has_bufline_api = exists('*deletebufline') && exists('*setbufline') + + if !l:data.done || (!l:has_bufline_api && a:buffer isnot bufnr('')) + return + endif + + call remove(g:ale_fix_buffer_data, a:buffer) + + if l:data.changes_made + " If the file is in DOS mode, we have to remove carriage returns from + " the ends of lines before calling setline(), or we will see them + " twice. + let l:new_lines = getbufvar(a:buffer, '&fileformat') is# 'dos' + \ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')') + \ : l:data.output + let l:first_line_to_remove = len(l:new_lines) + 1 + + " Use a Vim API for setting lines in other buffers, if available. + if l:has_bufline_api + call setbufline(a:buffer, 1, l:new_lines) + call deletebufline(a:buffer, l:first_line_to_remove, '$') + " Fall back on setting lines the old way, for the current buffer. + else + let l:old_line_length = len(l:data.lines_before) + + if l:old_line_length >= l:first_line_to_remove + let l:save = winsaveview() + silent execute + \ l:first_line_to_remove . ',' . l:old_line_length . 'd_' + call winrestview(l:save) + endif + + call setline(1, l:new_lines) + endif + + if l:data.should_save + if a:buffer is bufnr('') + if empty(&buftype) + noautocmd :w! + else + set nomodified + endif + else + call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks + call setbufvar(a:buffer, '&modified', 0) + endif + endif + endif + + if l:data.should_save + let l:should_lint = ale#Var(a:buffer, 'fix_on_save') + \ && ale#Var(a:buffer, 'lint_on_save') + else + let l:should_lint = l:data.changes_made + endif + + silent doautocmd User ALEFixPost + + " If ALE linting is enabled, check for problems with the file again after + " fixing problems. + if g:ale_enabled + \&& l:should_lint + \&& !ale#events#QuitRecently(a:buffer) + call ale#Queue(0, l:data.should_save ? 'lint_file' : '') + endif +endfunction + +function! ale#fix#ApplyFixes(buffer, output) abort + let l:data = g:ale_fix_buffer_data[a:buffer] + let l:data.output = a:output + let l:data.changes_made = l:data.lines_before != l:data.output + let l:data.done = 1 + + call ale#command#RemoveManagedFiles(a:buffer) + + if !bufexists(a:buffer) + " Remove the buffer data when it doesn't exist. + call remove(g:ale_fix_buffer_data, a:buffer) + endif + + if l:data.changes_made && bufexists(a:buffer) + let l:lines = getbufline(a:buffer, 1, '$') + + if l:data.lines_before != l:lines + call remove(g:ale_fix_buffer_data, a:buffer) + execute 'echoerr ''The file was changed before fixing finished''' + + return + endif + endif + + " We can only change the lines of a buffer which is currently open, + " so try and apply the fixes to the current buffer. + call ale#fix#ApplyQueuedFixes(a:buffer) +endfunction + +function! s:HandleExit(job_info, buffer, job_output, data) abort + let l:buffer_info = get(g:ale_fix_buffer_data, a:buffer, {}) + + if empty(l:buffer_info) + return + endif + + if a:job_info.read_temporary_file + let l:output = !empty(a:data.temporary_file) + \ ? readfile(a:data.temporary_file) + \ : [] + else + let l:output = a:job_output + endif + + let l:ChainCallback = get(a:job_info, 'chain_with', v:null) + let l:ProcessWith = get(a:job_info, 'process_with', v:null) + + " Post-process the output with a function if we have one. + if l:ProcessWith isnot v:null + let l:output = call(l:ProcessWith, [a:buffer, l:output]) + endif + + " Use the output of the job for changing the file if it isn't empty, + " otherwise skip this job and use the input from before. + " + " We'll use the input from before for chained commands. + if l:ChainCallback is v:null && !empty(split(join(l:output))) + let l:input = l:output + else + let l:input = a:job_info.input + endif + + if l:ChainCallback isnot v:null && !get(g:, 'ale_ignore_2_4_warnings') + execute 'echom ''chain_with is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' + endif + + let l:next_index = l:ChainCallback is v:null + \ ? a:job_info.callback_index + 1 + \ : a:job_info.callback_index + + call s:RunFixer({ + \ 'buffer': a:buffer, + \ 'input': l:input, + \ 'output': l:output, + \ 'callback_list': a:job_info.callback_list, + \ 'callback_index': l:next_index, + \ 'chain_callback': l:ChainCallback, + \}) +endfunction + +function! s:RunJob(result, options) abort + if ale#command#IsDeferred(a:result) + let a:result.result_callback = {x -> s:RunJob(x, a:options)} + + return + endif + + let l:buffer = a:options.buffer + let l:input = a:options.input + + if a:result is 0 || type(a:result) is v:t_list + if type(a:result) is v:t_list + let l:input = a:result + endif + + call s:RunFixer({ + \ 'buffer': l:buffer, + \ 'input': l:input, + \ 'callback_index': a:options.callback_index + 1, + \ 'callback_list': a:options.callback_list, + \}) + + return + endif + + let l:command = get(a:result, 'command', '') + let l:ChainWith = get(a:result, 'chain_with', v:null) + + if empty(l:command) + " If the command is empty, skip to the next item, or call the + " chain_with function. + call s:RunFixer({ + \ 'buffer': l:buffer, + \ 'input': l:input, + \ 'callback_index': a:options.callback_index + (l:ChainWith is v:null), + \ 'callback_list': a:options.callback_list, + \ 'chain_callback': l:ChainWith, + \ 'output': [], + \}) + + return + endif + + let l:read_temporary_file = get(a:result, 'read_temporary_file', 0) + " Default to piping the buffer for the last fixer in the chain. + let l:read_buffer = get(a:result, 'read_buffer', l:ChainWith is v:null) + let l:output_stream = get(a:result, 'output_stream', 'stdout') + + if l:read_temporary_file + let l:output_stream = 'none' + endif + + let l:Callback = function('s:HandleExit', [{ + \ 'input': l:input, + \ 'chain_with': l:ChainWith, + \ 'callback_index': a:options.callback_index, + \ 'callback_list': a:options.callback_list, + \ 'process_with': get(a:result, 'process_with', v:null), + \ 'read_temporary_file': l:read_temporary_file, + \}]) + let l:run_result = ale#command#Run(l:buffer, l:command, l:Callback, { + \ 'output_stream': l:output_stream, + \ 'executable': '', + \ 'read_buffer': l:read_buffer, + \ 'input': l:input, + \ 'log_output': 0, + \}) + + if empty(l:run_result) + call s:RunFixer({ + \ 'buffer': l:buffer, + \ 'input': l:input, + \ 'callback_index': a:options.callback_index + 1, + \ 'callback_list': a:options.callback_list, + \}) + endif +endfunction + +function! s:RunFixer(options) abort + let l:buffer = a:options.buffer + let l:input = a:options.input + let l:index = a:options.callback_index + + if len(a:options.callback_list) <= l:index + call ale#fix#ApplyFixes(l:buffer, l:input) + + return + endif + + let l:ChainCallback = get(a:options, 'chain_callback', v:null) + + let l:Function = l:ChainCallback isnot v:null + \ ? ale#util#GetFunction(l:ChainCallback) + \ : a:options.callback_list[l:index] + + " Record new jobs started as fixer jobs. + call setbufvar(l:buffer, 'ale_job_type', 'fixer') + + if l:ChainCallback isnot v:null + " Chained commands accept (buffer, output, [input]) + let l:result = ale#util#FunctionArgCount(l:Function) == 2 + \ ? call(l:Function, [l:buffer, a:options.output]) + \ : call(l:Function, [l:buffer, a:options.output, copy(l:input)]) + else + " Regular fixer commands accept (buffer, [input]) + let l:result = ale#util#FunctionArgCount(l:Function) == 1 + \ ? call(l:Function, [l:buffer]) + \ : call(l:Function, [l:buffer, copy(l:input)]) + endif + + call s:RunJob(l:result, { + \ 'buffer': l:buffer, + \ 'input': l:input, + \ 'callback_list': a:options.callback_list, + \ 'callback_index': l:index, + \}) +endfunction + +function! s:AddSubCallbacks(full_list, callbacks) abort + if type(a:callbacks) is v:t_string + call add(a:full_list, a:callbacks) + elseif type(a:callbacks) is v:t_list + call extend(a:full_list, a:callbacks) + else + return 0 + endif + + return 1 +endfunction + +function! s:IgnoreFixers(callback_list, filetype, config) abort + if type(a:config) is v:t_list + let l:ignore_list = a:config + else + let l:ignore_list = [] + + for l:part in split(a:filetype , '\.') + call extend(l:ignore_list, get(a:config, l:part, [])) + endfor + endif + + call filter(a:callback_list, 'index(l:ignore_list, v:val) < 0') +endfunction + +function! s:GetCallbacks(buffer, fixing_flag, fixers) abort + if len(a:fixers) + let l:callback_list = a:fixers + elseif type(get(b:, 'ale_fixers')) is v:t_list + " Lists can be used for buffer-local variables only + let l:callback_list = b:ale_fixers + else + " buffer and global options can use dictionaries mapping filetypes to + " callbacks to run. + let l:fixers = ale#Var(a:buffer, 'fixers') + let l:callback_list = [] + let l:matched = 0 + + for l:sub_type in split(&filetype, '\.') + if s:AddSubCallbacks(l:callback_list, get(l:fixers, l:sub_type)) + let l:matched = 1 + endif + endfor + + " If we couldn't find fixers for a filetype, default to '*' fixers. + if !l:matched + call s:AddSubCallbacks(l:callback_list, get(l:fixers, '*')) + endif + endif + + if a:fixing_flag is# 'save_file' + let l:config = ale#Var(a:buffer, 'fix_on_save_ignore') + + if !empty(l:config) + call s:IgnoreFixers(l:callback_list, &filetype, l:config) + endif + endif + + let l:corrected_list = [] + + " Variables with capital characters are needed, or Vim will complain about + " funcref variables. + for l:Item in l:callback_list + if type(l:Item) is v:t_string + let l:Func = ale#fix#registry#GetFunc(l:Item) + + if !empty(l:Func) + let l:Item = l:Func + endif + endif + + try + call add(l:corrected_list, ale#util#GetFunction(l:Item)) + catch /E475/ + " Rethrow exceptions for failing to get a function so we can print + " a friendly message about it. + throw 'BADNAME ' . v:exception + endtry + endfor + + return l:corrected_list +endfunction + +function! ale#fix#InitBufferData(buffer, fixing_flag) abort + " The 'done' flag tells the function for applying changes when fixing + " is complete. + let g:ale_fix_buffer_data[a:buffer] = { + \ 'lines_before': getbufline(a:buffer, 1, '$'), + \ 'done': 0, + \ 'should_save': a:fixing_flag is# 'save_file', + \ 'temporary_directory_list': [], + \} +endfunction + +" Accepts an optional argument for what to do when fixing. +" +" Returns 0 if no fixes can be applied, and 1 if fixing can be done. +function! ale#fix#Fix(buffer, fixing_flag, ...) abort + if a:fixing_flag isnot# '' && a:fixing_flag isnot# 'save_file' + throw "fixing_flag must be either '' or 'save_file'" + endif + + try + let l:callback_list = s:GetCallbacks(a:buffer, a:fixing_flag, a:000) + catch /E700\|BADNAME/ + let l:function_name = join(split(split(v:exception, ':')[3])) + let l:echo_message = printf( + \ 'There is no fixer named `%s`. Check :ALEFixSuggest', + \ l:function_name, + \) + execute 'echom l:echo_message' + + return 0 + endtry + + if empty(l:callback_list) + if a:fixing_flag is# '' + execute 'echom ''No fixers have been defined. Try :ALEFixSuggest''' + endif + + return 0 + endif + + call ale#command#StopJobs(a:buffer, 'fixer') + " Clean up any files we might have left behind from a previous run. + call ale#command#RemoveManagedFiles(a:buffer) + call ale#fix#InitBufferData(a:buffer, a:fixing_flag) + + silent doautocmd User ALEFixPre + + call s:RunFixer({ + \ 'buffer': a:buffer, + \ 'input': g:ale_fix_buffer_data[a:buffer].lines_before, + \ 'callback_index': 0, + \ 'callback_list': l:callback_list, + \}) + + return 1 +endfunction + +" Set up an autocmd command to try and apply buffer fixes when available. +augroup ALEBufferFixGroup + autocmd! + autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand(''))) diff --git a/pack/acp/start/ale/autoload/ale/fix/registry.vim b/pack/acp/start/ale/autoload/ale/fix/registry.vim new file mode 100644 index 0000000..1a8d02e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fix/registry.vim @@ -0,0 +1,524 @@ +" Author: w0rp +" Description: A registry of functions for fixing things. + +let s:default_registry = { +\ 'add_blank_lines_for_python_control_statements': { +\ 'function': 'ale#fixers#generic_python#AddLinesBeforeControlStatements', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Add blank lines before control statements.', +\ }, +\ 'align_help_tags': { +\ 'function': 'ale#fixers#help#AlignTags', +\ 'suggested_filetypes': ['help'], +\ 'description': 'Align help tags to the right margin', +\ }, +\ 'autopep8': { +\ 'function': 'ale#fixers#autopep8#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Fix PEP8 issues with autopep8.', +\ }, +\ 'bibclean': { +\ 'function': 'ale#fixers#bibclean#Fix', +\ 'suggested_filetypes': ['bib'], +\ 'description': 'Format bib files using bibclean.', +\ }, +\ 'black': { +\ 'function': 'ale#fixers#black#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Fix PEP8 issues with black.', +\ }, +\ 'fecs': { +\ 'function': 'ale#fixers#fecs#Fix', +\ 'suggested_filetypes': ['javascript', 'css', 'html'], +\ 'description': 'Apply fecs format to a file.', +\ }, +\ 'tidy': { +\ 'function': 'ale#fixers#tidy#Fix', +\ 'suggested_filetypes': ['html'], +\ 'description': 'Fix HTML files with tidy.', +\ }, +\ 'prettier_standard': { +\ 'function': 'ale#fixers#prettier_standard#Fix', +\ 'suggested_filetypes': ['javascript'], +\ 'description': 'Apply prettier-standard to a file.', +\ 'aliases': ['prettier-standard'], +\ }, +\ 'elm-format': { +\ 'function': 'ale#fixers#elm_format#Fix', +\ 'suggested_filetypes': ['elm'], +\ 'description': 'Apply elm-format to a file.', +\ 'aliases': ['format'], +\ }, +\ 'eslint': { +\ 'function': 'ale#fixers#eslint#Fix', +\ 'suggested_filetypes': ['javascript', 'typescript'], +\ 'description': 'Apply eslint --fix to a file.', +\ }, +\ 'mix_format': { +\ 'function': 'ale#fixers#mix_format#Fix', +\ 'suggested_filetypes': ['elixir'], +\ 'description': 'Apply mix format to a file.', +\ }, +\ 'isort': { +\ 'function': 'ale#fixers#isort#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Sort Python imports with isort.', +\ }, +\ 'prettier': { +\ 'function': 'ale#fixers#prettier#Fix', +\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'html', 'yaml'], +\ 'description': 'Apply prettier to a file.', +\ }, +\ 'prettier_eslint': { +\ 'function': 'ale#fixers#prettier_eslint#Fix', +\ 'suggested_filetypes': ['javascript'], +\ 'description': 'Apply prettier-eslint to a file.', +\ 'aliases': ['prettier-eslint'], +\ }, +\ 'importjs': { +\ 'function': 'ale#fixers#importjs#Fix', +\ 'suggested_filetypes': ['javascript'], +\ 'description': 'automatic imports for javascript', +\ }, +\ 'puppetlint': { +\ 'function': 'ale#fixers#puppetlint#Fix', +\ 'suggested_filetypes': ['puppet'], +\ 'description': 'Run puppet-lint -f on a file.', +\ }, +\ 'remove_trailing_lines': { +\ 'function': 'ale#fixers#generic#RemoveTrailingBlankLines', +\ 'suggested_filetypes': [], +\ 'description': 'Remove all blank lines at the end of a file.', +\ }, +\ 'trim_whitespace': { +\ 'function': 'ale#fixers#generic#TrimWhitespace', +\ 'suggested_filetypes': [], +\ 'description': 'Remove all trailing whitespace characters at the end of every line.', +\ }, +\ 'yapf': { +\ 'function': 'ale#fixers#yapf#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Fix Python files with yapf.', +\ }, +\ 'rubocop': { +\ 'function': 'ale#fixers#rubocop#Fix', +\ 'suggested_filetypes': ['ruby'], +\ 'description': 'Fix ruby files with rubocop --auto-correct.', +\ }, +\ 'rufo': { +\ 'function': 'ale#fixers#rufo#Fix', +\ 'suggested_filetypes': ['ruby'], +\ 'description': 'Fix ruby files with rufo', +\ }, +\ 'scalafmt': { +\ 'function': 'ale#fixers#scalafmt#Fix', +\ 'suggested_filetypes': ['scala'], +\ 'description': 'Fix Scala files using scalafmt', +\ }, +\ 'standard': { +\ 'function': 'ale#fixers#standard#Fix', +\ 'suggested_filetypes': ['javascript'], +\ 'description': 'Fix JavaScript files using standard --fix', +\ }, +\ 'standardrb': { +\ 'function': 'ale#fixers#standardrb#Fix', +\ 'suggested_filetypes': ['ruby'], +\ 'description': 'Fix ruby files with standardrb --fix', +\ }, +\ 'stylelint': { +\ 'function': 'ale#fixers#stylelint#Fix', +\ 'suggested_filetypes': ['css', 'sass', 'scss', 'sugarss', 'stylus'], +\ 'description': 'Fix stylesheet files using stylelint --fix.', +\ }, +\ 'swiftformat': { +\ 'function': 'ale#fixers#swiftformat#Fix', +\ 'suggested_filetypes': ['swift'], +\ 'description': 'Apply SwiftFormat to a file.', +\ }, +\ 'phpcbf': { +\ 'function': 'ale#fixers#phpcbf#Fix', +\ 'suggested_filetypes': ['php'], +\ 'description': 'Fix PHP files with phpcbf.', +\ }, +\ 'php_cs_fixer': { +\ 'function': 'ale#fixers#php_cs_fixer#Fix', +\ 'suggested_filetypes': ['php'], +\ 'description': 'Fix PHP files with php-cs-fixer.', +\ }, +\ 'clang-format': { +\ 'function': 'ale#fixers#clangformat#Fix', +\ 'suggested_filetypes': ['c', 'cpp', 'cuda'], +\ 'description': 'Fix C/C++ and cuda files with clang-format.', +\ }, +\ 'cmakeformat': { +\ 'function': 'ale#fixers#cmakeformat#Fix', +\ 'suggested_filetypes': ['cmake'], +\ 'description': 'Fix CMake files with cmake-format.', +\ }, +\ 'gofmt': { +\ 'function': 'ale#fixers#gofmt#Fix', +\ 'suggested_filetypes': ['go'], +\ 'description': 'Fix Go files with go fmt.', +\ }, +\ 'goimports': { +\ 'function': 'ale#fixers#goimports#Fix', +\ 'suggested_filetypes': ['go'], +\ 'description': 'Fix Go files imports with goimports.', +\ }, +\ 'gomod': { +\ 'function': 'ale#fixers#gomod#Fix', +\ 'suggested_filetypes': ['gomod'], +\ 'description': 'Fix Go module files with go mod edit -fmt.', +\ }, +\ 'tslint': { +\ 'function': 'ale#fixers#tslint#Fix', +\ 'suggested_filetypes': ['typescript'], +\ 'description': 'Fix typescript files with tslint --fix.', +\ }, +\ 'rustfmt': { +\ 'function': 'ale#fixers#rustfmt#Fix', +\ 'suggested_filetypes': ['rust'], +\ 'description': 'Fix Rust files with Rustfmt.', +\ }, +\ 'textlint': { +\ 'function': 'ale#fixers#textlint#Fix', +\ 'suggested_filetypes': ['text','markdown','asciidoc','tex'], +\ 'description': 'Fix text files with textlint --fix', +\ }, +\ 'hackfmt': { +\ 'function': 'ale#fixers#hackfmt#Fix', +\ 'suggested_filetypes': ['hack'], +\ 'description': 'Fix Hack files with hackfmt.', +\ }, +\ 'floskell': { +\ 'function': 'ale#fixers#floskell#Fix', +\ 'suggested_filetypes': ['haskell'], +\ 'description': 'Fix Haskell files with floskell.', +\ }, +\ 'hfmt': { +\ 'function': 'ale#fixers#hfmt#Fix', +\ 'suggested_filetypes': ['haskell'], +\ 'description': 'Fix Haskell files with hfmt.', +\ }, +\ 'brittany': { +\ 'function': 'ale#fixers#brittany#Fix', +\ 'suggested_filetypes': ['haskell'], +\ 'description': 'Fix Haskell files with brittany.', +\ }, +\ 'hlint': { +\ 'function': 'ale#fixers#hlint#Fix', +\ 'suggested_filetypes': ['haskell'], +\ 'description': 'Refactor Haskell files with hlint.', +\ }, +\ 'stylish-haskell': { +\ 'function': 'ale#fixers#stylish_haskell#Fix', +\ 'suggested_filetypes': ['haskell'], +\ 'description': 'Refactor Haskell files with stylish-haskell.', +\ }, +\ 'ocamlformat': { +\ 'function': 'ale#fixers#ocamlformat#Fix', +\ 'suggested_filetypes': ['ocaml'], +\ 'description': 'Fix OCaml files with ocamlformat.', +\ }, +\ 'ocp-indent': { +\ 'function': 'ale#fixers#ocp_indent#Fix', +\ 'suggested_filetypes': ['ocaml'], +\ 'description': 'Fix OCaml files with ocp-indent.', +\ }, +\ 'refmt': { +\ 'function': 'ale#fixers#refmt#Fix', +\ 'suggested_filetypes': ['reason'], +\ 'description': 'Fix ReasonML files with refmt.', +\ }, +\ 'shfmt': { +\ 'function': 'ale#fixers#shfmt#Fix', +\ 'suggested_filetypes': ['sh'], +\ 'description': 'Fix sh files with shfmt.', +\ }, +\ 'sqlfmt': { +\ 'function': 'ale#fixers#sqlfmt#Fix', +\ 'suggested_filetypes': ['sql'], +\ 'description': 'Fix SQL files with sqlfmt.', +\ }, +\ 'google_java_format': { +\ 'function': 'ale#fixers#google_java_format#Fix', +\ 'suggested_filetypes': ['java'], +\ 'description': 'Fix Java files with google-java-format.', +\ }, +\ 'fixjson': { +\ 'function': 'ale#fixers#fixjson#Fix', +\ 'suggested_filetypes': ['json'], +\ 'description': 'Fix JSON files with fixjson.', +\ }, +\ 'jq': { +\ 'function': 'ale#fixers#jq#Fix', +\ 'suggested_filetypes': ['json'], +\ 'description': 'Fix JSON files with jq.', +\ }, +\ 'perltidy': { +\ 'function': 'ale#fixers#perltidy#Fix', +\ 'suggested_filetypes': ['perl'], +\ 'description': 'Fix Perl files with perltidy.', +\ }, +\ 'xo': { +\ 'function': 'ale#fixers#xo#Fix', +\ 'suggested_filetypes': ['javascript', 'typescript'], +\ 'description': 'Fix JavaScript/TypeScript files using xo --fix.', +\ }, +\ 'qmlfmt': { +\ 'function': 'ale#fixers#qmlfmt#Fix', +\ 'suggested_filetypes': ['qml'], +\ 'description': 'Fix QML files with qmlfmt.', +\ }, +\ 'dartfmt': { +\ 'function': 'ale#fixers#dartfmt#Fix', +\ 'suggested_filetypes': ['dart'], +\ 'description': 'Fix Dart files with dartfmt.', +\ }, +\ 'xmllint': { +\ 'function': 'ale#fixers#xmllint#Fix', +\ 'suggested_filetypes': ['xml'], +\ 'description': 'Fix XML files with xmllint.', +\ }, +\ 'uncrustify': { +\ 'function': 'ale#fixers#uncrustify#Fix', +\ 'suggested_filetypes': ['c', 'cpp', 'cs', 'objc', 'objcpp', 'd', 'java', 'p', 'vala' ], +\ 'description': 'Fix C, C++, C#, ObjectiveC, ObjectiveC++, D, Java, Pawn, and VALA files with uncrustify.', +\ }, +\ 'terraform': { +\ 'function': 'ale#fixers#terraform#Fix', +\ 'suggested_filetypes': ['hcl', 'terraform'], +\ 'description': 'Fix tf and hcl files with terraform fmt.', +\ }, +\ 'ktlint': { +\ 'function': 'ale#fixers#ktlint#Fix', +\ 'suggested_filetypes': ['kt'], +\ 'description': 'Fix Kotlin files with ktlint.', +\ }, +\ 'styler': { +\ 'function': 'ale#fixers#styler#Fix', +\ 'suggested_filetypes': ['r', 'rmarkdown'], +\ 'description': 'Fix R files with styler.', +\ }, +\ 'latexindent': { +\ 'function': 'ale#fixers#latexindent#Fix', +\ 'suggested_filetypes': ['tex'], +\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.', +\ }, +\ 'pgformatter': { +\ 'function': 'ale#fixers#pgformatter#Fix', +\ 'suggested_filetypes': ['sql'], +\ 'description': 'A PostgreSQL SQL syntax beautifier', +\ }, +\ 'reorder-python-imports': { +\ 'function': 'ale#fixers#reorder_python_imports#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Sort Python imports with reorder-python-imports.', +\ }, +\} + +" Reset the function registry to the default entries. +function! ale#fix#registry#ResetToDefaults() abort + let s:entries = deepcopy(s:default_registry) + let s:aliases = {} + + " Set up aliases for fixers too. + for [l:key, l:entry] in items(s:entries) + for l:alias in get(l:entry, 'aliases', []) + let s:aliases[l:alias] = l:key + endfor + endfor +endfunction + +" Set up entries now. +call ale#fix#registry#ResetToDefaults() + +" Remove everything from the registry, useful for tests. +function! ale#fix#registry#Clear() abort + let s:entries = {} + let s:aliases = {} +endfunction + +" Add a function for fixing problems to the registry. +" (name, func, filetypes, desc, aliases) +function! ale#fix#registry#Add(name, func, filetypes, desc, ...) abort + " This command will throw from the sandbox. + let &l:equalprg=&l:equalprg + + if type(a:name) isnot v:t_string + throw '''name'' must be a String' + endif + + if type(a:func) isnot v:t_string + throw '''func'' must be a String' + endif + + if type(a:filetypes) isnot v:t_list + throw '''filetypes'' must be a List' + endif + + for l:type in a:filetypes + if type(l:type) isnot v:t_string + throw 'Each entry of ''filetypes'' must be a String' + endif + endfor + + if type(a:desc) isnot v:t_string + throw '''desc'' must be a String' + endif + + let l:aliases = get(a:000, 0, []) + + if type(l:aliases) isnot v:t_list + \|| !empty(filter(copy(l:aliases), 'type(v:val) isnot v:t_string')) + throw '''aliases'' must be a List of String values' + endif + + let s:entries[a:name] = { + \ 'function': a:func, + \ 'suggested_filetypes': a:filetypes, + \ 'description': a:desc, + \} + + " Set up aliases for the fixer. + if !empty(l:aliases) + let s:entries[a:name].aliases = l:aliases + + for l:alias in l:aliases + let s:aliases[l:alias] = a:name + endfor + endif +endfunction + +" Get a function from the registry by its short name. +function! ale#fix#registry#GetFunc(name) abort + " Use the exact name, or an alias. + let l:resolved_name = !has_key(s:entries, a:name) + \ ? get(s:aliases, a:name, a:name) + \ : a:name + + return get(s:entries, l:resolved_name, {'function': ''}).function +endfunction + +function! s:ShouldSuggestForType(suggested_filetypes, type_list) abort + for l:type in a:type_list + if index(a:suggested_filetypes, l:type) >= 0 + return 1 + endif + endfor + + return 0 +endfunction + +function! s:IsGenericFixer(suggested_filetypes) abort + if empty(a:suggested_filetypes) + return 1 + endif + + return 0 +endfunction + +function! s:FormatEntry(key, entry) abort + let l:aliases_str = '' + + " Show aliases in :ALEFixSuggest if they are there. + if !empty(get(a:entry, 'aliases', [])) + let l:aliases_str = ', ' . join( + \ map(copy(a:entry.aliases), 'string(v:val)'), + \ ',' + \) + endif + + return printf( + \ '%s%s - %s', + \ string(a:key), + \ l:aliases_str, + \ a:entry.description, + \) +endfunction + +" Get list of applicable fixers for filetype, including generic fixers +function! ale#fix#registry#GetApplicableFixers(filetype) abort + let l:type_list = split(a:filetype, '\.') + let l:fixer_name_list = [] + + for l:key in sort(keys(s:entries)) + let l:suggested_filetypes = s:entries[l:key].suggested_filetypes + + if s:IsGenericFixer(l:suggested_filetypes) || s:ShouldSuggestForType(l:suggested_filetypes, l:type_list) + call add(l:fixer_name_list, l:key) + endif + endfor + + return l:fixer_name_list +endfunction + +" Function that returns autocomplete candidates for ALEFix command +function! ale#fix#registry#CompleteFixers(ArgLead, CmdLine, CursorPos) abort + return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead') +endfunction + +function! ale#fix#registry#SuggestedFixers(filetype) abort + let l:type_list = split(a:filetype, '\.') + let l:filetype_fixer_list = [] + + for l:key in sort(keys(s:entries)) + let l:suggested_filetypes = s:entries[l:key].suggested_filetypes + + if s:ShouldSuggestForType(l:suggested_filetypes, l:type_list) + call add( + \ l:filetype_fixer_list, + \ s:FormatEntry(l:key, s:entries[l:key]), + \) + endif + endfor + + let l:generic_fixer_list = [] + + for l:key in sort(keys(s:entries)) + if s:IsGenericFixer(s:entries[l:key].suggested_filetypes) + call add( + \ l:generic_fixer_list, + \ s:FormatEntry(l:key, s:entries[l:key]), + \) + endif + endfor + + return [l:filetype_fixer_list, l:generic_fixer_list] +endfunction + +" Suggest functions to use from the registry. +function! ale#fix#registry#Suggest(filetype) abort + let l:suggested = ale#fix#registry#SuggestedFixers(a:filetype) + let l:filetype_fixer_list = l:suggested[0] + let l:generic_fixer_list = l:suggested[1] + + let l:filetype_fixer_header = !empty(l:filetype_fixer_list) + \ ? ['Try the following fixers appropriate for the filetype:', ''] + \ : [] + let l:generic_fixer_header = !empty(l:generic_fixer_list) + \ ? ['Try the following generic fixers:', ''] + \ : [] + + let l:has_both_lists = !empty(l:filetype_fixer_list) && !empty(l:generic_fixer_list) + + let l:lines = + \ l:filetype_fixer_header + \ + l:filetype_fixer_list + \ + (l:has_both_lists ? [''] : []) + \ + l:generic_fixer_header + \ + l:generic_fixer_list + + if empty(l:lines) + let l:lines = ['There is nothing in the registry to suggest.'] + else + let l:lines += ['', 'See :help ale-fix-configuration'] + endif + + let l:lines += ['', 'Press q to close this window'] + + new +set\ filetype=ale-fix-suggest + call setline(1, l:lines) + setlocal nomodified + setlocal nomodifiable +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/autopep8.vim b/pack/acp/start/ale/autoload/ale/fixers/autopep8.vim new file mode 100644 index 0000000..5798d82 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/autopep8.vim @@ -0,0 +1,26 @@ +" Author: w0rp +" Description: Fixing files with autopep8. + +call ale#Set('python_autopep8_executable', 'autopep8') +call ale#Set('python_autopep8_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_autopep8_options', '') + +function! ale#fixers#autopep8#Fix(buffer) abort + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'python_autopep8', + \ ['autopep8'], + \) + + if !executable(l:executable) + return 0 + endif + + let l:options = ale#Var(a:buffer, 'python_autopep8_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -', + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/bibclean.vim b/pack/acp/start/ale/autoload/ale/fixers/bibclean.vim new file mode 100644 index 0000000..89cb97a --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/bibclean.vim @@ -0,0 +1,15 @@ +" Author: Horacio Sanson - https://github.com/hsanson +" Description: Support for bibclean fixer for BibTeX files. + +call ale#Set('bib_bibclean_executable', 'bibclean') +call ale#Set('bib_bibclean_options', '-align-equals') + +function! ale#fixers#bibclean#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'bib_bibclean_options') + let l:executable = ale#Var(a:buffer, 'bib_bibclean_executable') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' ' . (empty(l:options) ? '' : l:options), + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/black.vim b/pack/acp/start/ale/autoload/ale/fixers/black.vim new file mode 100644 index 0000000..367b8d5 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/black.vim @@ -0,0 +1,37 @@ +" Author: w0rp +" Description: Fixing Python files with black. +" +call ale#Set('python_black_executable', 'black') +call ale#Set('python_black_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_black_options', '') +call ale#Set('python_black_auto_pipenv', 0) +call ale#Set('python_black_change_directory', 1) + +function! ale#fixers#black#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_black_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_black', ['black']) +endfunction + +function! ale#fixers#black#Fix(buffer) abort + let l:cd_string = ale#Var(a:buffer, 'python_black_change_directory') + \ ? ale#path#BufferCdString(a:buffer) + \ : '' + + let l:executable = ale#fixers#black#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run black' + \ : '' + + let l:options = ale#Var(a:buffer, 'python_black_options') + + return { + \ 'command': l:cd_string . ale#Escape(l:executable) . l:exec_args + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -', + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/brittany.vim b/pack/acp/start/ale/autoload/ale/fixers/brittany.vim new file mode 100644 index 0000000..c244834 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/brittany.vim @@ -0,0 +1,22 @@ +" Author: eborden , ifyouseewendy , aspidiets +" Description: Integration of brittany with ALE. + +call ale#Set('haskell_brittany_executable', 'brittany') + +function! ale#fixers#brittany#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_brittany_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'brittany') +endfunction + +function! ale#fixers#brittany#Fix(buffer) abort + let l:executable = ale#fixers#brittany#GetExecutable(a:buffer) + + return { + \ 'command': l:executable + \ . ' --write-mode inplace' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction + diff --git a/pack/acp/start/ale/autoload/ale/fixers/clangformat.vim b/pack/acp/start/ale/autoload/ale/fixers/clangformat.vim new file mode 100644 index 0000000..eae1a7b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/clangformat.vim @@ -0,0 +1,22 @@ +scriptencoding utf-8 +" Author: Peter Renström +" Description: Fixing C/C++ files with clang-format. + +call ale#Set('c_clangformat_executable', 'clang-format') +call ale#Set('c_clangformat_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('c_clangformat_options', '') + +function! ale#fixers#clangformat#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'c_clangformat', [ + \ 'clang-format', + \]) +endfunction + +function! ale#fixers#clangformat#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'c_clangformat_options') + + return { + \ 'command': ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer)) + \ . ' ' . l:options, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/cmakeformat.vim b/pack/acp/start/ale/autoload/ale/fixers/cmakeformat.vim new file mode 100644 index 0000000..f40ed6e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/cmakeformat.vim @@ -0,0 +1,18 @@ +" Author: Attila Maczak +" Description: Integration of cmakeformat with ALE. + +call ale#Set('cmake_cmakeformat_executable', 'cmake-format') +call ale#Set('cmake_cmakeformat_options', '') + +function! ale#fixers#cmakeformat#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'cmake_cmakeformat_executable') + let l:options = ale#Var(a:buffer, 'cmake_cmakeformat_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -i ' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/dartfmt.vim b/pack/acp/start/ale/autoload/ale/fixers/dartfmt.vim new file mode 100644 index 0000000..0687d6d --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/dartfmt.vim @@ -0,0 +1,18 @@ +" Author: reisub0 +" Description: Integration of dartfmt with ALE. + +call ale#Set('dart_dartfmt_executable', 'dartfmt') +call ale#Set('dart_dartfmt_options', '') + +function! ale#fixers#dartfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'dart_dartfmt_executable') + let l:options = ale#Var(a:buffer, 'dart_dartfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -w' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/elm_format.vim b/pack/acp/start/ale/autoload/ale/fixers/elm_format.vim new file mode 100644 index 0000000..cd2be2c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/elm_format.vim @@ -0,0 +1,23 @@ +" Author: soywod +" Description: Integration of elm-format with ALE. + +call ale#Set('elm_format_executable', 'elm-format') +call ale#Set('elm_format_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('elm_format_options', '--yes') + +function! ale#fixers#elm_format#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'elm_format', [ + \ 'node_modules/.bin/elm-format', + \]) +endfunction + +function! ale#fixers#elm_format#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'elm_format_options') + + return { + \ 'command': ale#Escape(ale#fixers#elm_format#GetExecutable(a:buffer)) + \ . ' %t' + \ . (empty(l:options) ? '' : ' ' . l:options), + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/eslint.vim b/pack/acp/start/ale/autoload/ale/fixers/eslint.vim new file mode 100644 index 0000000..62e692b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/eslint.vim @@ -0,0 +1,80 @@ +" Author: w0rp +" Description: Fixing files with eslint. + +function! ale#fixers#eslint#Fix(buffer) abort + let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) + let l:command = ale#node#Executable(a:buffer, l:executable) + \ . ' --version' + + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ l:executable, + \ l:command, + \ function('ale#fixers#eslint#ApplyFixForVersion'), + \) +endfunction + +function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort + for l:item in ale#util#FuzzyJSONDecode(a:output, []) + return split(get(l:item, 'output', ''), "\n") + endfor + + return [] +endfunction + +function! ale#fixers#eslint#ProcessEslintDOutput(buffer, output) abort + " If the output is an error message, don't use it. + for l:line in a:output[:10] + if l:line =~# '\v^Error:|^Could not connect' + return [] + endif + endfor + + return a:output +endfunction + +function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort + let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'javascript_eslint_options') + + " Use the configuration file from the options, if configured. + if l:options =~# '\v(^| )-c|(^| )--config' + let l:config = '' + let l:has_config = 1 + else + let l:config = ale#handlers#eslint#FindConfig(a:buffer) + let l:has_config = !empty(l:config) + endif + + if !l:has_config + return 0 + endif + + " Use --fix-to-stdout with eslint_d + if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0]) + return { + \ 'command': ale#node#Executable(a:buffer, l:executable) + \ . ale#Pad(l:options) + \ . ' --stdin-filename %s --stdin --fix-to-stdout', + \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \} + endif + + " 4.9.0 is the first version with --fix-dry-run + if ale#semver#GTE(a:version, [4, 9, 0]) + return { + \ 'command': ale#node#Executable(a:buffer, l:executable) + \ . ale#Pad(l:options) + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \} + endif + + return { + \ 'command': ale#node#Executable(a:buffer, l:executable) + \ . ale#Pad(l:options) + \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') + \ . ' --fix %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/fecs.vim b/pack/acp/start/ale/autoload/ale/fixers/fecs.vim new file mode 100644 index 0000000..d692bc9 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/fecs.vim @@ -0,0 +1,17 @@ +" Author: harttle +" Description: Apply fecs format to a file. + +function! ale#fixers#fecs#Fix(buffer) abort + let l:executable = ale#handlers#fecs#GetExecutable(a:buffer) + + if !executable(l:executable) + return 0 + endif + + let l:config_options = ' format --replace=true %t' + + return { + \ 'command': ale#Escape(l:executable) . l:config_options, + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/fixjson.vim b/pack/acp/start/ale/autoload/ale/fixers/fixjson.vim new file mode 100644 index 0000000..33ce0af --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/fixjson.vim @@ -0,0 +1,28 @@ +" Author: rhysd +" Description: Integration of fixjson with ALE. + +call ale#Set('json_fixjson_executable', 'fixjson') +call ale#Set('json_fixjson_options', '') +call ale#Set('json_fixjson_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#fixjson#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'json_fixjson', [ + \ 'node_modules/.bin/fixjson', + \]) +endfunction + +function! ale#fixers#fixjson#Fix(buffer) abort + let l:executable = ale#Escape(ale#fixers#fixjson#GetExecutable(a:buffer)) + let l:filename = ale#Escape(bufname(a:buffer)) + let l:command = l:executable . ' --stdin-filename ' . l:filename + + let l:options = ale#Var(a:buffer, 'json_fixjson_options') + + if l:options isnot# '' + let l:command .= ' ' . l:options + endif + + return { + \ 'command': l:command + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/floskell.vim b/pack/acp/start/ale/autoload/ale/fixers/floskell.vim new file mode 100644 index 0000000..f0015db --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/floskell.vim @@ -0,0 +1,20 @@ +" Author: robertjlooby +" Description: Integration of floskell with ALE. + +call ale#Set('haskell_floskell_executable', 'floskell') + +function! ale#fixers#floskell#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_floskell_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'floskell') +endfunction + +function! ale#fixers#floskell#Fix(buffer) abort + let l:executable = ale#fixers#floskell#GetExecutable(a:buffer) + + return { + \ 'command': l:executable + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/generic.vim b/pack/acp/start/ale/autoload/ale/fixers/generic.vim new file mode 100644 index 0000000..cb8865b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/generic.vim @@ -0,0 +1,25 @@ +" Author: w0rp +" Description: Generic functions for fixing files with. + +function! ale#fixers#generic#RemoveTrailingBlankLines(buffer, lines) abort + let l:end_index = len(a:lines) - 1 + + while l:end_index > 0 && empty(a:lines[l:end_index]) + let l:end_index -= 1 + endwhile + + return a:lines[:l:end_index] +endfunction + +" Remove all whitespaces at the end of lines +function! ale#fixers#generic#TrimWhitespace(buffer, lines) abort + let l:index = 0 + let l:lines_new = range(len(a:lines)) + + for l:line in a:lines + let l:lines_new[l:index] = substitute(l:line, '\s\+$', '', 'g') + let l:index = l:index + 1 + endfor + + return l:lines_new +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/generic_python.vim b/pack/acp/start/ale/autoload/ale/fixers/generic_python.vim new file mode 100644 index 0000000..d55a23c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/generic_python.vim @@ -0,0 +1,75 @@ +" Author: w0rp +" Description: Generic fixer functions for Python. + +" Add blank lines before control statements. +function! ale#fixers#generic_python#AddLinesBeforeControlStatements(buffer, lines) abort + let l:new_lines = [] + let l:last_indent_size = 0 + let l:last_line_is_blank = 0 + let l:in_docstring = 0 + + for l:line in a:lines + let l:indent_size = len(matchstr(l:line, '^ *')) + + if !l:in_docstring + " Make sure it is not just a single line docstring and then verify + " it's starting a new docstring + if match(l:line, '\v^ *("""|'''''').*("""|'''''')') == -1 + \&& match(l:line, '\v^ *("""|'''''')') >= 0 + let l:in_docstring = 1 + endif + else + if match(l:line, '\v^ *.*("""|'''''')') >= 0 + let l:in_docstring = 0 + endif + endif + + if !l:last_line_is_blank + \&& !l:in_docstring + \&& l:indent_size <= l:last_indent_size + \&& match(l:line, '\v^ *(return|if|for|while|break|continue)(\(| |$)') >= 0 + call add(l:new_lines, '') + endif + + call add(l:new_lines, l:line) + let l:last_indent_size = l:indent_size + let l:last_line_is_blank = empty(split(l:line)) + endfor + + return l:new_lines +endfunction + +" This function breaks up long lines so that autopep8 or other tools can +" fix the badly-indented code which is produced as a result. +function! ale#fixers#generic_python#BreakUpLongLines(buffer, lines) abort + " Default to a maximum line length of 79 + let l:max_line_length = 79 + let l:conf = ale#path#FindNearestFile(a:buffer, 'setup.cfg') + + " Read the maximum line length from setup.cfg + if !empty(l:conf) + for l:match in ale#util#GetMatches( + \ readfile(l:conf), + \ '\v^ *max-line-length *\= *(\d+)', + \) + let l:max_line_length = str2nr(l:match[1]) + endfor + endif + + let l:new_list = [] + + for l:line in a:lines + if len(l:line) > l:max_line_length && l:line !~# '# *noqa' + let l:line = substitute(l:line, '\v([(,])([^)])', '\1\n\2', 'g') + let l:line = substitute(l:line, '\v([^(])([)])', '\1,\n\2', 'g') + + for l:split_line in split(l:line, "\n") + call add(l:new_list, l:split_line) + endfor + else + call add(l:new_list, l:line) + endif + endfor + + return l:new_list +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/gofmt.vim b/pack/acp/start/ale/autoload/ale/fixers/gofmt.vim new file mode 100644 index 0000000..66b67a9 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/gofmt.vim @@ -0,0 +1,18 @@ +" Author: aliou +" Description: Integration of gofmt with ALE. + +call ale#Set('go_gofmt_executable', 'gofmt') +call ale#Set('go_gofmt_options', '') + +function! ale#fixers#gofmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'go_gofmt_executable') + let l:options = ale#Var(a:buffer, 'go_gofmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -l -w' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/goimports.vim b/pack/acp/start/ale/autoload/ale/fixers/goimports.vim new file mode 100644 index 0000000..783d020 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/goimports.vim @@ -0,0 +1,22 @@ +" Author: Jeff Willette +" Description: Integration of goimports with ALE. + +call ale#Set('go_goimports_executable', 'goimports') +call ale#Set('go_goimports_options', '') + +function! ale#fixers#goimports#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'go_goimports_executable') + let l:options = ale#Var(a:buffer, 'go_goimports_options') + + if !executable(l:executable) + return 0 + endif + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -l -w -srcdir %s' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/gomod.vim b/pack/acp/start/ale/autoload/ale/fixers/gomod.vim new file mode 100644 index 0000000..68895f9 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/gomod.vim @@ -0,0 +1,10 @@ +call ale#Set('go_go_executable', 'go') + +function! ale#fixers#gomod#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'go_go_executable') + + return { + \ 'command': ale#Escape(l:executable) . ' mod edit -fmt %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/google_java_format.vim b/pack/acp/start/ale/autoload/ale/fixers/google_java_format.vim new file mode 100644 index 0000000..20086c7 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/google_java_format.vim @@ -0,0 +1,23 @@ +" Author: butlerx +" Description: Integration of Google-java-format with ALE. + +call ale#Set('java_google_java_format_executable', 'google-java-format') +call ale#Set('java_google_java_format_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('java_google_java_format_options', '') + +function! ale#fixers#google_java_format#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'java_google_java_format_options') + let l:executable = ale#Var(a:buffer, 'java_google_java_format_executable') + + if !executable(l:executable) + return 0 + endif + + return { + \ 'command': ale#Escape(l:executable) + \ . ' ' . (empty(l:options) ? '' : ' ' . l:options) + \ . ' --replace' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/hackfmt.vim b/pack/acp/start/ale/autoload/ale/fixers/hackfmt.vim new file mode 100644 index 0000000..bf2d4f7 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/hackfmt.vim @@ -0,0 +1,18 @@ +" Author: Sam Howie +" Description: Integration of hackfmt with ALE. + +call ale#Set('hack_hackfmt_executable', 'hackfmt') +call ale#Set('hack_hackfmt_options', '') + +function! ale#fixers#hackfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'hack_hackfmt_executable') + let l:options = ale#Var(a:buffer, 'hack_hackfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -i' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/help.vim b/pack/acp/start/ale/autoload/ale/fixers/help.vim new file mode 100644 index 0000000..b20740f --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/help.vim @@ -0,0 +1,24 @@ +" Author: w0rp +" Description: Generic fixer functions for Vim help documents. + +function! ale#fixers#help#AlignTags(buffer, lines) abort + let l:new_lines = [] + + for l:line in a:lines + if len(l:line) != 79 + let l:match = matchlist(l:line, '\v +(\*[^*]+\*)$') + + if !empty(l:match) + let l:start = l:line[:-len(l:match[0]) - 1] + let l:tag = l:match[1] + let l:spaces = repeat(' ', 79 - len(l:start) - len(l:tag)) + + let l:line = l:start . l:spaces . l:tag + endif + endif + + call add(l:new_lines, l:line) + endfor + + return l:new_lines +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/hfmt.vim b/pack/acp/start/ale/autoload/ale/fixers/hfmt.vim new file mode 100644 index 0000000..0407b71 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/hfmt.vim @@ -0,0 +1,16 @@ +" Author: zack +" Description: Integration of hfmt with ALE. + +call ale#Set('haskell_hfmt_executable', 'hfmt') + +function! ale#fixers#hfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_hfmt_executable') + + return { + \ 'command': ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hfmt') + \ . ' -w' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction + diff --git a/pack/acp/start/ale/autoload/ale/fixers/hlint.vim b/pack/acp/start/ale/autoload/ale/fixers/hlint.vim new file mode 100644 index 0000000..88779a5 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/hlint.vim @@ -0,0 +1,13 @@ +" Author: eborden +" Description: Integration of hlint refactor with ALE. +" + +function! ale#fixers#hlint#Fix(buffer) abort + return { + \ 'command': ale#handlers#hlint#GetExecutable(a:buffer) + \ . ' --refactor' + \ . ' --refactor-options="--inplace"' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/importjs.vim b/pack/acp/start/ale/autoload/ale/fixers/importjs.vim new file mode 100644 index 0000000..b5487b2 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/importjs.vim @@ -0,0 +1,25 @@ +" Author: Jeff Willette +" Description: Integration of importjs with ALE. + +call ale#Set('javascript_importjs_executable', 'importjs') + +function! ale#fixers#importjs#ProcessOutput(buffer, output) abort + let l:result = ale#util#FuzzyJSONDecode(a:output, []) + + return split(get(l:result, 'fileContent', ''), "\n") +endfunction + +function! ale#fixers#importjs#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'javascript_importjs_executable') + + if !executable(l:executable) + return 0 + endif + + return { + \ 'command': ale#Escape(l:executable) + \ . ' fix' + \ . ' %s', + \ 'process_with': 'ale#fixers#importjs#ProcessOutput', + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/isort.vim b/pack/acp/start/ale/autoload/ale/fixers/isort.vim new file mode 100644 index 0000000..9070fb2 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/isort.vim @@ -0,0 +1,25 @@ +" Author: w0rp +" Description: Fixing Python imports with isort. + +call ale#Set('python_isort_executable', 'isort') +call ale#Set('python_isort_options', '') +call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#isort#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'python_isort_options') + + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'python_isort', + \ ['isort'], + \) + + if !executable(l:executable) + return 0 + endif + + return { + \ 'command': ale#path#BufferCdString(a:buffer) + \ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/jq.vim b/pack/acp/start/ale/autoload/ale/fixers/jq.vim new file mode 100644 index 0000000..cd9b913 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/jq.vim @@ -0,0 +1,22 @@ +call ale#Set('json_jq_executable', 'jq') +call ale#Set('json_jq_options', '') +call ale#Set('json_jq_filters', '.') + +function! ale#fixers#jq#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'json_jq_executable') +endfunction + +function! ale#fixers#jq#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'json_jq_options') + let l:filters = ale#Var(a:buffer, 'json_jq_filters') + + if empty(l:filters) + return 0 + endif + + return { + \ 'command': ale#Escape(ale#fixers#jq#GetExecutable(a:buffer)) + \ . ' ' . l:filters . ' ' + \ . l:options, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/ktlint.vim b/pack/acp/start/ale/autoload/ale/fixers/ktlint.vim new file mode 100644 index 0000000..cb975d6 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/ktlint.vim @@ -0,0 +1,9 @@ +" Author: Michael Phillips +" Description: Fix Kotlin files with ktlint. + +function! ale#fixers#ktlint#Fix(buffer) abort + return { + \ 'command': ale#handlers#ktlint#GetCommand(a:buffer) . ' --format', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/latexindent.vim b/pack/acp/start/ale/autoload/ale/fixers/latexindent.vim new file mode 100644 index 0000000..b0a0884 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/latexindent.vim @@ -0,0 +1,18 @@ +" Author: riley-martine +" Description: Integration of latexindent with ALE. + +call ale#Set('tex_latexindent_executable', 'latexindent') +call ale#Set('tex_latexindent_options', '') + +function! ale#fixers#latexindent#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'tex_latexindent_executable') + let l:options = ale#Var(a:buffer, 'tex_latexindent_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -l -w' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/mix_format.vim b/pack/acp/start/ale/autoload/ale/fixers/mix_format.vim new file mode 100644 index 0000000..7a09170 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/mix_format.vim @@ -0,0 +1,25 @@ +" Author: carakan , Fernando Mendes +" Description: Fixing files with elixir formatter 'mix format'. + +call ale#Set('elixir_mix_executable', 'mix') +call ale#Set('elixir_mix_format_options', '') + +function! ale#fixers#mix_format#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'elixir_mix_executable') +endfunction + +function! ale#fixers#mix_format#GetCommand(buffer) abort + let l:executable = ale#Escape(ale#fixers#mix_format#GetExecutable(a:buffer)) + let l:options = ale#Var(a:buffer, 'elixir_mix_format_options') + + return l:executable . ' format' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' %t' +endfunction + +function! ale#fixers#mix_format#Fix(buffer) abort + return { + \ 'command': ale#fixers#mix_format#GetCommand(a:buffer), + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/ocamlformat.vim b/pack/acp/start/ale/autoload/ale/fixers/ocamlformat.vim new file mode 100644 index 0000000..9b7c3e1 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/ocamlformat.vim @@ -0,0 +1,18 @@ +" Author: Stephen Lumenta <@sbl> +" Description: Integration of ocamlformat with ALE. + +call ale#Set('ocaml_ocamlformat_executable', 'ocamlformat') +call ale#Set('ocaml_ocamlformat_options', '') + +function! ale#fixers#ocamlformat#Fix(buffer) abort + let l:filename = expand('#' . a:buffer . ':p') + let l:executable = ale#Var(a:buffer, 'ocaml_ocamlformat_executable') + let l:options = ale#Var(a:buffer, 'ocaml_ocamlformat_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' --name=' . ale#Escape(l:filename) + \ . ' -' + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/ocp_indent.vim b/pack/acp/start/ale/autoload/ale/fixers/ocp_indent.vim new file mode 100644 index 0000000..e1b047b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/ocp_indent.vim @@ -0,0 +1,18 @@ +" Author: Kanenobu Mitsuru +" Description: Integration of ocp-indent with ALE. + +call ale#Set('ocaml_ocp_indent_executable', 'ocp-indent') +call ale#Set('ocaml_ocp_indent_options', '') +call ale#Set('ocaml_ocp_indent_config', '') + +function! ale#fixers#ocp_indent#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'ocaml_ocp_indent_executable') + let l:config = ale#Var(a:buffer, 'ocaml_ocp_indent_config') + let l:options = ale#Var(a:buffer, 'ocaml_ocp_indent_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:config) ? '' : ' --config=' . ale#Escape(l:config)) + \ . (empty(l:options) ? '': ' ' . l:options) + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/perltidy.vim b/pack/acp/start/ale/autoload/ale/fixers/perltidy.vim new file mode 100644 index 0000000..a55a572 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/perltidy.vim @@ -0,0 +1,18 @@ +" Author: kfly8 +" Description: Integration of perltidy with ALE. + +call ale#Set('perl_perltidy_executable', 'perltidy') +call ale#Set('perl_perltidy_options', '') + +function! ale#fixers#perltidy#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'perl_perltidy_executable') + let l:options = ale#Var(a:buffer, 'perl_perltidy_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -b' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/pgformatter.vim b/pack/acp/start/ale/autoload/ale/fixers/pgformatter.vim new file mode 100644 index 0000000..9ea08ec --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/pgformatter.vim @@ -0,0 +1,12 @@ +call ale#Set('sql_pgformatter_executable', 'pg_format') +call ale#Set('sql_pgformatter_options', '') + +function! ale#fixers#pgformatter#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'sql_pgformatter_executable') + let l:options = ale#Var(a:buffer, 'sql_pgformatter_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options), + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/php_cs_fixer.vim b/pack/acp/start/ale/autoload/ale/fixers/php_cs_fixer.vim new file mode 100644 index 0000000..5c59e26 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/php_cs_fixer.vim @@ -0,0 +1,24 @@ +" Author: Julien Deniau +" Description: Fixing files with php-cs-fixer. + +call ale#Set('php_cs_fixer_executable', 'php-cs-fixer') +call ale#Set('php_cs_fixer_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('php_cs_fixer_options', '') + +function! ale#fixers#php_cs_fixer#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'php_cs_fixer', [ + \ 'vendor/bin/php-cs-fixer', + \ 'php-cs-fixer' + \]) +endfunction + +function! ale#fixers#php_cs_fixer#Fix(buffer) abort + let l:executable = ale#fixers#php_cs_fixer#GetExecutable(a:buffer) + + return { + \ 'command': ale#Escape(l:executable) + \ . ' ' . ale#Var(a:buffer, 'php_cs_fixer_options') + \ . ' fix %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/phpcbf.vim b/pack/acp/start/ale/autoload/ale/fixers/phpcbf.vim new file mode 100644 index 0000000..f14b840 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/phpcbf.vim @@ -0,0 +1,25 @@ +" Author: notomo +" Description: Fixing files with phpcbf. + +call ale#Set('php_phpcbf_standard', '') +call ale#Set('php_phpcbf_executable', 'phpcbf') +call ale#Set('php_phpcbf_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#phpcbf#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'php_phpcbf', [ + \ 'vendor/bin/phpcbf', + \ 'phpcbf' + \]) +endfunction + +function! ale#fixers#phpcbf#Fix(buffer) abort + let l:executable = ale#fixers#phpcbf#GetExecutable(a:buffer) + let l:standard = ale#Var(a:buffer, 'php_phpcbf_standard') + let l:standard_option = !empty(l:standard) + \ ? '--standard=' . l:standard + \ : '' + + return { + \ 'command': ale#Escape(l:executable) . ' --stdin-path=%s ' . l:standard_option . ' -' + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/prettier.vim b/pack/acp/start/ale/autoload/ale/fixers/prettier.vim new file mode 100644 index 0000000..b7f0ecd --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/prettier.vim @@ -0,0 +1,108 @@ +" Author: tunnckoCore (Charlike Mike Reagent) , +" w0rp , morhetz (Pavel Pertsev) +" Description: Integration of Prettier with ALE. + +call ale#Set('javascript_prettier_executable', 'prettier') +call ale#Set('javascript_prettier_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('javascript_prettier_options', '') + +function! ale#fixers#prettier#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'javascript_prettier', [ + \ 'node_modules/.bin/prettier_d', + \ 'node_modules/prettier-cli/index.js', + \ 'node_modules/.bin/prettier', + \]) +endfunction + +function! ale#fixers#prettier#Fix(buffer) abort + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ ale#fixers#prettier#GetExecutable(a:buffer), + \ '%e --version', + \ function('ale#fixers#prettier#ApplyFixForVersion'), + \) +endfunction + +function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort + " If the output is an error message, don't use it. + for l:line in a:output[:10] + if l:line =~# '^\w*Error:' + return [] + endif + endfor + + return a:output +endfunction + +function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort + let l:executable = ale#fixers#prettier#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'javascript_prettier_options') + let l:parser = '' + + " Append the --parser flag depending on the current filetype (unless it's + " already set in g:javascript_prettier_options). + if empty(expand('#' . a:buffer . ':e')) && match(l:options, '--parser') == -1 + " Mimic Prettier's defaults. In cases without a file extension or + " filetype (scratch buffer), Prettier needs `parser` set to know how + " to process the buffer. + if ale#semver#GTE(a:version, [1, 16, 0]) + let l:parser = 'babel' + else + let l:parser = 'babylon' + endif + + let l:prettier_parsers = { + \ 'typescript': 'typescript', + \ 'css': 'css', + \ 'less': 'less', + \ 'scss': 'scss', + \ 'json': 'json', + \ 'json5': 'json5', + \ 'graphql': 'graphql', + \ 'markdown': 'markdown', + \ 'vue': 'vue', + \ 'yaml': 'yaml', + \ 'html': 'html', + \} + + for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.') + if has_key(l:prettier_parsers, l:filetype) + let l:parser = l:prettier_parsers[l:filetype] + break + endif + endfor + endif + + if !empty(l:parser) + let l:options = (!empty(l:options) ? l:options . ' ' : '') . '--parser ' . l:parser + endif + + " Special error handling needed for prettier_d + if l:executable =~# 'prettier_d$' + return { + \ 'command': ale#path#BufferCdString(a:buffer) + \ . ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --stdin-filepath %s --stdin', + \ 'process_with': 'ale#fixers#prettier#ProcessPrettierDOutput', + \} + endif + + " 1.4.0 is the first version with --stdin-filepath + if ale#semver#GTE(a:version, [1, 4, 0]) + return { + \ 'command': ale#path#BufferCdString(a:buffer) + \ . ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --stdin-filepath %s --stdin', + \} + endif + + return { + \ 'command': ale#Escape(l:executable) + \ . ' %t' + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --write', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/prettier_eslint.vim b/pack/acp/start/ale/autoload/ale/fixers/prettier_eslint.vim new file mode 100644 index 0000000..1e66f49 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/prettier_eslint.vim @@ -0,0 +1,56 @@ +" Author: tunnckoCore (Charlike Mike Reagent) , +" w0rp , morhetz (Pavel Pertsev) +" Description: Integration between Prettier and ESLint. + +call ale#Set('javascript_prettier_eslint_executable', 'prettier-eslint') +call ale#Set('javascript_prettier_eslint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('javascript_prettier_eslint_options', '') + +function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'javascript_prettier_eslint', [ + \ 'node_modules/prettier-eslint-cli/dist/index.js', + \ 'node_modules/.bin/prettier-eslint', + \]) +endfunction + +function! ale#fixers#prettier_eslint#Fix(buffer) abort + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ ale#fixers#prettier_eslint#GetExecutable(a:buffer), + \ '%e --version', + \ function('ale#fixers#prettier_eslint#ApplyFixForVersion'), + \) +endfunction + +function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version) abort + let l:options = ale#Var(a:buffer, 'javascript_prettier_eslint_options') + let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer) + + " 4.2.0 is the first version with --eslint-config-path + let l:config = ale#semver#GTE(a:version, [4, 2, 0]) + \ ? ale#handlers#eslint#FindConfig(a:buffer) + \ : '' + let l:eslint_config_option = !empty(l:config) + \ ? ' --eslint-config-path ' . ale#Escape(l:config) + \ : '' + + " 4.4.0 is the first version with --stdin-filepath + if ale#semver#GTE(a:version, [4, 4, 0]) + return { + \ 'command': ale#path#BufferCdString(a:buffer) + \ . ale#Escape(l:executable) + \ . l:eslint_config_option + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --stdin-filepath %s --stdin', + \} + endif + + return { + \ 'command': ale#Escape(l:executable) + \ . ' %t' + \ . l:eslint_config_option + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --write', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/prettier_standard.vim b/pack/acp/start/ale/autoload/ale/fixers/prettier_standard.vim new file mode 100644 index 0000000..b6e0a6f --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/prettier_standard.vim @@ -0,0 +1,24 @@ +" Author: sheerun (Adam Stankiewicz) +" Description: Integration of Prettier Standard with ALE. + +call ale#Set('javascript_prettier_standard_executable', 'prettier-standard') +call ale#Set('javascript_prettier_standard_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('javascript_prettier_standard_options', '') + +function! ale#fixers#prettier_standard#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'javascript_prettier_standard', [ + \ 'node_modules/prettier-standard/lib/index.js', + \ 'node_modules/.bin/prettier-standard', + \]) +endfunction + +function! ale#fixers#prettier_standard#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'javascript_prettier_standard_options') + + return { + \ 'command': ale#Escape(ale#fixers#prettier_standard#GetExecutable(a:buffer)) + \ . ' %t' + \ . ' ' . l:options, + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/puppetlint.vim b/pack/acp/start/ale/autoload/ale/fixers/puppetlint.vim new file mode 100644 index 0000000..bf36e48 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/puppetlint.vim @@ -0,0 +1,22 @@ +" Author: Alexander Olofsson +" Description: puppet-lint fixer + +if !exists('g:ale_puppet_puppetlint_executable') + let g:ale_puppet_puppetlint_executable = 'puppet-lint' +endif + +if !exists('g:ale_puppet_puppetlint_options') + let g:ale_puppet_puppetlint_options = '' +endif + +function! ale#fixers#puppetlint#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'puppet_puppetlint_executable') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' ' . ale#Var(a:buffer, 'puppet_puppetlint_options') + \ . ' --fix' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/qmlfmt.vim b/pack/acp/start/ale/autoload/ale/fixers/qmlfmt.vim new file mode 100644 index 0000000..90b2567 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/qmlfmt.vim @@ -0,0 +1,11 @@ +call ale#Set('qml_qmlfmt_executable', 'qmlfmt') + +function! ale#fixers#qmlfmt#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'qml_qmlfmt_executable') +endfunction + +function! ale#fixers#qmlfmt#Fix(buffer) abort + return { + \ 'command': ale#Escape(ale#fixers#qmlfmt#GetExecutable(a:buffer)), + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/refmt.vim b/pack/acp/start/ale/autoload/ale/fixers/refmt.vim new file mode 100644 index 0000000..514f950 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/refmt.vim @@ -0,0 +1,18 @@ +" Author: Ahmed El Gabri <@ahmedelgabri> +" Description: Integration of refmt with ALE. + +call ale#Set('reasonml_refmt_executable', 'refmt') +call ale#Set('reasonml_refmt_options', '') + +function! ale#fixers#refmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'reasonml_refmt_executable') + let l:options = ale#Var(a:buffer, 'reasonml_refmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' --in-place' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/reorder_python_imports.vim b/pack/acp/start/ale/autoload/ale/fixers/reorder_python_imports.vim new file mode 100644 index 0000000..42a0a6e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/reorder_python_imports.vim @@ -0,0 +1,25 @@ +" Author: jake +" Description: Fixing Python imports with reorder-python-imports. + +call ale#Set('python_reorder_python_imports_executable', 'reorder-python-imports') +call ale#Set('python_reorder_python_imports_options', '') +call ale#Set('python_reorder_python_imports_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#reorder_python_imports#Fix(buffer) abort + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'python_reorder_python_imports', + \ ['reorder-python-imports'], + \) + + if !executable(l:executable) + return 0 + endif + + let l:options = ale#Var(a:buffer, 'python_reorder_python_imports_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/rubocop.vim b/pack/acp/start/ale/autoload/ale/fixers/rubocop.vim new file mode 100644 index 0000000..33ba688 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/rubocop.vim @@ -0,0 +1,20 @@ +call ale#Set('ruby_rubocop_options', '') +call ale#Set('ruby_rubocop_executable', 'rubocop') + +function! ale#fixers#rubocop#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable') + let l:config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml') + let l:options = ale#Var(a:buffer, 'ruby_rubocop_options') + + return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop') + \ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '') + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --auto-correct --force-exclusion %t' +endfunction + +function! ale#fixers#rubocop#Fix(buffer) abort + return { + \ 'command': ale#fixers#rubocop#GetCommand(a:buffer), + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/rufo.vim b/pack/acp/start/ale/autoload/ale/fixers/rufo.vim new file mode 100644 index 0000000..01d537a --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/rufo.vim @@ -0,0 +1,20 @@ +" Author: Fohte (Hayato Kawai) https://github.com/fohte +" Description: Integration of Rufo with ALE. + +call ale#Set('ruby_rufo_executable', 'rufo') + +function! ale#fixers#rufo#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_rufo_executable') + let l:exec_args = l:executable =~? 'bundle$' + \ ? ' exec rufo' + \ : '' + + return ale#Escape(l:executable) . l:exec_args . ' %t' +endfunction + +function! ale#fixers#rufo#Fix(buffer) abort + return { + \ 'command': ale#fixers#rufo#GetCommand(a:buffer), + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/rustfmt.vim b/pack/acp/start/ale/autoload/ale/fixers/rustfmt.vim new file mode 100644 index 0000000..38882fb --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/rustfmt.vim @@ -0,0 +1,15 @@ +" Author: Kelly Fox +" Description: Integration of rustfmt with ALE. + +call ale#Set('rust_rustfmt_executable', 'rustfmt') +call ale#Set('rust_rustfmt_options', '') + +function! ale#fixers#rustfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'rust_rustfmt_executable') + let l:options = ale#Var(a:buffer, 'rust_rustfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options), + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/scalafmt.vim b/pack/acp/start/ale/autoload/ale/fixers/scalafmt.vim new file mode 100644 index 0000000..dd0e774 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/scalafmt.vim @@ -0,0 +1,25 @@ +" Author: Jeffrey Lau https://github.com/zoonfafer +" Description: Integration of Scalafmt with ALE. + +call ale#Set('scala_scalafmt_executable', 'scalafmt') +call ale#Set('scala_scalafmt_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('scala_scalafmt_options', '') + +function! ale#fixers#scalafmt#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'scala_scalafmt_executable') + let l:options = ale#Var(a:buffer, 'scala_scalafmt_options') + let l:exec_args = l:executable =~? 'ng$' + \ ? ' scalafmt' + \ : '' + + return ale#Escape(l:executable) . l:exec_args + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t' +endfunction + +function! ale#fixers#scalafmt#Fix(buffer) abort + return { + \ 'command': ale#fixers#scalafmt#GetCommand(a:buffer), + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/shfmt.vim b/pack/acp/start/ale/autoload/ale/fixers/shfmt.vim new file mode 100644 index 0000000..06e8da5 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/shfmt.vim @@ -0,0 +1,31 @@ +scriptencoding utf-8 +" Author: Simon Bugert +" Description: Fix sh files with shfmt. + +call ale#Set('sh_shfmt_executable', 'shfmt') +call ale#Set('sh_shfmt_options', '') + +function! s:DefaultOption(buffer) abort + if getbufvar(a:buffer, '&expandtab') == 0 + " Tab is used by default + return '' + endif + + let l:tabsize = getbufvar(a:buffer, '&shiftwidth') + + if l:tabsize == 0 + let l:tabsize = getbufvar(a:buffer, '&tabstop') + endif + + return ' -i ' . l:tabsize +endfunction + +function! ale#fixers#shfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'sh_shfmt_executable') + let l:options = ale#Var(a:buffer, 'sh_shfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . (empty(l:options) ? s:DefaultOption(a:buffer) : ' ' . l:options) + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/sqlfmt.vim b/pack/acp/start/ale/autoload/ale/fixers/sqlfmt.vim new file mode 100644 index 0000000..c88a8ec --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/sqlfmt.vim @@ -0,0 +1,13 @@ +call ale#Set('sql_sqlfmt_executable', 'sqlfmt') +call ale#Set('sql_sqlfmt_options', '') + +function! ale#fixers#sqlfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'sql_sqlfmt_executable') + let l:options = ale#Var(a:buffer, 'sql_sqlfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -w' + \ . (empty(l:options) ? '' : ' ' . l:options), + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/standard.vim b/pack/acp/start/ale/autoload/ale/fixers/standard.vim new file mode 100644 index 0000000..77712d4 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/standard.vim @@ -0,0 +1,25 @@ +" Author: Sumner Evans +" Description: Fixing files with Standard. + +call ale#Set('javascript_standard_executable', 'standard') +call ale#Set('javascript_standard_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('javascript_standard_options', '') + +function! ale#fixers#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#fixers#standard#Fix(buffer) abort + let l:executable = ale#fixers#standard#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'javascript_standard_options') + + return { + \ 'command': ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --fix %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/standardrb.vim b/pack/acp/start/ale/autoload/ale/fixers/standardrb.vim new file mode 100644 index 0000000..fab1e2b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/standardrb.vim @@ -0,0 +1,23 @@ +" Author: Justin Searls - https://github.com/searls +" Description: Fix Ruby files with StandardRB. + +call ale#Set('ruby_standardrb_options', '') +call ale#Set('ruby_standardrb_executable', 'standardrb') + +function! ale#fixers#standardrb#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_standardrb_executable') + let l:config = ale#path#FindNearestFile(a:buffer, '.standard.yml') + let l:options = ale#Var(a:buffer, 'ruby_standardrb_options') + + return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb') + \ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '') + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' --fix --force-exclusion %t' +endfunction + +function! ale#fixers#standardrb#Fix(buffer) abort + return { + \ 'command': ale#fixers#standardrb#GetCommand(a:buffer), + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/stylelint.vim b/pack/acp/start/ale/autoload/ale/fixers/stylelint.vim new file mode 100644 index 0000000..6bfb2fd --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/stylelint.vim @@ -0,0 +1,22 @@ +" Author: Mahmoud Mostafa +" Description: Fixing files with stylelint. + +call ale#Set('stylelint_executable', 'stylelint') +call ale#Set('stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#stylelint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'stylelint', [ + \ 'node_modules/stylelint/bin/stylelint.js', + \ 'node_modules/.bin/stylelint', + \]) +endfunction + +function! ale#fixers#stylelint#Fix(buffer) abort + let l:executable = ale#fixers#stylelint#GetExecutable(a:buffer) + + return { + \ 'command': ale#node#Executable(a:buffer, l:executable) + \ . ' --fix %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/styler.vim b/pack/acp/start/ale/autoload/ale/fixers/styler.vim new file mode 100644 index 0000000..7ff3275 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/styler.vim @@ -0,0 +1,16 @@ +" Author: tvatter +" Description: Fixing R files with styler. + +call ale#Set('r_styler_executable', 'Rscript') +call ale#Set('r_styler_options', 'tidyverse_style') + +function! ale#fixers#styler#Fix(buffer) abort + return { + \ 'command': 'Rscript --vanilla -e ' + \ . '"suppressPackageStartupMessages(library(styler));' + \ . 'style_file(commandArgs(TRUE), style = ' + \ . ale#Var(a:buffer, 'r_styler_options') . ')"' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/stylish_haskell.vim b/pack/acp/start/ale/autoload/ale/fixers/stylish_haskell.vim new file mode 100644 index 0000000..ce71c1c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/stylish_haskell.vim @@ -0,0 +1,21 @@ +" Author: eborden +" Description: Integration of stylish-haskell formatting with ALE. +" +call ale#Set('haskell_stylish_haskell_executable', 'stylish-haskell') + +function! ale#fixers#stylish_haskell#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_stylish_haskell_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'stylish-haskell') +endfunction + +function! ale#fixers#stylish_haskell#Fix(buffer) abort + let l:executable = ale#fixers#stylish_haskell#GetExecutable(a:buffer) + + return { + \ 'command': l:executable + \ . ' --inplace' + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/swiftformat.vim b/pack/acp/start/ale/autoload/ale/fixers/swiftformat.vim new file mode 100644 index 0000000..304182b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/swiftformat.vim @@ -0,0 +1,25 @@ +" Author: gfontenot (Gordon Fontenot) +" Description: Integration of SwiftFormat with ALE. + +call ale#Set('swift_swiftformat_executable', 'swiftformat') +call ale#Set('swift_swiftformat_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('swift_swiftformat_options', '') + +function! ale#fixers#swiftformat#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'swift_swiftformat', [ + \ 'Pods/SwiftFormat/CommandLineTool/swiftformat', + \ 'ios/Pods/SwiftFormat/CommandLineTool/swiftformat', + \ 'swiftformat', + \]) +endfunction + +function! ale#fixers#swiftformat#Fix(buffer) abort + let l:options = ale#Var(a:buffer, 'swift_swiftformat_options') + + return { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape(ale#fixers#swiftformat#GetExecutable(a:buffer)) + \ . ' %t' + \ . ' ' . l:options, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/terraform.vim b/pack/acp/start/ale/autoload/ale/fixers/terraform.vim new file mode 100644 index 0000000..bc05380 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/terraform.vim @@ -0,0 +1,17 @@ +" Author: dsifford +" Description: Fixer for terraform and .hcl files + +call ale#Set('terraform_fmt_executable', 'terraform') +call ale#Set('terraform_fmt_options', '') + +function! ale#fixers#terraform#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'terraform_fmt_executable') + let l:options = ale#Var(a:buffer, 'terraform_fmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' fmt' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' -' + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/textlint.vim b/pack/acp/start/ale/autoload/ale/fixers/textlint.vim new file mode 100644 index 0000000..38ab2bf --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/textlint.vim @@ -0,0 +1,15 @@ +" Author: TANIGUCHI Masaya +" Description: Integration of textlint with ALE. + +function! ale#fixers#textlint#Fix(buffer) abort + let l:executable = ale#handlers#textlint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'textlint_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' --fix' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/tidy.vim b/pack/acp/start/ale/autoload/ale/fixers/tidy.vim new file mode 100644 index 0000000..1af4120 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/tidy.vim @@ -0,0 +1,26 @@ +" Author: meain +" Description: Fixing HTML files with tidy. + +call ale#Set('html_tidy_executable', 'tidy') +call ale#Set('html_tidy_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#tidy#Fix(buffer) abort + let l:executable = ale#node#FindExecutable( + \ a:buffer, + \ 'html_tidy', + \ ['tidy'], + \) + + if !executable(l:executable) + return 0 + endif + + let l:config = ale#path#FindNearestFile(a:buffer, '.tidyrc') + let l:config_options = !empty(l:config) + \ ? ' -q --tidy-mark no --show-errors 0 --show-warnings 0 -config ' . ale#Escape(l:config) + \ : ' -q --tidy-mark no --show-errors 0 --show-warnings 0' + + return { + \ 'command': ale#Escape(l:executable) . l:config_options, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/tslint.vim b/pack/acp/start/ale/autoload/ale/fixers/tslint.vim new file mode 100644 index 0000000..b352af3 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/tslint.vim @@ -0,0 +1,22 @@ +" Author: carakan +" Description: Fixing files with tslint. + +function! ale#fixers#tslint#Fix(buffer) abort + let l:executable = ale#handlers#tslint#GetExecutable(a:buffer) + + 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 { + \ 'command': ale#node#Executable(a:buffer, l:executable) + \ . l:tslint_config_option + \ . ' --fix %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/uncrustify.vim b/pack/acp/start/ale/autoload/ale/fixers/uncrustify.vim new file mode 100644 index 0000000..ffec18e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/uncrustify.vim @@ -0,0 +1,16 @@ +" Author: Derek P Sifford +" Description: Fixer for C, C++, C#, ObjectiveC, D, Java, Pawn, and VALA. + +call ale#Set('c_uncrustify_executable', 'uncrustify') +call ale#Set('c_uncrustify_options', '') + +function! ale#fixers#uncrustify#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'c_uncrustify_executable') + let l:options = ale#Var(a:buffer, 'c_uncrustify_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' --no-backup' + \ . (empty(l:options) ? '' : ' ' . l:options) + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/xmllint.vim b/pack/acp/start/ale/autoload/ale/fixers/xmllint.vim new file mode 100644 index 0000000..b14ffd3 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/xmllint.vim @@ -0,0 +1,29 @@ +" Author: Cyril Roelandt +" Description: Integration of xmllint with ALE. + +call ale#Set('xml_xmllint_executable', 'xmllint') +call ale#Set('xml_xmllint_options', '') +call ale#Set('xml_xmllint_indentsize', 2) + +function! ale#fixers#xmllint#Fix(buffer) abort + let l:executable = ale#Escape(ale#Var(a:buffer, 'xml_xmllint_executable')) + let l:filename = ale#Escape(bufname(a:buffer)) + let l:command = l:executable . ' --format ' . l:filename + + let l:indent = ale#Var(a:buffer, 'xml_xmllint_indentsize') + + if l:indent isnot# '' + let l:env = ale#Env('XMLLINT_INDENT', repeat(' ', l:indent)) + let l:command = l:env . l:command + endif + + let l:options = ale#Var(a:buffer, 'xml_xmllint_options') + + if l:options isnot# '' + let l:command .= ' ' . l:options + endif + + return { + \ 'command': l:command + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/xo.vim b/pack/acp/start/ale/autoload/ale/fixers/xo.vim new file mode 100644 index 0000000..882350b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/xo.vim @@ -0,0 +1,23 @@ +" Author: Albert Marquez - https://github.com/a-marquez +" Description: Fixing files with XO. + +call ale#Set('javascript_xo_executable', 'xo') +call ale#Set('javascript_xo_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('javascript_xo_options', '') + +function! ale#fixers#xo#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'javascript_xo', [ + \ 'node_modules/xo/cli.js', + \ 'node_modules/.bin/xo', + \]) +endfunction + +function! ale#fixers#xo#Fix(buffer) abort + let l:executable = ale#fixers#xo#GetExecutable(a:buffer) + + return { + \ 'command': ale#node#Executable(a:buffer, l:executable) + \ . ' --fix %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/fixers/yapf.vim b/pack/acp/start/ale/autoload/ale/fixers/yapf.vim new file mode 100644 index 0000000..f04bb1f --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/fixers/yapf.vim @@ -0,0 +1,26 @@ +" Author: w0rp +" Description: Fixing Python files with yapf. + +call ale#Set('python_yapf_executable', 'yapf') +call ale#Set('python_yapf_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#yapf#Fix(buffer) abort + let l:executable = ale#python#FindExecutable( + \ a:buffer, + \ 'python_yapf', + \ ['yapf'], + \) + + if !executable(l:executable) + return 0 + endif + + let l:config = ale#path#FindNearestFile(a:buffer, '.style.yapf') + let l:config_options = !empty(l:config) + \ ? ' --no-local-style --style ' . ale#Escape(l:config) + \ : '' + + return { + \ 'command': ale#Escape(l:executable) . l:config_options, + \} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/go.vim b/pack/acp/start/ale/autoload/ale/go.vim new file mode 100644 index 0000000..cd7d950 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/go.vim @@ -0,0 +1,27 @@ +" Author: Horacio Sanson https://github.com/hsanson +" Description: Functions for integrating with Go tools + +" Find the nearest dir listed in GOPATH and assume it the root of the go +" project. +function! ale#go#FindProjectRoot(buffer) abort + let l:sep = has('win32') ? ';' : ':' + + let l:filename = ale#path#Simplify(expand('#' . a:buffer . ':p')) + + for l:name in split($GOPATH, l:sep) + let l:path_dir = ale#path#Simplify(l:name) + + " Use the directory from GOPATH if the current filename starts with it. + if l:filename[: len(l:path_dir) - 1] is? l:path_dir + return l:path_dir + endif + endfor + + let l:default_go_path = ale#path#Simplify(expand('~/go')) + + if isdirectory(l:default_go_path) + return l:default_go_path + endif + + return '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/gradle.vim b/pack/acp/start/ale/autoload/ale/gradle.vim new file mode 100644 index 0000000..dc377fb --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/gradle.vim @@ -0,0 +1,67 @@ +" Author: Michael Pardo +" Description: Functions for working with Gradle projects. + +let s:script_path = fnamemodify(resolve(expand(':p')), ':h') +let s:init_path = has('win32') +\ ? s:script_path . '\gradle\init.gradle' +\ : s:script_path . '/gradle/init.gradle' + +function! ale#gradle#GetInitPath() abort + return s:init_path +endfunction + +" Given a buffer number, find a Gradle project root. +function! ale#gradle#FindProjectRoot(buffer) abort + let l:gradlew_path = ale#path#FindNearestFile(a:buffer, 'gradlew') + + if !empty(l:gradlew_path) + return fnamemodify(l:gradlew_path, ':h') + endif + + let l:settings_path = ale#path#FindNearestFile(a:buffer, 'settings.gradle') + + if !empty(l:settings_path) + return fnamemodify(l:settings_path, ':h') + endif + + let l:build_path = ale#path#FindNearestFile(a:buffer, 'build.gradle') + + if !empty(l:build_path) + return fnamemodify(l:build_path, ':h') + endif + + return '' +endfunction + +" Given a buffer number, find the path to the executable. +" First search on the path for 'gradlew', if nothing is found, try the global +" command. Returns an empty string if cannot find the executable. +function! ale#gradle#FindExecutable(buffer) abort + let l:gradlew_path = ale#path#FindNearestFile(a:buffer, 'gradlew') + + if !empty(l:gradlew_path) + return l:gradlew_path + endif + + if executable('gradle') + return 'gradle' + endif + + return '' +endfunction + +" Given a buffer number, build a command to print the classpath of the root +" project. Returns an empty string if cannot build the command. +function! ale#gradle#BuildClasspathCommand(buffer) abort + let l:executable = ale#gradle#FindExecutable(a:buffer) + let l:project_root = ale#gradle#FindProjectRoot(a:buffer) + + if !empty(l:executable) && !empty(l:project_root) + return ale#path#CdString(l:project_root) + \ . ale#Escape(l:executable) + \ . ' -I ' . ale#Escape(s:init_path) + \ . ' -q printClasspath' + endif + + return '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/gradle/init.gradle b/pack/acp/start/ale/autoload/ale/gradle/init.gradle new file mode 100644 index 0000000..fb1db9e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/gradle/init.gradle @@ -0,0 +1,23 @@ +class ClasspathPlugin implements Plugin { + void apply(Project project) { + project.task('printClasspath') { + doLast { + project + .rootProject + .allprojects + .configurations + .flatten() + .findAll { it.name.endsWith('Classpath') } + .collect { it.resolve() } + .flatten() + .unique() + .findAll { it.exists() } + .each { println it } + } + } + } +} + +rootProject { + apply plugin: ClasspathPlugin +} diff --git a/pack/acp/start/ale/autoload/ale/handlers/alex.vim b/pack/acp/start/ale/autoload/ale/handlers/alex.vim new file mode 100644 index 0000000..190a7f8 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/alex.vim @@ -0,0 +1,54 @@ +scriptencoding utf-8 +" Author: Johannes Wienke +" Description: Error handling for errors in alex output format + +function! ale#handlers#alex#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'alex', [ + \ 'node_modules/.bin/alex', + \ 'node_modules/alex/cli.js', + \]) +endfunction + +function! ale#handlers#alex#CreateCommandCallback(flags) abort + return {b -> ale#node#Executable(b, ale#handlers#alex#GetExecutable(b)) + \ . ' %s ' + \ . a:flags} +endfunction + +function! ale#handlers#alex#Handle(buffer, lines) abort + " Example output: + " 6:256-6:262 warning Be careful with “killed”, it’s profane in some cases killed retext-profanities + let l:pattern = '\v^ *(\d+):(\d+)-(\d+):(\d+) +warning +(.{-}) +(.{-}) +(.{-})$' + 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, + \ 'end_lnum': l:match[3] + 0, + \ 'end_col': l:match[4] - 1, + \ 'text': l:match[5] . ' (' . (l:match[7]) . ')', + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction + +" Define a linter for a specific filetype. Accept flags to adapt to the filetype. +" no flags treat input as markdown +" --html treat input as HTML +" --text treat input as plaintext +function! ale#handlers#alex#DefineLinter(filetype, flags) abort + call ale#Set('alex_executable', 'alex') + call ale#Set('alex_use_global', get(g:, 'ale_use_global_executables', 0)) + + call ale#linter#Define(a:filetype, { + \ 'name': 'alex', + \ 'executable': function('ale#handlers#alex#GetExecutable'), + \ 'command': ale#handlers#alex#CreateCommandCallback(a:flags), + \ 'output_stream': 'stderr', + \ 'callback': 'ale#handlers#alex#Handle', + \ 'lint_file': 1, + \}) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/ccls.vim b/pack/acp/start/ale/autoload/ale/handlers/ccls.vim new file mode 100644 index 0000000..1e2aa31 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/ccls.vim @@ -0,0 +1,19 @@ +scriptencoding utf-8 +" Author: Ye Jingchen +" Description: Utilities for ccls + +function! ale#handlers#ccls#GetProjectRoot(buffer) abort + " Try to find ccls configuration files first. + let l:config = ale#path#FindNearestFile(a:buffer, '.ccls-root') + + if empty(l:config) + let l:config = ale#path#FindNearestFile(a:buffer, '.ccls') + endif + + if !empty(l:config) + return fnamemodify(l:config, ':h') + endif + + " Fall back on default project root detection. + return ale#c#FindProjectRoot(a:buffer) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/cppcheck.vim b/pack/acp/start/ale/autoload/ale/handlers/cppcheck.vim new file mode 100644 index 0000000..6d8fa15 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/cppcheck.vim @@ -0,0 +1,62 @@ +" Description: Handle errors for cppcheck. + +function! ale#handlers#cppcheck#GetCdCommand(buffer) abort + let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer) + let l:cd_command = !empty(l:dir) ? ale#path#CdString(l:dir) : '' + + return l:cd_command +endfunction + +function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort + let l:buffer_path_include = '' + + " Get path to this buffer so we can include it into cppcheck with -I + " This could be expanded to get more -I directives from the compile + " command in compile_commands.json, if it's found. + let l:buffer_path = fnamemodify(bufname(a:buffer), ':p:h') + let l:buffer_path_include = ' -I' . ale#Escape(l:buffer_path) + + return l:buffer_path_include +endfunction + +function! ale#handlers#cppcheck#GetCompileCommandsOptions(buffer) abort + " If the current buffer is modified, using compile_commands.json does no + " good, so include the file's directory instead. It's not quite as good as + " using --project, but is at least equivalent to running cppcheck on this + " file manually from the file's directory. + let l:modified = getbufvar(a:buffer, '&modified') + + if l:modified + return '' + endif + + " 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:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer) + + return !empty(l:json_path) + \ ? '--project=' . ale#Escape(l:json_path[len(l:dir) + 1: ]) + \ : '' +endfunction + +function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort + " Look for lines like the following. + " + " [test.cpp:5]: (error) Array 'a[10]' accessed at index 10, which is out of bounds + let l:pattern = '\v^\[(.+):(\d+)\]: \(([a-z]+)\) (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + if ale#path#IsBufferPath(a:buffer, l:match[1]) + call add(l:output, { + \ 'lnum': str2nr(l:match[2]), + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \ 'text': l:match[4], + \}) + endif + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/cpplint.vim b/pack/acp/start/ale/autoload/ale/handlers/cpplint.vim new file mode 100644 index 0000000..5c475a5 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/cpplint.vim @@ -0,0 +1,21 @@ +" Author: Dawid Kurek https://github.com/dawikur +" Description: Handle errors for cpplint. + +function! ale#handlers#cpplint#HandleCppLintFormat(buffer, lines) abort + " Look for lines like the following. + " test.cpp:5: Estra space after ( in function call [whitespace/parents] [4] + 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, + \ 'col': 0, + \ 'text': join(split(l:match[2])), + \ 'code': l:match[3], + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/css.vim b/pack/acp/start/ale/autoload/ale/handlers/css.vim new file mode 100644 index 0000000..de9eadc --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/css.vim @@ -0,0 +1,70 @@ +scriptencoding utf-8 +" Author: w0rp +" Description: Error handling for CSS linters. + +function! ale#handlers#css#HandleCSSLintFormat(buffer, lines) abort + " Matches patterns line the following: + " + " something.css: line 2, col 1, Error - Expected RBRACE at line 2, col 1. (errors) + " something.css: line 2, col 5, Warning - Expected (inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | grid | inline-grid | run-in | ruby | ruby-base | ruby-text | ruby-base-container | ruby-text-container | contents | none | -moz-box | -moz-inline-block | -moz-inline-box | -moz-inline-grid | -moz-inline-stack | -moz-inline-table | -moz-grid | -moz-grid-group | -moz-grid-line | -moz-groupbox | -moz-deck | -moz-popup | -moz-stack | -moz-marker | -webkit-box | -webkit-inline-box | -ms-flexbox | -ms-inline-flexbox | flex | -webkit-flex | inline-flex | -webkit-inline-flex) but found 'wat'. (known-properties) + " + " These errors can be very massive, so the type will be moved to the front + " so you can actually read the error type. + let l:pattern = '\v^.*: line (\d+), col (\d+), (Error|Warning) - (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:match[3] is# 'Warning' ? 'W' : 'E', + \ 'text': l:match[4], + \} + + let l:code_match = matchlist(l:match[4], '\v(.+) \(([^(]+)\)$') + + " Split up the error code and the text if we find one. + if !empty(l:code_match) + let l:item.text = l:code_match[1] + let l:item.code = l:code_match[2] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +function! ale#handlers#css#HandleStyleLintFormat(buffer, lines) abort + let l:exception_pattern = '\v^Error:' + + for l:line in a:lines[:10] + if len(matchlist(l:line, l:exception_pattern)) > 0 + return [{ + \ 'lnum': 1, + \ 'text': 'stylelint exception thrown (type :ALEDetail for more information)', + \ 'detail': join(a:lines, "\n"), + \}] + endif + endfor + + " Matches patterns line the following: + " + " src/main.css + " 108:10 ✖ Unexpected leading zero number-leading-zero + " 116:20 ✖ Expected a trailing semicolon declaration-block-trailing-semicolon + let l:pattern = '\v^.* (\d+):(\d+) \s+(\S+)\s+ (.*[^ ])\s+([^ ]+)\s*$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'type': l:match[3] is# '✖' ? 'E' : 'W', + \ 'text': l:match[4], + \ 'code': l:match[5], + \}) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/elixir.vim b/pack/acp/start/ale/autoload/ale/handlers/elixir.vim new file mode 100644 index 0000000..2fddf8e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/elixir.vim @@ -0,0 +1,28 @@ +" Author: Matteo Centenaro (bugant) - https://github.com/bugant +" Author: Jon Parise +" Description: Functions for working with Elixir projects + +" Find the root directory for an elixir project that uses mix. +function! ale#handlers#elixir#FindMixProjectRoot(buffer) abort + let l:mix_file = ale#path#FindNearestFile(a:buffer, 'mix.exs') + + if !empty(l:mix_file) + return fnamemodify(l:mix_file, ':p:h') + endif + + return '.' +endfunction + +" Similar to ale#handlers#elixir#FindMixProjectRoot but also continue the +" search upward for a potential umbrella project root. If an umbrella root +" does not exist, the initial project root will be returned. +function! ale#handlers#elixir#FindMixUmbrellaRoot(buffer) abort + let l:app_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) + let l:umbrella_root = fnamemodify(l:app_root, ':h:h') + + if filereadable(l:umbrella_root . '/mix.exs') + return l:umbrella_root + endif + + return l:app_root +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/eslint.vim b/pack/acp/start/ale/autoload/ale/handlers/eslint.vim new file mode 100644 index 0000000..4d533ff --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/eslint.vim @@ -0,0 +1,246 @@ +" Author: w0rp +" Description: Functions for working with eslint, for checking or fixing files. + +let s:sep = has('win32') ? '\' : '/' + +call ale#Set('javascript_eslint_options', '') +call ale#Set('javascript_eslint_executable', 'eslint') +call ale#Set('javascript_eslint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('javascript_eslint_suppress_eslintignore', 0) +call ale#Set('javascript_eslint_suppress_missing_config', 0) + +function! ale#handlers#eslint#FindConfig(buffer) abort + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + for l:basename in [ + \ '.eslintrc.js', + \ '.eslintrc.yaml', + \ '.eslintrc.yml', + \ '.eslintrc.json', + \ '.eslintrc', + \] + let l:config = ale#path#Simplify(join([l:path, l:basename], s:sep)) + + if filereadable(l:config) + return l:config + endif + endfor + endfor + + return ale#path#FindNearestFile(a:buffer, 'package.json') +endfunction + +function! ale#handlers#eslint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'javascript_eslint', [ + \ 'node_modules/.bin/eslint_d', + \ 'node_modules/eslint/bin/eslint.js', + \ 'node_modules/.bin/eslint', + \]) +endfunction + +function! ale#handlers#eslint#GetCommand(buffer) abort + let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) + + let l:options = ale#Var(a:buffer, 'javascript_eslint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -f json --stdin --stdin-filename %s' +endfunction + +function! s:AddHintsForTypeScriptParsingErrors(output) abort + for l:item in a:output + let l:item.text = substitute( + \ l:item.text, + \ '^\(Parsing error\)', + \ '\1 (You may need configure typescript-eslint-parser)', + \ '', + \) + endfor +endfunction + +function! s:CheckForBadConfig(buffer, lines) abort + let l:config_error_pattern = '\v^ESLint couldn''t find a configuration file' + \ . '|^Cannot read config file' + \ . '|^.*Configuration for rule .* is invalid' + \ . '|^ImportDeclaration should appear' + + " Look for a message in the first few lines which indicates that + " a configuration file couldn't be found. + for l:line in a:lines[:10] + let l:match = matchlist(l:line, l:config_error_pattern) + + if len(l:match) > 0 + " Don't show the missing config error if we've disabled it. + if ale#Var(a:buffer, 'javascript_eslint_suppress_missing_config') + \&& l:match[0] is# 'ESLint couldn''t find a configuration file' + return 0 + endif + + return 1 + endif + endfor + + return 0 +endfunction + +function! s:parseJSON(buffer, lines) abort + try + let l:parsed = json_decode(a:lines[-1]) + catch + return [] + endtry + + if type(l:parsed) != v:t_list || empty(l:parsed) + return [] + endif + + let l:errors = l:parsed[0]['messages'] + + if empty(l:errors) + return [] + endif + + let l:output = [] + + for l:error in l:errors + let l:obj = ({ + \ 'lnum': get(l:error, 'line', 0), + \ 'text': get(l:error, 'message', ''), + \ 'type': 'E', + \}) + + if get(l:error, 'severity', 0) is# 1 + let l:obj.type = 'W' + endif + + if has_key(l:error, 'ruleId') + let l:code = l:error['ruleId'] + + " Sometimes ESLint returns null here + if !empty(l:code) + let l:obj.code = l:code + endif + endif + + if has_key(l:error, 'column') + let l:obj.col = l:error['column'] + endif + + if has_key(l:error, 'endColumn') + let l:obj.end_col = l:error['endColumn'] - 1 + endif + + if has_key(l:error, 'endLine') + let l:obj.end_lnum = l:error['endLine'] + endif + + call add(l:output, l:obj) + endfor + + return l:output +endfunction + +let s:col_end_patterns = [ +\ '\vParsing error: Unexpected token (.+) ?', +\ '\v''(.+)'' is not defined.', +\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]', +\ '\vUnexpected (console) statement', +\] + +function! s:parseLines(buffer, lines) abort + " Matches patterns line the following: + " + " /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle] + " /path/to/some-filename.js:56:41: Missing semicolon. [Error/semi] + let l:pattern = '^.*:\(\d\+\):\(\d\+\): \(.\+\) \[\(.\+\)\]$' + " This second pattern matches lines like the following: + " + " /path/to/some-filename.js:13:3: Parsing error: Unexpected token + let l:parsing_pattern = '^.*:\(\d\+\):\(\d\+\): \(.\+\)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern]) + let l:text = l:match[3] + + let l:obj = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:text, + \ 'type': 'E', + \} + + " Take the error type from the output if available. + let l:split_code = split(l:match[4], '/') + + if get(l:split_code, 0, '') is# 'Warning' + let l:obj.type = 'W' + endif + + " The code can be something like 'Error/foo/bar', or just 'Error' + if !empty(get(l:split_code, 1)) + let l:obj.code = join(l:split_code[1:], '/') + endif + + for l:col_match in ale#util#GetMatches(l:text, s:col_end_patterns) + let l:obj.end_col = l:obj.col + len(l:col_match[1]) - 1 + endfor + + call add(l:output, l:obj) + endfor + + return l:output +endfunction + +function! s:FilterResult(buffer, obj) abort + if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore') + if a:obj.text =~# '^File ignored' + return 0 + endif + endif + + if has_key(a:obj, 'code') && a:obj.code is# 'no-trailing-spaces' + \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + return 0 + endif + + return 1 +endfunction + +function! s:HandleESLintOutput(buffer, lines, type) abort + if s:CheckForBadConfig(a:buffer, a:lines) + return [{ + \ 'lnum': 1, + \ 'text': 'eslint configuration error (type :ALEDetail for more information)', + \ 'detail': join(a:lines, "\n"), + \}] + endif + + if a:lines == ['Could not connect'] + return [{ + \ 'lnum': 1, + \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', + \}] + endif + + if a:type is# 'json' + let l:output = s:parseJSON(a:buffer, a:lines) + else + let l:output = s:parseLines(a:buffer, a:lines) + endif + + call filter(l:output, {idx, obj -> s:FilterResult(a:buffer, obj)}) + + if expand('#' . a:buffer . ':t') =~? '\.tsx\?$' + call s:AddHintsForTypeScriptParsingErrors(l:output) + endif + + return l:output +endfunction + +function! ale#handlers#eslint#HandleJSON(buffer, lines) abort + return s:HandleESLintOutput(a:buffer, a:lines, 'json') +endfunction + +function! ale#handlers#eslint#Handle(buffer, lines) abort + return s:HandleESLintOutput(a:buffer, a:lines, 'lines') +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/fecs.vim b/pack/acp/start/ale/autoload/ale/handlers/fecs.vim new file mode 100644 index 0000000..5362edb --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/fecs.vim @@ -0,0 +1,52 @@ +" Author: harttle +" Description: fecs http://fecs.baidu.com/ + +call ale#Set('javascript_fecs_executable', 'fecs') +call ale#Set('javascript_fecs_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#handlers#fecs#GetCommand(buffer) abort + return '%e check --colors=false --rule=true %t' +endfunction + +function! ale#handlers#fecs#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'javascript_fecs', [ + \ 'node_modules/.bin/fecs', + \ 'node_modules/fecs/bin/fecs', + \]) +endfunction + +function! ale#handlers#fecs#Handle(buffer, lines) abort + " Matches patterns looking like the following + " + " fecs WARN → line 20, col 25: Unexpected console statement. (no-console) + " fecs ERROR → line 24, col 36: Missing radix parameter. (radix) + " + let l:pattern = '\v^.*(WARN|ERROR)\s+→\s+line (\d+),\s+col\s+(\d+):\s+(.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:obj = { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[4] + \} + + let l:code_match = matchlist(l:match[4], '\v^(.{-})\s*\((.+)\)$') + + if !empty(l:code_match) + let l:obj.code = l:code_match[2] + let l:obj.text = l:code_match[1] + endif + + if l:match[1] is# 'WARN' + let l:obj.type = 'W' + elseif l:match[1] is# 'ERROR' + let l:obj.type = 'E' + endif + + call add(l:output, l:obj) + endfor + + return l:output +endfunction + diff --git a/pack/acp/start/ale/autoload/ale/handlers/flawfinder.vim b/pack/acp/start/ale/autoload/ale/handlers/flawfinder.vim new file mode 100644 index 0000000..b7d2bec --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/flawfinder.vim @@ -0,0 +1,48 @@ +scriptencoding utf-8 +" Author: Christian Gibbons +" Description: This file defines a handler function that should work for the +" flawfinder format with the -CDQS flags. + +" Swiped this function from the GCC handler. Not sure if needed, but doesn't +" hurt to have it. +function! s:RemoveUnicodeQuotes(text) abort + let l:text = a:text + let l:text = substitute(l:text, '[`´‘’]', '''', 'g') + let l:text = substitute(l:text, '\v\\u2018([^\\]+)\\u2019', '''\1''', 'g') + let l:text = substitute(l:text, '[“”]', '"', 'g') + + return l:text +endfunction + +function! ale#handlers#flawfinder#HandleFlawfinderFormat(buffer, lines) abort + " Look for lines like the following. + " + " :12:4: [2] (buffer) char:Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length. + " :31:4: [1] (buffer) strncpy:Easily used incorrectly; doesn't always \0-terminate or check for invalid pointers [MS-banned] (CWE-120). + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ( \[[0-5]\] [^:]+):(.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + " Use severity level to determine if it should be considered a warning + " or error. + let l:severity = str2nr(matchstr(split(l:match[4])[0], '[0-5]')) + + let l:item = { + \ 'lnum': str2nr(l:match[2]), + \ 'col': str2nr(l:match[3]), + \ 'type': (l:severity < ale#Var(a:buffer, 'c_flawfinder_error_severity')) + \ ? 'W' : 'E', + \ 'text': s:RemoveUnicodeQuotes(join(split(l:match[4])[1:]) . ': ' . l:match[5]), + \} + + " If the filename is something like , or -, then + " this is an error for the file we checked. + if l:match[1] isnot# '-' && l:match[1][0] isnot# '<' + let l:item['filename'] = l:match[1] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/gawk.vim b/pack/acp/start/ale/autoload/ale/handlers/gawk.vim new file mode 100644 index 0000000..50bc4c4 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/gawk.vim @@ -0,0 +1,27 @@ +" Author: Anthony DeDominic +" Description: Handle output from gawk's --lint option + +function! ale#handlers#gawk#HandleGawkFormat(buffer, lines) abort + " Look for lines like the following: + " gawk: /tmp/v0fddXz/1/something.awk:1: ^ invalid char ''' in expression + let l:pattern = '^.\{-}:\(\d\+\):\s\+\(warning:\|\^\)\s*\(.*\)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:ecode = 'E' + + if l:match[2] is? 'warning:' + let l:ecode = 'W' + endif + + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': 0, + \ 'text': l:match[3], + \ 'code': 0, + \ 'type': l:ecode, + \}) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/gcc.vim b/pack/acp/start/ale/autoload/ale/handlers/gcc.vim new file mode 100644 index 0000000..ec16b97 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/gcc.vim @@ -0,0 +1,159 @@ +scriptencoding utf-8 +" Author: w0rp +" Description: This file defines a handler function which ought to work for +" any program which outputs errors in the format that GCC uses. + +let s:pragma_error = '#pragma once in main file' + +" Look for lines like the following. +" +" :8:5: warning: conversion lacks type at end of format [-Wformat=] +" :10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’) +" -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004] +let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$' +let s:inline_pattern = '\v inlined from .* at \:(\d+):(\d+):$' + +function! s:IsHeaderFile(filename) abort + return a:filename =~? '\v\.(h|hpp)$' +endfunction + +function! s:RemoveUnicodeQuotes(text) abort + let l:text = a:text + let l:text = substitute(l:text, '[`´‘’]', '''', 'g') + let l:text = substitute(l:text, '\v\\u2018([^\\]+)\\u2019', '''\1''', 'g') + let l:text = substitute(l:text, '[“”]', '"', 'g') + + return l:text +endfunction + +function! s:ParseInlinedFunctionProblems(buffer, lines) abort + let l:output = [] + let l:pos_match = [] + + for l:line in a:lines + let l:match = matchlist(l:line, s:pattern) + + if !empty(l:match) && !empty(l:pos_match) + call add(l:output, { + \ 'lnum': str2nr(l:pos_match[1]), + \ 'col': str2nr(l:pos_match[2]), + \ 'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W', + \ 'text': s:RemoveUnicodeQuotes(l:match[5]), + \}) + endif + + let l:pos_match = matchlist(l:line, s:inline_pattern) + endfor + + return l:output +endfunction + +" Report problems inside of header files just for gcc and clang +function! s:ParseProblemsInHeaders(buffer, lines) abort + let l:output = [] + let l:include_item = {} + + for l:line in a:lines[: -2] + let l:include_match = matchlist(l:line, '\v^In file included from') + + if !empty(l:include_item) + let l:pattern_match = matchlist(l:line, s:pattern) + + if !empty(l:pattern_match) && l:pattern_match[1] is# '' + if has_key(l:include_item, 'lnum') + call add(l:output, l:include_item) + endif + + let l:include_item = {} + + continue + endif + + let l:include_item.detail .= "\n" . l:line + endif + + if !empty(l:include_match) + if empty(l:include_item) + let l:include_item = { + \ 'text': 'Error found in header. See :ALEDetail', + \ 'detail': l:line, + \} + endif + endif + + if !empty(l:include_item) + let l:stdin_match = matchlist(l:line, '\vfrom \:(\d+):(\d*):?$') + + if !empty(l:stdin_match) + let l:include_item.lnum = str2nr(l:stdin_match[1]) + + if str2nr(l:stdin_match[2]) + let l:include_item.col = str2nr(l:stdin_match[2]) + endif + endif + endif + endfor + + if !empty(l:include_item) && has_key(l:include_item, 'lnum') + call add(l:output, l:include_item) + endif + + return l:output +endfunction + +function! ale#handlers#gcc#HandleGCCFormat(buffer, lines) abort + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, s:pattern) + " Filter out the pragma errors + if s:IsHeaderFile(bufname(bufnr(''))) + \&& l:match[5][:len(s:pragma_error) - 1] is# s:pragma_error + continue + endif + + " If the 'error type' is a note, make it detail related to + " the previous error parsed in output + if l:match[4] is# 'note' + if !empty(l:output) + if !has_key(l:output[-1], 'detail') + let l:output[-1].detail = l:output[-1].text + endif + + let l:output[-1].detail = l:output[-1].detail . "\n" + \ . s:RemoveUnicodeQuotes(l:match[0]) + endif + + continue + endif + + let l:item = { + \ 'lnum': str2nr(l:match[2]), + \ 'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W', + \ 'text': s:RemoveUnicodeQuotes(l:match[5]), + \} + + if !empty(l:match[3]) + let l:item.col = str2nr(l:match[3]) + endif + + " If the filename is something like , or -, then + " this is an error for the file we checked. + if l:match[1] isnot# '-' && l:match[1][0] isnot# '<' + let l:item['filename'] = l:match[1] + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +" Handle problems with the GCC format, but report problems inside of headers. +function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort + let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines) + + call extend(l:output, s:ParseInlinedFunctionProblems(a:buffer, a:lines)) + call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines)) + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/go.vim b/pack/acp/start/ale/autoload/ale/handlers/go.vim new file mode 100644 index 0000000..f17cd86 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/go.vim @@ -0,0 +1,26 @@ +" Author: neersighted +" Description: go vet for Go files +" +" Author: John Eikenberry +" Description: updated to work with go1.10 +" +" Author: Ben Paxton +" Description: moved to generic Golang file from govet + +function! ale#handlers#go#Handler(buffer, lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? ?(.+)$' + let l:output = [] + let l:dir = expand('#' . a:buffer . ':p:h') + + 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, + \ 'text': l:match[4], + \ 'type': 'E', + \}) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/haskell.vim b/pack/acp/start/ale/autoload/ale/handlers/haskell.vim new file mode 100644 index 0000000..3613b1b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/haskell.vim @@ -0,0 +1,101 @@ +" Author: w0rp +" Description: Error handling for the format GHC outputs. +" +function! ale#handlers#haskell#GetStackExecutable(bufnr) abort + if ale#path#FindNearestFile(a:bufnr, 'stack.yaml') isnot# '' + return 'stack' + endif + + " if there is no stack.yaml file, we don't use stack even if it exists, + " so we return '', because executable('') apparently always fails + return '' +endfunction + +" Remember the directory used for temporary files for Vim. +let s:temp_dir = fnamemodify(ale#util#Tempname(), ':h') +" Build part of a regular expression for matching ALE temporary filenames. +let s:temp_regex_prefix = +\ '\M' +\ . substitute(s:temp_dir, '\\', '\\\\', 'g') +\ . '\.\{-}' + +function! ale#handlers#haskell#HandleGHCFormat(buffer, lines) abort + " Look for lines like the following. + " + "Appoint/Lib.hs:8:1: warning: + "Appoint/Lib.hs:8:1: + let l:basename = expand('#' . a:buffer . ':t') + " Build a complete regular expression for replacing temporary filenames + " in Haskell error messages with the basename for this file. + let l:temp_filename_regex = s:temp_regex_prefix . l:basename + + let l:pattern = '\v^\s*([a-zA-Z]?:?[^:]+):(\d+):(\d+):(.*)?$' + let l:output = [] + + let l:corrected_lines = [] + + " Group the lines into smaller lists. + for l:line in a:lines + if len(matchlist(l:line, l:pattern)) > 0 + call add(l:corrected_lines, [l:line]) + elseif l:line is# '' + call add(l:corrected_lines, [l:line]) + elseif len(l:corrected_lines) > 0 + call add(l:corrected_lines[-1], l:line) + endif + endfor + + for l:line_list in l:corrected_lines + " Join the smaller lists into one large line to parse. + let l:line = l:line_list[0] + + for l:extra_line in l:line_list[1:] + let l:line .= substitute(l:extra_line, '\v^\s+', ' ', '') + endfor + + 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[4], '\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[4][:0] is# ' ' ? l:match[4][1:] : l:match[4] + endif + + if l:ghc_type is? 'Warning' + let l:type = 'W' + else + let l:type = 'E' + endif + + " Replace temporary filenames in problem messages with the basename + let l:text = substitute(l:text, l:temp_filename_regex, l:basename, 'g') + + let l:item = { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:text, + \ 'type': l:type, + \} + + " Include extra lines as details if they are there. + if len(l:line_list) > 1 + let l:item.detail = join(l:line_list[1:], "\n") + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/haskell_stack.vim b/pack/acp/start/ale/autoload/ale/handlers/haskell_stack.vim new file mode 100644 index 0000000..108301a --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/haskell_stack.vim @@ -0,0 +1,7 @@ +function! ale#handlers#haskell_stack#EscapeExecutable(executable, stack_exec) abort + let l:exec_args = a:executable =~? 'stack$' + \ ? ' exec ' . ale#Escape(a:stack_exec) . ' --' + \ : '' + + return ale#Escape(a:executable) . l:exec_args +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/hlint.vim b/pack/acp/start/ale/autoload/ale/handlers/hlint.vim new file mode 100644 index 0000000..b9a8c32 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/hlint.vim @@ -0,0 +1,8 @@ +call ale#Set('haskell_hlint_executable', 'hlint') +call ale#Set('haskell_hlint_options', get(g:, 'hlint_options', '')) + +function! ale#handlers#hlint#GetExecutable(buffer) abort + let l:executable = ale#Var(a:buffer, 'haskell_hlint_executable') + + return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hlint') +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/ktlint.vim b/pack/acp/start/ale/autoload/ale/handlers/ktlint.vim new file mode 100644 index 0000000..ad99948 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/ktlint.vim @@ -0,0 +1,45 @@ +" Author: Michael Phillips +" Description: Handler functions for ktlint. + +call ale#Set('kotlin_ktlint_executable', 'ktlint') +call ale#Set('kotlin_ktlint_rulesets', []) +call ale#Set('kotlin_ktlint_options', '') + +function! ale#handlers#ktlint#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'kotlin_ktlint_executable') + let l:options = ale#Var(a:buffer, 'kotlin_ktlint_options') + let l:rulesets = ale#handlers#ktlint#GetRulesets(a:buffer) + + return ale#Escape(l:executable) + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . (empty(l:rulesets) ? '' : ' ' . l:rulesets) + \ . ' %t' +endfunction + +function! ale#handlers#ktlint#GetRulesets(buffer) abort + let l:rulesets = map(ale#Var(a:buffer, 'kotlin_ktlint_rulesets'), '''--ruleset '' . v:val') + + return join(l:rulesets, ' ') +endfunction + +function! ale#handlers#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 diff --git a/pack/acp/start/ale/autoload/ale/handlers/languagetool.vim b/pack/acp/start/ale/autoload/ale/handlers/languagetool.vim new file mode 100644 index 0000000..10e049d --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/languagetool.vim @@ -0,0 +1,74 @@ +" Author: Vincent (wahrwolf [at] wolfpit.net) +" Description: languagetool for markdown files +" +call ale#Set('languagetool_executable', 'languagetool') + +function! ale#handlers#languagetool#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'languagetool_executable') +endfunction + +function! ale#handlers#languagetool#GetCommand(buffer) abort + let l:executable = ale#handlers#languagetool#GetExecutable(a:buffer) + + return ale#Escape(l:executable) . ' --autoDetect %s' +endfunction + +function! ale#handlers#languagetool#HandleOutput(buffer, lines) abort + " Match lines like: + " 1.) Line 5, column 1, Rule ID: + let l:head_pattern = '^\v.+.\) Line (\d+), column (\d+), Rule ID. (.+)$' + let l:head_matches = ale#util#GetMatches(a:lines, l:head_pattern) + + " Match lines like: + " Message: Did you forget a comma after a conjunctive/linking adverb? + let l:message_pattern = '^\vMessage. (.+)$' + let l:message_matches = ale#util#GetMatches(a:lines, l:message_pattern) + + " Match lines like: + " ^^^^^ " + let l:markers_pattern = '^\v *(\^+) *$' + let l:markers_matches = ale#util#GetMatches(a:lines, l:markers_pattern) + + let l:output = [] + + + " Okay tbh I was to lazy to figure out a smarter solution here + " We just check that the arrays are same sized and merge everything + " together + let l:i = 0 + + while l:i < len(l:head_matches) + \ && ( + \ (len(l:head_matches) == len(l:markers_matches)) + \ && (len(l:head_matches) == len(l:message_matches)) + \ ) + let l:item = { + \ 'lnum' : str2nr(l:head_matches[l:i][1]), + \ 'col' : str2nr(l:head_matches[l:i][2]), + \ 'end_col' : str2nr(l:head_matches[l:i][2]) + len(l:markers_matches[l:i][1])-1, + \ 'type' : 'W', + \ 'code' : l:head_matches[l:i][3], + \ 'text' : l:message_matches[l:i][1] + \} + call add(l:output, l:item) + let l:i+=1 + endwhile + + return l:output +endfunction + +" Define the languagetool linter for a given filetype. +" TODO: +" - Add language detection settings based on user env (for mothertongue) +" - Add fixer +" - Add config options for rules +function! ale#handlers#languagetool#DefineLinter(filetype) abort + call ale#linter#Define(a:filetype, { + \ 'name': 'languagetool', + \ 'executable': function('ale#handlers#languagetool#GetExecutable'), + \ 'command': function('ale#handlers#languagetool#GetCommand'), + \ 'output_stream': 'stdout', + \ 'callback': 'ale#handlers#languagetool#HandleOutput', + \ 'lint_file': 1, + \}) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/markdownlint.vim b/pack/acp/start/ale/autoload/ale/handlers/markdownlint.vim new file mode 100644 index 0000000..daaa1d6 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/markdownlint.vim @@ -0,0 +1,17 @@ +" Author: Ty-Lucas Kelley +" Description: Adds support for markdownlint + +function! ale#handlers#markdownlint#Handle(buffer, lines) abort + let l:pattern=': \(\d*\): \(MD\d\{3}\)\(\/\)\([A-Za-z0-9-]\+\)\(.*\)$' + 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] . l:match[3] . l:match[4] . ')' . l:match[5], + \ 'type': 'W', + \}) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/ols.vim b/pack/acp/start/ale/autoload/ale/handlers/ols.vim new file mode 100644 index 0000000..74130a2 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/ols.vim @@ -0,0 +1,26 @@ +" Author: Michael Jungo +" Description: Handlers for the OCaml language server + +function! ale#handlers#ols#GetExecutable(buffer) abort + let l:ols_setting = ale#handlers#ols#GetLanguage(a:buffer) . '_ols' + + return ale#node#FindExecutable(a:buffer, l:ols_setting, [ + \ 'node_modules/.bin/ocaml-language-server', + \]) +endfunction + +function! ale#handlers#ols#GetCommand(buffer) abort + let l:executable = ale#handlers#ols#GetExecutable(a:buffer) + + return ale#node#Executable(a:buffer, l:executable) . ' --stdio' +endfunction + +function! ale#handlers#ols#GetLanguage(buffer) abort + return getbufvar(a:buffer, '&filetype') +endfunction + +function! ale#handlers#ols#GetProjectRoot(buffer) abort + let l:merlin_file = ale#path#FindNearestFile(a:buffer, '.merlin') + + return !empty(l:merlin_file) ? fnamemodify(l:merlin_file, ':h') : '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/pony.vim b/pack/acp/start/ale/autoload/ale/handlers/pony.vim new file mode 100644 index 0000000..ea84ac4 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/pony.vim @@ -0,0 +1,33 @@ +scriptencoding utf-8 +" Description: This file defines a handler function which ought to work for +" any program which outputs errors in the format that ponyc uses. + +function! s:RemoveUnicodeQuotes(text) abort + let l:text = a:text + let l:text = substitute(l:text, '[`´‘’]', '''', 'g') + let l:text = substitute(l:text, '\v\\u2018([^\\]+)\\u2019', '''\1''', 'g') + let l:text = substitute(l:text, '[“”]', '"', 'g') + + return l:text +endfunction + +function! ale#handlers#pony#HandlePonycFormat(buffer, lines) abort + " Look for lines like the following. + " /home/code/pony/classes/Wombat.pony:22:30: can't lookup private fields from outside the type + let l:pattern = '\v^([^:]+):(\d+):(\d+)?:? (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'filename': l:match[1], + \ 'lnum': str2nr(l:match[2]), + \ 'col': str2nr(l:match[3]), + \ 'type': 'E', + \ 'text': s:RemoveUnicodeQuotes(l:match[4]), + \} + + call add(l:output, l:item) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/redpen.vim b/pack/acp/start/ale/autoload/ale/handlers/redpen.vim new file mode 100644 index 0000000..195057c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/redpen.vim @@ -0,0 +1,65 @@ +" Author: rhysd https://rhysd.github.io +" Description: Redpen, a proofreading tool (http://redpen.cc) + +function! ale#handlers#redpen#HandleRedpenOutput(buffer, lines) abort + " Only one file was passed to redpen. So response array has only one + " element. + let l:res = get(ale#util#FuzzyJSONDecode(a:lines, []), 0, {}) + let l:output = [] + + for l:err in get(l:res, 'errors', []) + let l:item = { + \ 'text': l:err.message, + \ 'type': 'W', + \ 'code': l:err.validator, + \} + + if has_key(l:err, 'startPosition') + let l:item.lnum = l:err.startPosition.lineNum + let l:item.col = l:err.startPosition.offset + 1 + + if has_key(l:err, 'endPosition') + let l:item.end_lnum = l:err.endPosition.lineNum + let l:item.end_col = l:err.endPosition.offset + endif + else + " Fallback to a whole sentence region when a region is not + " specified by the error. + let l:item.lnum = l:err.lineNum + let l:item.col = l:err.sentenceStartColumnNum + 1 + endif + + " Adjust column number for multibyte string + let l:line = getline(l:item.lnum) + + if l:line is# '' + let l:line = l:err.sentence + endif + + let l:line = split(l:line, '\zs') + + if l:item.col >= 2 + let l:col = 0 + + for l:strlen in map(l:line[0:(l:item.col - 2)], 'strlen(v:val)') + let l:col = l:col + l:strlen + endfor + + let l:item.col = l:col + 1 + endif + + if has_key(l:item, 'end_col') + let l:col = 0 + + for l:strlen in map(l:line[0:(l:item.end_col - 1)], 'strlen(v:val)') + let l:col = l:col + l:strlen + endfor + + let l:item.end_col = l:col + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/ruby.vim b/pack/acp/start/ale/autoload/ale/handlers/ruby.vim new file mode 100644 index 0000000..c28b8b7 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/ruby.vim @@ -0,0 +1,46 @@ +" Author: Brandon Roehl - https://github.com/BrandonRoehl, Matthias Guenther https://wikimatze.de +" +" Description: This file implements handlers specific to Ruby. + +function! s:HandleSyntaxError(buffer, lines) abort + " Matches patterns line the following: + " + " test.rb:3: warning: parentheses after method name is interpreted as an argument list, not a decomposed argument + " test.rb:8: syntax error, unexpected keyword_end, expecting end-of-input + let l:pattern = '\v^.+:(\d+): (warning: )?(.+)$' + let l:column = '\v^(\s+)\^$' + let l:output = [] + + for l:line in a:lines + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) == 0 + let l:match = matchlist(l:line, l:column) + + if len(l:match) != 0 + let l:output[len(l:output) - 1]['col'] = len(l:match[1]) + endif + else + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': 0, + \ 'text': l:match[2] . l:match[3], + \ 'type': empty(l:match[2]) ? 'E' : 'W', + \}) + endif + endfor + + return l:output +endfunction + +function! ale#handlers#ruby#HandleSyntaxErrors(buffer, lines) abort + return s:HandleSyntaxError(a:buffer, a:lines) +endfunction + +function! ale#handlers#ruby#EscapeExecutable(executable, bundle_exec) abort + let l:exec_args = a:executable =~? 'bundle' + \ ? ' exec ' . a:bundle_exec + \ : '' + + return ale#Escape(a:executable) . l:exec_args +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/rust.vim b/pack/acp/start/ale/autoload/ale/handlers/rust.vim new file mode 100644 index 0000000..a7fac46 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/rust.vim @@ -0,0 +1,78 @@ +" Author: Daniel Schemala , +" w0rp +" +" Description: This file implements handlers specific to Rust. + +if !exists('g:ale_rust_ignore_error_codes') + let g:ale_rust_ignore_error_codes = [] +endif + +if !exists('g:ale_rust_ignore_secondary_spans') + let g:ale_rust_ignore_secondary_spans = 0 +endif + +function! s:FindSpan(buffer, span) abort + if ale#path#IsBufferPath(a:buffer, a:span.file_name) || a:span.file_name is# '' + return a:span + endif + + " Search inside the expansion of an error, as the problem for this buffer + " could lie inside a nested object. + if !empty(get(a:span, 'expansion', v:null)) + return s:FindSpan(a:buffer, a:span.expansion.span) + endif + + return {} +endfunction + +function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort + let l:output = [] + + for l:errorline in a:lines + " ignore everything that is not JSON + if l:errorline !~# '^{' + continue + endif + + let l:error = json_decode(l:errorline) + + if has_key(l:error, 'message') && type(l:error.message) is v:t_dict + let l:error = l:error.message + endif + + if !has_key(l:error, 'code') + continue + endif + + if !empty(l:error.code) && index(g:ale_rust_ignore_error_codes, l:error.code.code) > -1 + continue + endif + + for l:root_span in l:error.spans + let l:span = s:FindSpan(a:buffer, l:root_span) + + if ale#Var(a:buffer, 'rust_ignore_secondary_spans') && !get(l:span, 'is_primary', 1) + continue + endif + + if !empty(l:span) + let l:output_line = { + \ 'lnum': l:span.line_start, + \ 'end_lnum': l:span.line_end, + \ 'col': l:span.column_start, + \ 'end_col': l:span.column_end-1, + \ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label), + \ 'type': toupper(l:error.level[0]), + \} + + if has_key(l:error, 'rendered') && !empty(l:error.rendered) + let l:output_line.detail = l:error.rendered + endif + + call add(l:output, l:output_line) + endif + endfor + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/scala.vim b/pack/acp/start/ale/autoload/ale/handlers/scala.vim new file mode 100644 index 0000000..3fe7a12 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/scala.vim @@ -0,0 +1,37 @@ +" Author: Nils Leuzinger - https://github.com/PawkyPenguin +" Description: Scala linting handlers for scalac-like compilers. + +function! ale#handlers#scala#HandleScalacLintFormat(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 diff --git a/pack/acp/start/ale/autoload/ale/handlers/sh.vim b/pack/acp/start/ale/autoload/ale/handlers/sh.vim new file mode 100644 index 0000000..75eaf71 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/sh.vim @@ -0,0 +1,20 @@ +" Author: w0rp + +" Get the shell type for a buffer, based on the hashbang line. +function! ale#handlers#sh#GetShellType(buffer) abort + let l:bang_line = get(getbufline(a:buffer, 1), 0, '') + + " Take the shell executable from the hashbang, if we can. + if l:bang_line[:1] is# '#!' + " Remove options like -e, etc. + let l:command = substitute(l:bang_line, ' --\?[a-zA-Z0-9]\+', '', 'g') + + for l:possible_shell in ['bash', 'dash', 'ash', 'tcsh', 'csh', 'zsh', 'ksh', 'sh'] + if l:command =~# l:possible_shell . '\s*$' + return l:possible_shell + endif + endfor + endif + + return '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/sml.vim b/pack/acp/start/ale/autoload/ale/handlers/sml.vim new file mode 100644 index 0000000..594ee4f --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/sml.vim @@ -0,0 +1,93 @@ +" Author: Jake Zimmerman +" Description: Shared functions for SML linters + +" The glob to use for finding the .cm file. +" +" See :help ale-sml-smlnj for more information. +call ale#Set('sml_smlnj_cm_file', '*.cm') + +function! ale#handlers#sml#GetCmFile(buffer) abort + let l:pattern = ale#Var(a:buffer, 'sml_smlnj_cm_file') + let l:as_list = 1 + + let l:cmfile = '' + + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + let l:results = glob(l:path . '/' . l:pattern, 0, l:as_list) + + if len(l:results) > 0 + " If there is more than one CM file, we take the first one + " See :help ale-sml-smlnj for how to configure this. + let l:cmfile = l:results[0] + endif + endfor + + return l:cmfile +endfunction + +" Only one of smlnj or smlnj-cm can be enabled at a time. +function! s:GetExecutable(buffer, source) abort + if ale#handlers#sml#GetCmFile(a:buffer) is# '' + " No CM file found; only allow single-file mode to be enabled + if a:source is# 'smlnj-file' + return 'sml' + elseif a:source is# 'smlnj-cm' + return '' + endif + else + " Found a CM file; only allow cm-file mode to be enabled + if a:source is# 'smlnj-file' + return '' + elseif a:source is# 'smlnj-cm' + return 'sml' + endif + endif +endfunction + +function! ale#handlers#sml#GetExecutableSmlnjCm(buffer) abort + return s:GetExecutable(a:buffer, 'smlnj-cm') +endfunction + +function! ale#handlers#sml#GetExecutableSmlnjFile(buffer) abort + return s:GetExecutable(a:buffer, 'smlnj-file') +endfunction + +function! ale#handlers#sml#Handle(buffer, lines) abort + " Try to match basic sml errors + " TODO(jez) We can get better errorfmt strings from Syntastic + 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 + +" vim:ts=4:sts=4:sw=4 diff --git a/pack/acp/start/ale/autoload/ale/handlers/textlint.vim b/pack/acp/start/ale/autoload/ale/handlers/textlint.vim new file mode 100644 index 0000000..6d495b0 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/textlint.vim @@ -0,0 +1,39 @@ +" Author: tokida https://rouger.info, Yasuhiro Kiyota +" Description: textlint, a proofreading tool (https://textlint.github.io/) + +call ale#Set('textlint_executable', 'textlint') +call ale#Set('textlint_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('textlint_options', '') + +function! ale#handlers#textlint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'textlint', [ + \ 'node_modules/.bin/textlint', + \ 'node_modules/textlint/bin/textlint.js', + \]) +endfunction + +function! ale#handlers#textlint#GetCommand(buffer) abort + let l:executable = ale#handlers#textlint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'textlint_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -f json --stdin --stdin-filename %s' +endfunction + +function! ale#handlers#textlint#HandleTextlintOutput(buffer, lines) abort + let l:res = get(ale#util#FuzzyJSONDecode(a:lines, []), 0, {'messages': []}) + let l:output = [] + + for l:err in l:res.messages + call add(l:output, { + \ 'text': l:err.message, + \ 'type': 'W', + \ 'code': l:err.ruleId, + \ 'lnum': l:err.line, + \ 'col' : l:err.column + \}) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/tslint.vim b/pack/acp/start/ale/autoload/ale/handlers/tslint.vim new file mode 100644 index 0000000..9057934 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/tslint.vim @@ -0,0 +1,13 @@ +function! ale#handlers#tslint#InitVariables() abort + call ale#Set('typescript_tslint_executable', 'tslint') + call ale#Set('typescript_tslint_config_path', '') + call ale#Set('typescript_tslint_rules_dir', '') + call ale#Set('typescript_tslint_use_global', get(g:, 'ale_use_global_executables', 0)) + call ale#Set('typescript_tslint_ignore_empty_files', 0) +endfunction + +function! ale#handlers#tslint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'typescript_tslint', [ + \ 'node_modules/.bin/tslint', + \]) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/tsserver.vim b/pack/acp/start/ale/autoload/ale/handlers/tsserver.vim new file mode 100644 index 0000000..f78499a --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/tsserver.vim @@ -0,0 +1,8 @@ +" Author: Derek Sifford +" Description: Handlers for tsserver + +function! ale#handlers#tsserver#GetProjectRoot(buffer) abort + let l:tsconfig_file = ale#path#FindNearestFile(a:buffer, 'tsconfig.json') + + return !empty(l:tsconfig_file) ? fnamemodify(l:tsconfig_file, ':h') : '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/unix.vim b/pack/acp/start/ale/autoload/ale/handlers/unix.vim new file mode 100644 index 0000000..f90fd59 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/unix.vim @@ -0,0 +1,26 @@ +" Author: w0rp +" Description: Error handling for errors in a Unix format. + +function! s:HandleUnixFormat(buffer, lines, type) abort + let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\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], + \ 'type': a:type, + \}) + endfor + + return l:output +endfunction + +function! ale#handlers#unix#HandleAsError(buffer, lines) abort + return s:HandleUnixFormat(a:buffer, a:lines, 'E') +endfunction + +function! ale#handlers#unix#HandleAsWarning(buffer, lines) abort + return s:HandleUnixFormat(a:buffer, a:lines, 'W') +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/vale.vim b/pack/acp/start/ale/autoload/ale/handlers/vale.vim new file mode 100644 index 0000000..2da72fc --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/vale.vim @@ -0,0 +1,39 @@ +" Author: Johannes Wienke +" Description: output handler for the vale JSON format + +function! ale#handlers#vale#GetType(severity) abort + if a:severity is? 'warning' + return 'W' + elseif a:severity is? 'suggestion' + return 'I' + endif + + return 'E' +endfunction + +function! ale#handlers#vale#Handle(buffer, lines) abort + try + let l:errors = json_decode(join(a:lines, '')) + catch + return [] + endtry + + if empty(l:errors) + return [] + endif + + let l:output = [] + + for l:error in l:errors[keys(l:errors)[0]] + call add(l:output, { + \ 'lnum': l:error['Line'], + \ 'col': l:error['Span'][0], + \ 'end_col': l:error['Span'][1], + \ 'code': l:error['Check'], + \ 'text': l:error['Message'], + \ 'type': ale#handlers#vale#GetType(l:error['Severity']), + \}) + endfor + + return l:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/handlers/writegood.vim b/pack/acp/start/ale/autoload/ale/handlers/writegood.vim new file mode 100644 index 0000000..8ae61a3 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/handlers/writegood.vim @@ -0,0 +1,72 @@ +" Author: Sumner Evans +" Description: Error handling for errors in the write-good format. + +function! ale#handlers#writegood#ResetOptions() abort + call ale#Set('writegood_options', '') + call ale#Set('writegood_executable', 'write-good') + call ale#Set('writegood_use_global', get(g:, 'ale_use_global_executables', 0)) +endfunction + +" Reset the options so the tests can test how they are set. +call ale#handlers#writegood#ResetOptions() + +function! ale#handlers#writegood#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'writegood', [ + \ 'node_modules/.bin/write-good', + \ 'node_modules/write-good/bin/write-good.js', + \]) +endfunction + +function! ale#handlers#writegood#GetCommand(buffer) abort + let l:executable = ale#handlers#writegood#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'writegood_options') + + return ale#node#Executable(a:buffer, l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' %t' +endfunction + +function! ale#handlers#writegood#Handle(buffer, lines) abort + " Look for lines like the following. + " + " "it is" is wordy or unneeded on line 20 at column 53 + " "easily" can weaken meaning on line 154 at column 29 + let l:marks_pattern = '\v^ *(\^+) *$' + let l:pattern = '\v^(".*"\s.*)\son\sline\s(\d+)\sat\scolumn\s(\d+)$' + let l:output = [] + let l:last_len = 0 + + for l:match in ale#util#GetMatches(a:lines, [l:marks_pattern, l:pattern]) + if empty(l:match[2]) + let l:last_len = len(l:match[1]) + else + let l:col = l:match[3] + 1 + + " Add the linter error. Note that we need to add 1 to the col because + " write-good reports the column corresponding to the space before the + " offending word or phrase. + call add(l:output, { + \ 'text': l:match[1], + \ 'lnum': l:match[2] + 0, + \ 'col': l:col, + \ 'end_col': l:last_len ? (l:col + l:last_len - 1) : l:col, + \ 'type': 'W', + \}) + + let l:last_len = 0 + endif + endfor + + return l:output +endfunction + +" Define the writegood linter for a given filetype. +function! ale#handlers#writegood#DefineLinter(filetype) abort + call ale#linter#Define(a:filetype, { + \ 'name': 'writegood', + \ 'aliases': ['write-good'], + \ 'executable': function('ale#handlers#writegood#GetExecutable'), + \ 'command': function('ale#handlers#writegood#GetCommand'), + \ 'callback': 'ale#handlers#writegood#Handle', + \}) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/highlight.vim b/pack/acp/start/ale/autoload/ale/highlight.vim new file mode 100644 index 0000000..cb7911e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/highlight.vim @@ -0,0 +1,159 @@ +scriptencoding utf8 +" Author: w0rp +" Description: This module implements error/warning highlighting. + +if !hlexists('ALEError') + highlight link ALEError SpellBad +endif + +if !hlexists('ALEStyleError') + highlight link ALEStyleError ALEError +endif + +if !hlexists('ALEWarning') + highlight link ALEWarning SpellCap +endif + +if !hlexists('ALEStyleWarning') + highlight link ALEStyleWarning ALEWarning +endif + +if !hlexists('ALEInfo') + highlight link ALEInfo ALEWarning +endif + +" The maximum number of items for the second argument of matchaddpos() +let s:MAX_POS_VALUES = 8 +let s:MAX_COL_SIZE = 1073741824 " pow(2, 30) + +function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort + if a:line >= a:end_line + " For single lines, just return the one position. + return [[[a:line, a:col, a:end_col - a:col + 1]]] + endif + + " Get positions from the first line at the first column, up to a large + " integer for highlighting up to the end of the line, followed by + " the lines in-between, for highlighting entire lines, and + " a highlight for the last line, up to the end column. + let l:all_positions = + \ [[a:line, a:col, s:MAX_COL_SIZE]] + \ + range(a:line + 1, a:end_line - 1) + \ + [[a:end_line, 1, a:end_col]] + + return map( + \ range(0, len(l:all_positions) - 1, s:MAX_POS_VALUES), + \ 'l:all_positions[v:val : v:val + s:MAX_POS_VALUES - 1]', + \) +endfunction + +" Given a loclist for current items to highlight, remove all highlights +" except these which have matching loclist item entries. + +function! ale#highlight#RemoveHighlights() abort + for l:match in getmatches() + if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$' + call matchdelete(l:match.id) + endif + endfor +endfunction + +function! s:highlight_line(bufnr, lnum, group) abort + call matchaddpos(a:group, [a:lnum]) +endfunction + +function! s:highlight_range(bufnr, range, group) abort + " Set all of the positions, which are chunked into Lists which + " are as large as will be accepted by matchaddpos. + call map( + \ ale#highlight#CreatePositions( + \ a:range.lnum, + \ a:range.col, + \ a:range.end_lnum, + \ a:range.end_col + \ ), + \ 'matchaddpos(a:group, v:val)' + \) +endfunction + +function! ale#highlight#UpdateHighlights() abort + let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled + \ ? get(b:, 'ale_highlight_items', []) + \ : [] + + call ale#highlight#RemoveHighlights() + + for l:item in l:item_list + if l:item.type is# 'W' + if get(l:item, 'sub_type', '') is# 'style' + let l:group = 'ALEStyleWarning' + else + let l:group = 'ALEWarning' + endif + elseif l:item.type is# 'I' + let l:group = 'ALEInfo' + elseif get(l:item, 'sub_type', '') is# 'style' + let l:group = 'ALEStyleError' + else + let l:group = 'ALEError' + endif + + let l:range = { + \ 'lnum': l:item.lnum, + \ 'col': l:item.col, + \ 'end_lnum': get(l:item, 'end_lnum', l:item.lnum), + \ 'end_col': get(l:item, 'end_col', l:item.col) + \} + + call s:highlight_range(l:item.bufnr, l:range, l:group) + endfor + + " If highlights are enabled and signs are not enabled, we should still + " offer line highlights by adding a separate set of highlights. + if !g:ale_set_signs + let l:available_groups = { + \ 'ALEWarningLine': hlexists('ALEWarningLine'), + \ 'ALEInfoLine': hlexists('ALEInfoLine'), + \ 'ALEErrorLine': hlexists('ALEErrorLine'), + \} + + for l:item in l:item_list + if l:item.type is# 'W' + let l:group = 'ALEWarningLine' + elseif l:item.type is# 'I' + let l:group = 'ALEInfoLine' + else + let l:group = 'ALEErrorLine' + endif + + if l:available_groups[l:group] + call s:highlight_line(l:item.bufnr, l:item.lnum, l:group) + endif + endfor + endif +endfunction + +function! ale#highlight#BufferHidden(buffer) abort + " Remove highlights right away when buffers are hidden. + " They will be restored later when buffers are entered. + call ale#highlight#RemoveHighlights() +endfunction + +augroup ALEHighlightBufferGroup + autocmd! + autocmd BufEnter * call ale#highlight#UpdateHighlights() + autocmd BufHidden * call ale#highlight#BufferHidden(expand('')) +augroup END + +function! ale#highlight#SetHighlights(buffer, loclist) abort + let l:new_list = getbufvar(a:buffer, 'ale_enabled', 1) && g:ale_enabled + \ ? filter(copy(a:loclist), 'v:val.bufnr == a:buffer && v:val.col > 0') + \ : [] + + " Set the list in the buffer variable. + call setbufvar(str2nr(a:buffer), 'ale_highlight_items', l:new_list) + + " Update highlights for the current buffer, which may or may not + " be the buffer we just set highlights for. + call ale#highlight#UpdateHighlights() +endfunction diff --git a/pack/acp/start/ale/autoload/ale/history.vim b/pack/acp/start/ale/autoload/ale/history.vim new file mode 100644 index 0000000..27ae74c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/history.vim @@ -0,0 +1,62 @@ +" Author: w0rp +" Description: Tools for managing command history + +" A flag for controlling the maximum size of the command history to store. +let g:ale_max_buffer_history_size = get(g:, 'ale_max_buffer_history_size', 20) + +" Return a shallow copy of the command history for a given buffer number. +function! ale#history#Get(buffer) abort + return copy(getbufvar(a:buffer, 'ale_history', [])) +endfunction + +function! ale#history#Add(buffer, status, job_id, command) abort + if g:ale_max_buffer_history_size <= 0 + " Don't save anything if the history isn't a positive number. + call setbufvar(a:buffer, 'ale_history', []) + + return + endif + + let l:history = getbufvar(a:buffer, 'ale_history', []) + + " Remove the first item if we hit the max history size. + if len(l:history) >= g:ale_max_buffer_history_size + let l:history = l:history[1:] + endif + + call add(l:history, { + \ 'status': a:status, + \ 'job_id': a:job_id, + \ 'command': a:command, + \}) + + call setbufvar(a:buffer, 'ale_history', l:history) +endfunction + +function! s:FindHistoryItem(buffer, job_id) abort + " Search backwards to find a matching job ID. IDs might be recycled, + " so finding the last one should be good enough. + for l:obj in reverse(ale#history#Get(a:buffer)) + if l:obj.job_id == a:job_id + return l:obj + endif + endfor + + return {} +endfunction + +" Set an exit code for a command which finished. +function! ale#history#SetExitCode(buffer, job_id, exit_code) abort + let l:obj = s:FindHistoryItem(a:buffer, a:job_id) + + " If we find a match, then set the code and status. + let l:obj.exit_code = a:exit_code + let l:obj.status = 'finished' +endfunction + +" Set the output for a command which finished. +function! ale#history#RememberOutput(buffer, job_id, output) abort + let l:obj = s:FindHistoryItem(a:buffer, a:job_id) + + let l:obj.output = a:output +endfunction diff --git a/pack/acp/start/ale/autoload/ale/hover.vim b/pack/acp/start/ale/autoload/ale/hover.vim new file mode 100644 index 0000000..2af35aa --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/hover.vim @@ -0,0 +1,189 @@ +" Author: w0rp +" Description: Hover support for LSP linters. + +let s:hover_map = {} + +" Used to get the hover map in tests. +function! ale#hover#GetMap() abort + return deepcopy(s:hover_map) +endfunction + +" Used to set the hover map in tests. +function! ale#hover#SetMap(map) abort + let s:hover_map = a:map +endfunction + +function! ale#hover#ClearLSPData() abort + let s:hover_map = {} +endfunction + +function! ale#hover#HandleTSServerResponse(conn_id, response) abort + if get(a:response, 'command', '') is# 'quickinfo' + \&& has_key(s:hover_map, a:response.request_seq) + let l:options = remove(s:hover_map, a:response.request_seq) + + if get(a:response, 'success', v:false) is v:true + \&& get(a:response, 'body', v:null) isnot v:null + " If we pass the show_documentation flag, we should show the full + " documentation, and always in the preview window. + if get(l:options, 'show_documentation', 0) + let l:documentation = get(a:response.body, 'documentation', '') + + " displayString is not included here, because it can be very + " noisy and run on for many lines for complex types. A less + " verbose alternative may be nice in future. + if !empty(l:documentation) + call ale#preview#Show(split(l:documentation, "\n"), { + \ 'filetype': 'ale-preview.message', + \ 'stay_here': 1, + \}) + endif + elseif get(l:options, 'hover_from_balloonexpr', 0) + \&& exists('*balloon_show') + \&& ale#Var(l:options.buffer, 'set_balloons') + call balloon_show(a:response.body.displayString) + else + call ale#util#ShowMessage(a:response.body.displayString) + endif + endif + endif +endfunction + +function! ale#hover#HandleLSPResponse(conn_id, response) abort + if has_key(a:response, 'id') + \&& has_key(s:hover_map, a:response.id) + let l:options = remove(s:hover_map, a:response.id) + + " If the call did __not__ come from balloonexpr... + if !get(l:options, 'hover_from_balloonexpr', 0) + let l:buffer = bufnr('') + let [l:line, l:column] = getpos('.')[1:2] + let l:end = len(getline(l:line)) + + if l:buffer isnot l:options.buffer + \|| l:line isnot l:options.line + \|| min([l:column, l:end]) isnot min([l:options.column, l:end]) + " ... Cancel display the message if the cursor has moved. + return + endif + endif + + " The result can be a Dictionary item, a List of the same, or null. + let l:result = get(a:response, 'result', v:null) + + if l:result is v:null + return + endif + + let l:result = l:result.contents + + if type(l:result) is v:t_string + " The result can be just a string. + let l:result = [l:result] + endif + + if type(l:result) is v:t_dict + " If the result is an object, then it's markup content. + let l:result = [l:result.value] + endif + + if type(l:result) is v:t_list + " Replace objects with text values. + call map(l:result, 'type(v:val) is v:t_string ? v:val : v:val.value') + let l:str = join(l:result, "\n") + let l:str = substitute(l:str, '^\s*\(.\{-}\)\s*$', '\1', '') + + if !empty(l:str) + if get(l:options, 'hover_from_balloonexpr', 0) + \&& exists('*balloon_show') + \&& ale#Var(l:options.buffer, 'set_balloons') + call balloon_show(l:str) + else + call ale#util#ShowMessage(l:str) + endif + endif + endif + endif +endfunction + +function! s:OnReady(line, column, opt, linter, lsp_details) abort + let l:id = a:lsp_details.connection_id + + if !ale#lsp#HasCapability(l:id, 'hover') + return + endif + + let l:buffer = a:lsp_details.buffer + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#hover#HandleTSServerResponse') + \ : function('ale#hover#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:column = a:column + + let l:message = ale#lsp#tsserver_message#Quickinfo( + \ l:buffer, + \ a:line, + \ l:column + \) + else + " Send a message saying the buffer has changed first, or the + " hover position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:buffer) + + let l:column = min([a:column, len(getbufline(l:buffer, a:line)[0])]) + + let l:message = ale#lsp#message#Hover(l:buffer, a:line, l:column) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message) + + let s:hover_map[l:request_id] = { + \ 'buffer': l:buffer, + \ 'line': a:line, + \ 'column': l:column, + \ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0), + \ 'show_documentation': get(a:opt, 'show_documentation', 0), + \} +endfunction + +" Obtain Hover information for the specified position +" Pass optional arguments in the dictionary opt. +" Currently, only one key/value is useful: +" - called_from_balloonexpr, this flag marks if we want the result from this +" ale#hover#Show to display in a balloon if possible +" +" Currently, the callbacks displays the info from hover : +" - in the balloon if opt.called_from_balloonexpr and balloon_show is detected +" - as status message otherwise +function! ale#hover#Show(buffer, line, col, opt) abort + let l:show_documentation = get(a:opt, 'show_documentation', 0) + let l:Callback = function('s:OnReady', [a:line, a:col, a:opt]) + + for l:linter in ale#linter#Get(getbufvar(a:buffer, '&filetype')) + " Only tsserver supports documentation requests at the moment. + if !empty(l:linter.lsp) + \&& (!l:show_documentation || l:linter.lsp is# 'tsserver') + call ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback) + endif + endfor +endfunction + +" This function implements the :ALEHover command. +function! ale#hover#ShowAtCursor() abort + let l:buffer = bufnr('') + let l:pos = getpos('.') + + call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], {}) +endfunction + +" This function implements the :ALEDocumentation command. +function! ale#hover#ShowDocumentationAtCursor() abort + let l:buffer = bufnr('') + let l:pos = getpos('.') + let l:options = {'show_documentation': 1} + + call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], l:options) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/java.vim b/pack/acp/start/ale/autoload/ale/java.vim new file mode 100644 index 0000000..e641ac6 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/java.vim @@ -0,0 +1,26 @@ +" Author: Horacio Sanson https://github.com/hsanson +" Description: Functions for integrating with Java tools + +" Find the nearest dir contining a gradle or pom file and asume it +" the root of a java app. +function! ale#java#FindProjectRoot(buffer) abort + let l:gradle_root = ale#gradle#FindProjectRoot(a:buffer) + + if !empty(l:gradle_root) + return l:gradle_root + endif + + let l:maven_pom_file = ale#path#FindNearestFile(a:buffer, 'pom.xml') + + if !empty(l:maven_pom_file) + return fnamemodify(l:maven_pom_file, ':h') + endif + + let l:ant_root = ale#ant#FindProjectRoot(a:buffer) + + if !empty(l:ant_root) + return l:ant_root + endif + + return '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/job.vim b/pack/acp/start/ale/autoload/ale/job.vim new file mode 100644 index 0000000..14b3e48 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/job.vim @@ -0,0 +1,373 @@ +" Author: w0rp +" Description: APIs for working with Asynchronous jobs, with an API normalised +" between Vim 8 and NeoVim. +" +" Important functions are described below. They are: +" +" ale#job#Start(command, options) -> job_id +" ale#job#IsRunning(job_id) -> 1 if running, 0 otherwise. +" ale#job#Stop(job_id) + +" A setting for wrapping commands. +let g:ale_command_wrapper = get(g:, 'ale_command_wrapper', '') + +if !has_key(s:, 'job_map') + let s:job_map = {} +endif + +" A map from timer IDs to jobs, for tracking jobs that need to be killed +" with SIGKILL if they don't terminate right away. +if !has_key(s:, 'job_kill_timers') + let s:job_kill_timers = {} +endif + +function! s:KillHandler(timer) abort + let l:job = remove(s:job_kill_timers, a:timer) + call job_stop(l:job, 'kill') +endfunction + +function! s:NeoVimCallback(job, data, event) abort + let l:info = s:job_map[a:job] + + if a:event is# 'stdout' + let l:info.out_cb_line = ale#util#JoinNeovimOutput( + \ a:job, + \ l:info.out_cb_line, + \ a:data, + \ l:info.mode, + \ ale#util#GetFunction(l:info.out_cb), + \) + elseif a:event is# 'stderr' + let l:info.err_cb_line = ale#util#JoinNeovimOutput( + \ a:job, + \ l:info.err_cb_line, + \ a:data, + \ l:info.mode, + \ ale#util#GetFunction(l:info.err_cb), + \) + else + if has_key(l:info, 'out_cb') && !empty(l:info.out_cb_line) + call ale#util#GetFunction(l:info.out_cb)(a:job, l:info.out_cb_line) + endif + + if has_key(l:info, 'err_cb') && !empty(l:info.err_cb_line) + call ale#util#GetFunction(l:info.err_cb)(a:job, l:info.err_cb_line) + endif + + try + call ale#util#GetFunction(l:info.exit_cb)(a:job, a:data) + finally + " Automatically forget about the job after it's done. + if has_key(s:job_map, a:job) + call remove(s:job_map, a:job) + endif + endtry + endif +endfunction + +function! s:VimOutputCallback(channel, data) abort + let l:job = ch_getjob(a:channel) + let l:job_id = ale#job#ParseVim8ProcessID(string(l:job)) + + " Only call the callbacks for jobs which are valid. + if l:job_id > 0 && has_key(s:job_map, l:job_id) + call ale#util#GetFunction(s:job_map[l:job_id].out_cb)(l:job_id, a:data) + endif +endfunction + +function! s:VimErrorCallback(channel, data) abort + let l:job = ch_getjob(a:channel) + let l:job_id = ale#job#ParseVim8ProcessID(string(l:job)) + + " Only call the callbacks for jobs which are valid. + if l:job_id > 0 && has_key(s:job_map, l:job_id) + call ale#util#GetFunction(s:job_map[l:job_id].err_cb)(l:job_id, a:data) + endif +endfunction + +function! s:VimCloseCallback(channel) abort + let l:job = ch_getjob(a:channel) + let l:job_id = ale#job#ParseVim8ProcessID(string(l:job)) + let l:info = get(s:job_map, l:job_id, {}) + + if empty(l:info) + return + endif + + " job_status() can trigger the exit handler. + " The channel can close before the job has exited. + if job_status(l:job) is# 'dead' + try + if !empty(l:info) && has_key(l:info, 'exit_cb') + " We have to remove the callback, so we don't call it twice. + call ale#util#GetFunction(remove(l:info, 'exit_cb'))(l:job_id, get(l:info, 'exit_code', 1)) + endif + finally + " Automatically forget about the job after it's done. + if has_key(s:job_map, l:job_id) + call remove(s:job_map, l:job_id) + endif + endtry + endif +endfunction + +function! s:VimExitCallback(job, exit_code) abort + let l:job_id = ale#job#ParseVim8ProcessID(string(a:job)) + let l:info = get(s:job_map, l:job_id, {}) + + if empty(l:info) + return + endif + + let l:info.exit_code = a:exit_code + + " The program can exit before the data has finished being read. + if ch_status(job_getchannel(a:job)) is# 'closed' + try + if !empty(l:info) && has_key(l:info, 'exit_cb') + " We have to remove the callback, so we don't call it twice. + call ale#util#GetFunction(remove(l:info, 'exit_cb'))(l:job_id, a:exit_code) + endif + finally + " Automatically forget about the job after it's done. + if has_key(s:job_map, l:job_id) + call remove(s:job_map, l:job_id) + endif + endtry + endif +endfunction + +function! ale#job#ParseVim8ProcessID(job_string) abort + return matchstr(a:job_string, '\d\+') + 0 +endfunction + +function! ale#job#ValidateArguments(command, options) abort + if a:options.mode isnot# 'nl' && a:options.mode isnot# 'raw' + throw 'Invalid mode: ' . a:options.mode + endif +endfunction + +function! s:PrepareWrappedCommand(original_wrapper, command) abort + let l:match = matchlist(a:command, '\v^(.*(\&\&|;)) *(.*)$') + let l:prefix = '' + let l:command = a:command + + if !empty(l:match) + let l:prefix = l:match[1] . ' ' + let l:command = l:match[3] + endif + + let l:format = a:original_wrapper + + if l:format =~# '%@' + let l:wrapped = substitute(l:format, '%@', ale#Escape(l:command), '') + else + if l:format !~# '%\*' + let l:format .= ' %*' + endif + + let l:wrapped = substitute(l:format, '%\*', l:command, '') + endif + + return l:prefix . l:wrapped +endfunction + +function! ale#job#PrepareCommand(buffer, command) abort + let l:wrapper = ale#Var(a:buffer, 'command_wrapper') + + " The command will be executed in a subshell. This fixes a number of + " issues, including reading the PATH variables correctly, %PATHEXT% + " expansion on Windows, etc. + " + " NeoVim handles this issue automatically if the command is a String, + " but we'll do this explicitly, so we use the same exact command for both + " versions. + let l:command = !empty(l:wrapper) + \ ? s:PrepareWrappedCommand(l:wrapper, a:command) + \ : a:command + + " If a custom shell is specified, use that. + if exists('g:ale_shell') + let l:shell_arguments = get(g:, 'ale_shell_arguments', &shellcmdflag) + + return split(g:ale_shell) + split(l:shell_arguments) + [l:command] + endif + + if has('win32') + return 'cmd /s/c "' . l:command . '"' + endif + + if &shell =~? 'fish$\|pwsh$' + return ['/bin/sh', '-c', l:command] + endif + + return split(&shell) + split(&shellcmdflag) + [l:command] +endfunction + +" Start a job with options which are agnostic to Vim and NeoVim. +" +" The following options are accepted: +" +" out_cb - A callback for receiving stdin. Arguments: (job_id, data) +" err_cb - A callback for receiving stderr. Arguments: (job_id, data) +" exit_cb - A callback for program exit. Arguments: (job_id, status_code) +" mode - A mode for I/O. Can be 'nl' for split lines or 'raw'. +function! ale#job#Start(command, options) abort + call ale#job#ValidateArguments(a:command, a:options) + + let l:job_info = copy(a:options) + let l:job_options = {} + + if has('nvim') + if has_key(a:options, 'out_cb') + let l:job_options.on_stdout = function('s:NeoVimCallback') + let l:job_info.out_cb_line = '' + endif + + if has_key(a:options, 'err_cb') + let l:job_options.on_stderr = function('s:NeoVimCallback') + let l:job_info.err_cb_line = '' + endif + + if has_key(a:options, 'exit_cb') + let l:job_options.on_exit = function('s:NeoVimCallback') + endif + + let l:job_info.job = jobstart(a:command, l:job_options) + let l:job_id = l:job_info.job + else + let l:job_options = { + \ 'in_mode': l:job_info.mode, + \ 'out_mode': l:job_info.mode, + \ 'err_mode': l:job_info.mode, + \} + + if has_key(a:options, 'out_cb') + let l:job_options.out_cb = function('s:VimOutputCallback') + endif + + if has_key(a:options, 'err_cb') + let l:job_options.err_cb = function('s:VimErrorCallback') + endif + + if has_key(a:options, 'exit_cb') + " Set a close callback to which simply calls job_status() + " when the channel is closed, which can trigger the exit callback + " earlier on. + let l:job_options.close_cb = function('s:VimCloseCallback') + let l:job_options.exit_cb = function('s:VimExitCallback') + endif + + " Use non-blocking writes for Vim versions that support the option. + if has('patch-8.1.350') + let l:job_options.noblock = 1 + endif + + " Vim 8 will read the stdin from the file's buffer. + let l:job_info.job = job_start(a:command, l:job_options) + let l:job_id = ale#job#ParseVim8ProcessID(string(l:job_info.job)) + endif + + if l:job_id > 0 + " Store the job in the map for later only if we can get the ID. + let s:job_map[l:job_id] = l:job_info + endif + + return l:job_id +endfunction + +" Force running commands in a Windows CMD command line. +" This means the same command syntax works everywhere. +function! ale#job#StartWithCmd(command, options) abort + let l:shell = &l:shell + let l:shellcmdflag = &l:shellcmdflag + let &l:shell = 'cmd' + let &l:shellcmdflag = '/c' + + try + let l:job_id = ale#job#Start(a:command, a:options) + finally + let &l:shell = l:shell + let &l:shellcmdflag = l:shellcmdflag + endtry + + return l:job_id +endfunction + +" Send raw data to the job. +function! ale#job#SendRaw(job_id, string) abort + if has('nvim') + call jobsend(a:job_id, a:string) + else + let l:job = s:job_map[a:job_id].job + + if ch_status(l:job) is# 'open' + call ch_sendraw(job_getchannel(l:job), a:string) + endif + endif +endfunction + +" Given a job ID, return 1 if the job is currently running. +" Invalid job IDs will be ignored. +function! ale#job#IsRunning(job_id) abort + if has('nvim') + try + " In NeoVim, if the job isn't running, jobpid() will throw. + call jobpid(a:job_id) + + return 1 + catch + endtry + elseif has_key(s:job_map, a:job_id) + let l:job = s:job_map[a:job_id].job + + return job_status(l:job) is# 'run' + endif + + return 0 +endfunction + +function! ale#job#HasOpenChannel(job_id) abort + if ale#job#IsRunning(a:job_id) + if has('nvim') + " TODO: Implement a check for NeoVim. + return 1 + endif + + " Check if the Job's channel can be written to. + return ch_status(s:job_map[a:job_id].job) is# 'open' + endif + + return 0 +endfunction + +" Given a Job ID, stop that job. +" Invalid job IDs will be ignored. +function! ale#job#Stop(job_id) abort + if !has_key(s:job_map, a:job_id) + return + endif + + if has('nvim') + " FIXME: NeoVim kills jobs on a timer, but will not kill any processes + " which are child processes on Unix. Some work needs to be done to + " kill child processes to stop long-running processes like pylint. + silent! call jobstop(a:job_id) + else + let l:job = s:job_map[a:job_id].job + + " We must close the channel for reading the buffer if it is open + " when stopping a job. Otherwise, we will get errors in the status line. + if ch_status(job_getchannel(l:job)) is# 'open' + call ch_close_in(job_getchannel(l:job)) + endif + + " Ask nicely for the job to stop. + call job_stop(l:job) + + if ale#job#IsRunning(l:job) + " Set a 100ms delay for killing the job with SIGKILL. + let s:job_kill_timers[timer_start(100, function('s:KillHandler'))] = l:job + endif + endif +endfunction diff --git a/pack/acp/start/ale/autoload/ale/julia.vim b/pack/acp/start/ale/autoload/ale/julia.vim new file mode 100644 index 0000000..18dd9ad --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/julia.vim @@ -0,0 +1,19 @@ +" Author: Bartolomeo Stellato bartolomeo.stellato@gmail.com +" Description: Functions for integrating with Julia tools + +" Find the nearest dir containing a julia project +let s:__ale_julia_project_filenames = ['REQUIRE', 'Manifest.toml', 'Project.toml'] + +function! ale#julia#FindProjectRoot(buffer) abort + for l:project_filename in s:__ale_julia_project_filenames + let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename) + + if !empty(l:full_path) + let l:path = fnamemodify(l:full_path, ':p:h') + + return l:path + endif + endfor + + return '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/linter.vim b/pack/acp/start/ale/autoload/ale/linter.vim new file mode 100644 index 0000000..78dcd3a --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/linter.vim @@ -0,0 +1,551 @@ +" Author: w0rp +" Description: Linter registration and lazy-loading +" Retrieves linters as requested by the engine, loading them if needed. + +let s:runtime_loaded_map = {} +let s:linters = {} + +" Default filetype aliases. +" The user defined aliases will be merged with this Dictionary. +" +" NOTE: Update the g:ale_linter_aliases documentation when modifying this. +let s:default_ale_linter_aliases = { +\ 'Dockerfile': 'dockerfile', +\ 'csh': 'sh', +\ 'plaintex': 'tex', +\ 'rmarkdown': 'r', +\ 'systemverilog': 'verilog', +\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], +\ 'vimwiki': 'markdown', +\ 'vue': ['vue', 'javascript'], +\ 'xsd': ['xsd', 'xml'], +\ 'xslt': ['xslt', 'xml'], +\ 'zsh': 'sh', +\} + +" Default linters to run for particular filetypes. +" The user defined linter selections will be merged with this Dictionary. +" +" No linters are used for plaintext files by default. +" +" Only cargo is enabled for Rust by default. +" rpmlint is disabled by default because it can result in code execution. +" hhast is disabled by default because it executes code in the project root. +" +" NOTE: Update the g:ale_linters documentation when modifying this. +let s:default_ale_linters = { +\ 'csh': ['shell'], +\ 'elixir': ['credo', 'dialyxir', 'dogma'], +\ 'go': ['gofmt', 'golint', 'go vet'], +\ 'hack': ['hack'], +\ 'help': [], +\ 'perl': ['perlcritic'], +\ 'perl6': [], +\ 'python': ['flake8', 'mypy', 'pylint'], +\ 'rust': ['cargo'], +\ 'spec': [], +\ 'text': [], +\ 'vue': ['eslint', 'vls'], +\ 'zsh': ['shell'], +\} + +" Testing/debugging helper to unload all linters. +function! ale#linter#Reset() abort + let s:runtime_loaded_map = {} + let s:linters = {} +endfunction + +" Return a reference to the linters loaded. +" This is only for tests. +" Do not call this function. +function! ale#linter#GetLintersLoaded() abort + " This command will throw from the sandbox. + let &l:equalprg=&l:equalprg + + return s:linters +endfunction + +function! s:IsCallback(value) abort + return type(a:value) is v:t_string || type(a:value) is v:t_func +endfunction + +function! s:IsBoolean(value) abort + return type(a:value) is v:t_number && (a:value == 0 || a:value == 1) +endfunction + +function! s:LanguageGetter(buffer) dict abort + return l:self.language +endfunction + +function! ale#linter#PreProcess(filetype, linter) abort + if type(a:linter) isnot v:t_dict + throw 'The linter object must be a Dictionary' + endif + + let l:obj = { + \ 'name': get(a:linter, 'name'), + \ 'lsp': get(a:linter, 'lsp', ''), + \} + + if type(l:obj.name) isnot v:t_string + throw '`name` must be defined to name the linter' + endif + + let l:needs_address = l:obj.lsp is# 'socket' + let l:needs_executable = l:obj.lsp isnot# 'socket' + let l:needs_command = l:obj.lsp isnot# 'socket' + let l:needs_lsp_details = !empty(l:obj.lsp) + + if empty(l:obj.lsp) + let l:obj.callback = get(a:linter, 'callback') + + if !s:IsCallback(l:obj.callback) + throw '`callback` must be defined with a callback to accept output' + endif + endif + + if index(['', 'socket', 'stdio', 'tsserver'], l:obj.lsp) < 0 + throw '`lsp` must be either `''lsp''`, `''stdio''`, `''socket''` or `''tsserver''` if defined' + endif + + if !l:needs_executable + if has_key(a:linter, 'executable') + \|| has_key(a:linter, 'executable_callback') + throw '`executable` and `executable_callback` cannot be used when lsp == ''socket''' + endif + elseif has_key(a:linter, 'executable_callback') + let l:obj.executable_callback = a:linter.executable_callback + + if !s:IsCallback(l:obj.executable_callback) + throw '`executable_callback` must be a callback if defined' + endif + elseif has_key(a:linter, 'executable') + let l:obj.executable = a:linter.executable + + if type(l:obj.executable) isnot v:t_string + \&& type(l:obj.executable) isnot v:t_func + throw '`executable` must be a String or Function if defined' + endif + else + throw 'Either `executable` or `executable_callback` must be defined' + endif + + if !l:needs_command + if has_key(a:linter, 'command') + \|| has_key(a:linter, 'command_callback') + \|| has_key(a:linter, 'command_chain') + throw '`command` and `command_callback` and `command_chain` cannot be used when lsp == ''socket''' + endif + elseif has_key(a:linter, 'command_chain') + let l:obj.command_chain = a:linter.command_chain + + if type(l:obj.command_chain) isnot v:t_list + throw '`command_chain` must be a List' + endif + + if empty(l:obj.command_chain) + throw '`command_chain` must contain at least one item' + endif + + let l:link_index = 0 + + for l:link in l:obj.command_chain + let l:err_prefix = 'The `command_chain` item ' . l:link_index . ' ' + + if !s:IsCallback(get(l:link, 'callback')) + throw l:err_prefix . 'must define a `callback` function' + endif + + if has_key(l:link, 'output_stream') + if type(l:link.output_stream) isnot v:t_string + \|| index(['stdout', 'stderr', 'both'], l:link.output_stream) < 0 + throw l:err_prefix . '`output_stream` flag must be ' + \ . "'stdout', 'stderr', or 'both'" + endif + endif + + if has_key(l:link, 'read_buffer') && !s:IsBoolean(l:link.read_buffer) + throw l:err_prefix . 'value for `read_buffer` must be `0` or `1`' + endif + + let l:link_index += 1 + endfor + elseif has_key(a:linter, 'command_callback') + let l:obj.command_callback = a:linter.command_callback + + if !s:IsCallback(l:obj.command_callback) + throw '`command_callback` must be a callback if defined' + endif + elseif has_key(a:linter, 'command') + let l:obj.command = a:linter.command + + if type(l:obj.command) isnot v:t_string + \&& type(l:obj.command) isnot v:t_func + throw '`command` must be a String or Function if defined' + endif + else + throw 'Either `command`, `executable_callback`, `command_chain` ' + \ . 'must be defined' + endif + + if ( + \ has_key(a:linter, 'command') + \ + has_key(a:linter, 'command_chain') + \ + has_key(a:linter, 'command_callback') + \) > 1 + throw 'Only one of `command`, `command_callback`, or `command_chain` ' + \ . 'should be set' + endif + + if !l:needs_address + if has_key(a:linter, 'address') || has_key(a:linter, 'address_callback') + throw '`address` or `address_callback` cannot be used when lsp != ''socket''' + endif + elseif has_key(a:linter, 'address') + if type(a:linter.address) isnot v:t_string + \&& type(a:linter.address) isnot v:t_func + throw '`address` must be a String or Function if defined' + endif + + let l:obj.address = a:linter.address + elseif has_key(a:linter, 'address_callback') + let l:obj.address_callback = a:linter.address_callback + + if !s:IsCallback(l:obj.address_callback) + throw '`address_callback` must be a callback if defined' + endif + else + throw '`address` or `address_callback` must be defined for getting the LSP address' + endif + + if l:needs_lsp_details + if has_key(a:linter, 'language_callback') + if has_key(a:linter, 'language') + throw 'Only one of `language` or `language_callback` ' + \ . 'should be set' + endif + + let l:obj.language_callback = get(a:linter, 'language_callback') + + if !s:IsCallback(l:obj.language_callback) + throw '`language_callback` must be a callback for LSP linters' + endif + else + " Default to using the filetype as the language. + let l:Language = get(a:linter, 'language', a:filetype) + + if type(l:Language) is v:t_string + " Make 'language_callback' return the 'language' value. + let l:obj.language = l:Language + let l:obj.language_callback = function('s:LanguageGetter') + elseif type(l:Language) is v:t_func + let l:obj.language_callback = l:Language + else + throw '`language` must be a String or Funcref' + endif + endif + + if has_key(a:linter, 'project_root') + let l:obj.project_root = a:linter.project_root + + if type(l:obj.project_root) isnot v:t_string + \&& type(l:obj.project_root) isnot v:t_func + throw '`project_root` must be a String or Function if defined' + endif + elseif has_key(a:linter, 'project_root_callback') + let l:obj.project_root_callback = a:linter.project_root_callback + + if !s:IsCallback(l:obj.project_root_callback) + throw '`project_root_callback` must be a callback if defined' + endif + else + throw '`project_root` or `project_root_callback` must be defined for LSP linters' + endif + + if has_key(a:linter, 'completion_filter') + let l:obj.completion_filter = a:linter.completion_filter + + if !s:IsCallback(l:obj.completion_filter) + throw '`completion_filter` must be a callback' + endif + endif + + if has_key(a:linter, 'initialization_options_callback') + if has_key(a:linter, 'initialization_options') + throw 'Only one of `initialization_options` or ' + \ . '`initialization_options_callback` should be set' + endif + + let l:obj.initialization_options_callback = a:linter.initialization_options_callback + + if !s:IsCallback(l:obj.initialization_options_callback) + throw '`initialization_options_callback` must be a callback if defined' + endif + elseif has_key(a:linter, 'initialization_options') + let l:obj.initialization_options = a:linter.initialization_options + + if type(l:obj.initialization_options) isnot v:t_dict + \&& type(l:obj.initialization_options) isnot v:t_func + throw '`initialization_options` must be a String or Function if defined' + endif + endif + + if has_key(a:linter, 'lsp_config_callback') + if has_key(a:linter, 'lsp_config') + throw 'Only one of `lsp_config` or `lsp_config_callback` should be set' + endif + + let l:obj.lsp_config_callback = a:linter.lsp_config_callback + + if !s:IsCallback(l:obj.lsp_config_callback) + throw '`lsp_config_callback` must be a callback if defined' + endif + elseif has_key(a:linter, 'lsp_config') + if type(a:linter.lsp_config) isnot v:t_dict + \&& type(a:linter.lsp_config) isnot v:t_func + throw '`lsp_config` must be a Dictionary or Function if defined' + endif + + let l:obj.lsp_config = a:linter.lsp_config + endif + endif + + let l:obj.output_stream = get(a:linter, 'output_stream', 'stdout') + + if type(l:obj.output_stream) isnot v:t_string + \|| index(['stdout', 'stderr', 'both'], l:obj.output_stream) < 0 + throw "`output_stream` must be 'stdout', 'stderr', or 'both'" + endif + + " An option indicating that this linter should only be run against the + " file on disk. + let l:obj.lint_file = get(a:linter, 'lint_file', 0) + + if !s:IsBoolean(l:obj.lint_file) + throw '`lint_file` must be `0` or `1`' + endif + + " An option indicating that the buffer should be read. + let l:obj.read_buffer = get(a:linter, 'read_buffer', !l:obj.lint_file) + + if !s:IsBoolean(l:obj.read_buffer) + throw '`read_buffer` must be `0` or `1`' + endif + + if l:obj.lint_file && l:obj.read_buffer + throw 'Only one of `lint_file` or `read_buffer` can be `1`' + endif + + let l:obj.aliases = get(a:linter, 'aliases', []) + + if type(l:obj.aliases) isnot v:t_list + \|| len(filter(copy(l:obj.aliases), 'type(v:val) isnot v:t_string')) > 0 + throw '`aliases` must be a List of String values' + endif + + for l:key in filter(keys(a:linter), 'v:val[-9:] is# ''_callback'' || v:val is# ''command_chain''') + if !get(g:, 'ale_ignore_2_4_warnings') + execute 'echom l:key . '' is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.''' + endif + + break + endfor + + return l:obj +endfunction + +function! ale#linter#Define(filetype, linter) abort + " This command will throw from the sandbox. + let &l:equalprg=&l:equalprg + + let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter) + + if !has_key(s:linters, a:filetype) + let s:linters[a:filetype] = [] + endif + + " Remove previously defined linters with the same name. + call filter(s:linters[a:filetype], 'v:val.name isnot# a:linter.name') + call add(s:linters[a:filetype], l:new_linter) +endfunction + +" Prevent any linters from being loaded for a given filetype. +function! ale#linter#PreventLoading(filetype) abort + let s:runtime_loaded_map[a:filetype] = 1 +endfunction + +function! ale#linter#GetAll(filetypes) abort + " Don't return linters in the sandbox. + " Otherwise a sandboxed script could modify them. + if ale#util#InSandbox() + return [] + endif + + let l:combined_linters = [] + + for l:filetype in a:filetypes + " Load linters from runtimepath if we haven't done that yet. + if !has_key(s:runtime_loaded_map, l:filetype) + execute 'silent! runtime! ale_linters/' . l:filetype . '/*.vim' + + let s:runtime_loaded_map[l:filetype] = 1 + endif + + call extend(l:combined_linters, get(s:linters, l:filetype, [])) + endfor + + return l:combined_linters +endfunction + +function! s:GetAliasedFiletype(original_filetype) abort + let l:buffer_aliases = get(b:, 'ale_linter_aliases', {}) + + " b:ale_linter_aliases can be set to a List or String. + if type(l:buffer_aliases) is v:t_list + \|| type(l:buffer_aliases) is v:t_string + return l:buffer_aliases + endif + + " Check for aliased filetypes first in a buffer variable, + " then the global variable, + " then in the default mapping, + " otherwise use the original filetype. + for l:dict in [ + \ l:buffer_aliases, + \ g:ale_linter_aliases, + \ s:default_ale_linter_aliases, + \] + if has_key(l:dict, a:original_filetype) + return l:dict[a:original_filetype] + endif + endfor + + return a:original_filetype +endfunction + +function! ale#linter#ResolveFiletype(original_filetype) abort + let l:filetype = s:GetAliasedFiletype(a:original_filetype) + + if type(l:filetype) isnot v:t_list + return [l:filetype] + endif + + return l:filetype +endfunction + +function! s:GetLinterNames(original_filetype) abort + let l:buffer_ale_linters = get(b:, 'ale_linters', {}) + + " b:ale_linters can be set to 'all' + if l:buffer_ale_linters is# 'all' + return 'all' + endif + + " b:ale_linters can be set to a List. + if type(l:buffer_ale_linters) is v:t_list + return l:buffer_ale_linters + endif + + " Try to get a buffer-local setting for the filetype + if has_key(l:buffer_ale_linters, a:original_filetype) + return l:buffer_ale_linters[a:original_filetype] + endif + + " Try to get a global setting for the filetype + if has_key(g:ale_linters, a:original_filetype) + return g:ale_linters[a:original_filetype] + endif + + " If the user has configured ALE to only enable linters explicitly, then + " don't enable any linters by default. + if g:ale_linters_explicit + return [] + endif + + " Try to get a default setting for the filetype + if has_key(s:default_ale_linters, a:original_filetype) + return s:default_ale_linters[a:original_filetype] + endif + + return 'all' +endfunction + +function! ale#linter#Get(original_filetypes) abort + let l:possibly_duplicated_linters = [] + + " Handle dot-separated filetypes. + for l:original_filetype in split(a:original_filetypes, '\.') + let l:filetype = ale#linter#ResolveFiletype(l:original_filetype) + let l:linter_names = s:GetLinterNames(l:original_filetype) + let l:all_linters = ale#linter#GetAll(l:filetype) + let l:filetype_linters = [] + + if type(l:linter_names) is v:t_string && l:linter_names is# 'all' + let l:filetype_linters = l:all_linters + elseif type(l:linter_names) is v:t_list + " Select only the linters we or the user has specified. + for l:linter in l:all_linters + let l:name_list = [l:linter.name] + l:linter.aliases + + for l:name in l:name_list + if index(l:linter_names, l:name) >= 0 + call add(l:filetype_linters, l:linter) + break + endif + endfor + endfor + endif + + call extend(l:possibly_duplicated_linters, l:filetype_linters) + endfor + + let l:name_list = [] + let l:combined_linters = [] + + " Make sure we override linters so we don't get two with the same name, + " like 'eslint' for both 'javascript' and 'typescript' + " + " Note that the reverse calls here modify the List variables. + for l:linter in reverse(l:possibly_duplicated_linters) + if index(l:name_list, l:linter.name) < 0 + call add(l:name_list, l:linter.name) + call add(l:combined_linters, l:linter) + endif + endfor + + return reverse(l:combined_linters) +endfunction + +" Given a buffer and linter, get the executable String for the linter. +function! ale#linter#GetExecutable(buffer, linter) abort + let l:Executable = has_key(a:linter, 'executable_callback') + \ ? function(a:linter.executable_callback) + \ : a:linter.executable + + return type(l:Executable) is v:t_func + \ ? l:Executable(a:buffer) + \ : l:Executable +endfunction + +" Given a buffer and linter, get the command String for the linter. +" The command_chain key is not supported. +function! ale#linter#GetCommand(buffer, linter) abort + let l:Command = has_key(a:linter, 'command_callback') + \ ? function(a:linter.command_callback) + \ : a:linter.command + + return type(l:Command) is v:t_func + \ ? l:Command(a:buffer) + \ : l:Command +endfunction + +" Given a buffer and linter, get the address for connecting to the server. +function! ale#linter#GetAddress(buffer, linter) abort + let l:Address = has_key(a:linter, 'address_callback') + \ ? function(a:linter.address_callback) + \ : a:linter.address + + return type(l:Address) is v:t_func + \ ? l:Address(a:buffer) + \ : l:Address +endfunction diff --git a/pack/acp/start/ale/autoload/ale/list.vim b/pack/acp/start/ale/autoload/ale/list.vim new file mode 100644 index 0000000..80a3021 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/list.vim @@ -0,0 +1,197 @@ +" Author: Bjorn Neergaard , modified by Yann fery +" Description: Manages the loclist and quickfix lists + +" This flag dictates if ale open the configured loclist +let g:ale_open_list = get(g:, 'ale_open_list', 0) +" This flag dictates if ale keeps open loclist even if there is no error in loclist +let g:ale_keep_list_window_open = get(g:, 'ale_keep_list_window_open', 0) +" This flag dictates that quickfix windows should be opened vertically +let g:ale_list_vertical = get(g:, 'ale_list_vertical', 0) +" The window size to set for the quickfix and loclist windows +let g:ale_list_window_size = get(g:, 'ale_list_window_size', 10) +" A string format for the loclist messages. +let g:ale_loclist_msg_format = get(g:, 'ale_loclist_msg_format', +\ get(g:, 'ale_echo_msg_format', '%code: %%s') +\) + +if !exists('s:timer_args') + let s:timer_args = {} +endif + +" Return 1 if there is a buffer with buftype == 'quickfix' in bufffer list +function! ale#list#IsQuickfixOpen() abort + for l:buf in range(1, bufnr('$')) + if getbufvar(l:buf, '&buftype') is# 'quickfix' + return 1 + endif + endfor + + return 0 +endfunction + +" Check if we should open the list, based on the save event being fired, and +" that setting being on, or the setting just being set to `1`. +function! s:ShouldOpen(buffer) abort + let l:val = ale#Var(a:buffer, 'open_list') + let l:saved = getbufvar(a:buffer, 'ale_save_event_fired', 0) + + return l:val is 1 || (l:val is# 'on_save' && l:saved) +endfunction + +function! ale#list#GetCombinedList() abort + let l:list = [] + + for l:info in values(g:ale_buffer_info) + call extend(l:list, l:info.loclist) + endfor + + call sort(l:list, function('ale#util#LocItemCompareWithText')) + call uniq(l:list, function('ale#util#LocItemCompareWithText')) + + return l:list +endfunction + +function! s:FixList(buffer, list) abort + let l:format = ale#Var(a:buffer, 'loclist_msg_format') + let l:new_list = [] + + for l:item in a:list + let l:fixed_item = copy(l:item) + + let l:fixed_item.text = ale#GetLocItemMessage(l:item, l:format) + + if l:item.bufnr == -1 + " If the buffer number is invalid, remove it. + call remove(l:fixed_item, 'bufnr') + endif + + call add(l:new_list, l:fixed_item) + endfor + + return l:new_list +endfunction + +function! s:WinFindBuf(buffer) abort + return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0] +endfunction + +function! s:SetListsImpl(timer_id, buffer, loclist) abort + let l:title = expand('#' . a:buffer . ':p') + + if g:ale_set_quickfix + let l:quickfix_list = ale#list#GetCombinedList() + + if has('nvim') + call setqflist(s:FixList(a:buffer, l:quickfix_list), ' ', l:title) + else + call setqflist(s:FixList(a:buffer, l:quickfix_list)) + call setqflist([], 'r', {'title': l:title}) + endif + elseif g:ale_set_loclist + " If windows support is off, win_findbuf() may not exist. + " We'll set result in the current window, which might not be correct, + " but it's better than nothing. + let l:ids = s:WinFindBuf(a:buffer) + + for l:id in l:ids + if has('nvim') + call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title) + else + call setloclist(l:id, s:FixList(a:buffer, a:loclist)) + call setloclist(l:id, [], 'r', {'title': l:title}) + endif + endfor + endif + + " Open a window to show the problems if we need to. + " + " We'll check if the current buffer's List is not empty here, so the + " window will only be opened if the current buffer has problems. + if s:ShouldOpen(a:buffer) && !empty(a:loclist) + let l:winnr = winnr() + let l:mode = mode() + let l:reset_visual_selection = l:mode is? 'v' || l:mode is# "\" + let l:reset_character_selection = l:mode is? 's' || l:mode is# "\" + + " open windows vertically instead of default horizontally + let l:open_type = '' + + if ale#Var(a:buffer, 'list_vertical') == 1 + let l:open_type = 'vert rightbelow ' + endif + + if g:ale_set_quickfix + if !ale#list#IsQuickfixOpen() + silent! execute l:open_type . 'copen ' . str2nr(ale#Var(a:buffer, 'list_window_size')) + endif + elseif g:ale_set_loclist + silent! execute l:open_type . 'lopen ' . str2nr(ale#Var(a:buffer, 'list_window_size')) + endif + + " If focus changed, restore it (jump to the last window). + if l:winnr isnot# winnr() + wincmd p + endif + + if l:reset_visual_selection || l:reset_character_selection + " If we were in a selection mode before, select the last selection. + normal! gv + + if l:reset_character_selection + " Switch back to Select mode, if we were in that. + normal! "\" + endif + endif + endif + + " If ALE isn't currently checking for more problems, close the window if + " needed now. This check happens inside of this timer function, so + " the window can be closed reliably. + if !ale#engine#IsCheckingBuffer(a:buffer) + call s:CloseWindowIfNeeded(a:buffer) + endif +endfunction + +function! ale#list#SetLists(buffer, loclist) abort + if get(g:, 'ale_set_lists_synchronously') == 1 + \|| getbufvar(a:buffer, 'ale_save_event_fired', 0) + " Update lists immediately if running a test synchronously, or if the + " buffer was saved. + " + " The lists need to be updated immediately when saving a buffer so + " that we can reliably close window automatically, if so configured. + call s:SetListsImpl(-1, a:buffer, a:loclist) + else + call ale#util#StartPartialTimer( + \ 0, + \ function('s:SetListsImpl'), + \ [a:buffer, a:loclist], + \) + endif +endfunction + +function! s:CloseWindowIfNeeded(buffer) abort + if ale#Var(a:buffer, 'keep_list_window_open') || !s:ShouldOpen(a:buffer) + return + endif + + try + " Only close windows if the quickfix list or loclist is completely empty, + " including errors set through other means. + if g:ale_set_quickfix + if empty(getqflist()) + cclose + endif + else + let l:win_ids = s:WinFindBuf(a:buffer) + + for l:win_id in l:win_ids + if g:ale_set_loclist && empty(getloclist(l:win_id)) + lclose + endif + endfor + endif + " Ignore 'Cannot close last window' errors. + catch /E444/ + endtry +endfunction diff --git a/pack/acp/start/ale/autoload/ale/loclist_jumping.vim b/pack/acp/start/ale/autoload/ale/loclist_jumping.vim new file mode 100644 index 0000000..55097d1 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/loclist_jumping.vim @@ -0,0 +1,163 @@ +" Author: w0rp +" Description: This file implements functions for jumping around in a file +" based on ALE's internal loclist. + +" Search for the nearest line either before or after the current position +" in the loclist. The argument 'wrap' can be passed to enable wrapping +" around the end of the list. +" +" If there are no items or we have hit the end with wrapping off, an empty +" List will be returned, otherwise a pair of [line_number, column_number] will +" be returned. +function! ale#loclist_jumping#FindNearest(direction, wrap, ...) abort + let l:buffer = bufnr('') + let l:pos = getpos('.') + let l:info = get(g:ale_buffer_info, bufnr('%'), {'loclist': []}) + " Copy the list and filter to only the items in this buffer. + let l:loclist = filter(copy(l:info.loclist), 'v:val.bufnr == l:buffer') + let l:search_item = {'bufnr': l:buffer, 'lnum': l:pos[1], 'col': l:pos[2]} + + if a:0 > 0 + let l:filter = a:1 + else + let l:filter = 'any' + endif + + if a:0 > 1 + let l:subtype_filter = a:2 + else + let l:subtype_filter = 'any' + endif + + " When searching backwards, so we can find the next smallest match. + if a:direction is# 'before' + call reverse(l:loclist) + endif + + " Look for items before or after the current position. + for l:item in l:loclist + " Compare the cursor with a item where the column number is bounded, + " such that it's possible for the cursor to actually be on the given + " column number, without modifying the cursor number we return. This + " will allow us to move through matches, but still let us move the + " cursor to a line without changing the column, in some cases. + let l:cmp_value = ale#util#LocItemCompare( + \ { + \ 'bufnr': l:buffer, + \ 'lnum': l:item.lnum, + \ 'col': min([ + \ max([l:item.col, 1]), + \ max([len(getline(l:item.lnum)), 1]), + \ ]), + \ }, + \ l:search_item + \) + + if (l:filter is# 'any' || l:filter is# l:item.type) + \&& ( + \ l:subtype_filter is# 'any' + \ || l:subtype_filter is# get(l:item, 'sub_type', '') + \) + + if a:direction is# 'before' && l:cmp_value < 0 + return [l:item.lnum, l:item.col] + endif + + if a:direction is# 'after' && l:cmp_value > 0 + return [l:item.lnum, l:item.col] + endif + endif + endfor + + " If we found nothing, and the wrap option is set to 1, then we should + " wrap around the list of warnings/errors + if a:wrap + for l:item in l:loclist + if (l:filter is# 'any' || l:filter is# l:item.type) + \&& ( + \ l:subtype_filter is# 'any' + \ || l:subtype_filter is# get(l:item, 'sub_type', '') + \) + return [l:item.lnum, l:item.col] + endif + endfor + endif + + return [] +endfunction + +" As before, find the nearest match, but position the cursor at it. +function! ale#loclist_jumping#Jump(direction, ...) abort + if a:0 > 0 + let l:wrap = a:1 + else + let l:wrap = 0 + endif + + if a:0 > 1 + let l:filter = a:2 + else + let l:filter = 'any' + endif + + if a:0 > 2 + let l:subtype_filter = a:3 + else + let l:subtype_filter = 'any' + endif + + let l:nearest = ale#loclist_jumping#FindNearest(a:direction, + \ l:wrap, l:filter, l:subtype_filter) + + if !empty(l:nearest) + normal! m` + call cursor([l:nearest[0], max([l:nearest[1], 1])]) + endif +endfunction + +function! ale#loclist_jumping#WrapJump(direction, sargs) abort + let [l:args, l:rest] = ale#args#Parse(['error', 'warning', 'info', 'wrap', + \ 'style', 'nostyle'], a:sargs) + + let l:wrap = 0 + let l:type_filter = 'any' + let l:subtype_filter = 'any' + + if get(l:args, 'wrap', 'nil') is# '' + let l:wrap = 1 + endif + + if get(l:args, 'error', 'nil') is# '' + let l:type_filter = 'E' + elseif get(l:args, 'warning', 'nil') is# '' + let l:type_filter = 'W' + elseif get(l:args, 'info', 'nil') is# '' + let l:type_filter = 'I' + endif + + if get(l:args, 'nostyle', 'nil') is# '' + let l:subtype_filter = 'style' + elseif get(l:args, 'style', 'nil') is# '' + let l:subtype_filter = '' + endif + + call ale#loclist_jumping#Jump(a:direction, l:wrap, l:type_filter, + \ l:subtype_filter) +endfunction + +function! ale#loclist_jumping#JumpToIndex(index) abort + let l:buffer = bufnr('') + let l:info = get(g:ale_buffer_info, l:buffer, {'loclist': []}) + let l:loclist = filter(copy(l:info.loclist), 'v:val.bufnr == l:buffer') + + if empty(l:loclist) + return + endif + + let l:item = l:loclist[a:index] + + if !empty(l:item) + normal! m` + call cursor([l:item.lnum, l:item.col]) + endif +endfunction diff --git a/pack/acp/start/ale/autoload/ale/lsp.vim b/pack/acp/start/ale/autoload/ale/lsp.vim new file mode 100644 index 0000000..017096c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/lsp.vim @@ -0,0 +1,631 @@ +" Author: w0rp +" Description: Language Server Protocol client code + +" A Dictionary for tracking connections. +let s:connections = get(s:, 'connections', {}) +let g:ale_lsp_next_message_id = 1 + +" Given an id, which can be an executable or address, and a project path, +" create a new connection if needed. Return a unique ID for the connection. +function! ale#lsp#Register(executable_or_address, project, init_options) abort + let l:conn_id = a:executable_or_address . ':' . a:project + + if !has_key(s:connections, l:conn_id) + " is_tsserver: 1 if the connection is for tsserver. + " data: The message data received so far. + " root: The project root. + " open_documents: A Dictionary mapping buffers to b:changedtick, keeping + " track of when documents were opened, and when we last changed them. + " initialized: 0 if the connection is ready, 1 otherwise. + " init_request_id: The ID for the init request. + " init_options: Options to send to the server. + " config: Configuration settings to send to the server. + " callback_list: A list of callbacks for handling LSP responses. + " capabilities_queue: The list of callbacks to call with capabilities. + " capabilities: Features the server supports. + let s:connections[l:conn_id] = { + \ 'id': l:conn_id, + \ 'is_tsserver': 0, + \ 'data': '', + \ 'root': a:project, + \ 'open_documents': {}, + \ 'initialized': 0, + \ 'init_request_id': 0, + \ 'init_options': a:init_options, + \ 'config': {}, + \ 'callback_list': [], + \ 'init_queue': [], + \ 'capabilities': { + \ 'hover': 0, + \ 'references': 0, + \ 'completion': 0, + \ 'completion_trigger_characters': [], + \ 'definition': 0, + \ 'typeDefinition': 0, + \ 'symbol_search': 0, + \ }, + \} + endif + + return l:conn_id +endfunction + +" Remove an LSP connection with a given ID. This is only for tests. +function! ale#lsp#RemoveConnectionWithID(id) abort + if has_key(s:connections, a:id) + call remove(s:connections, a:id) + endif +endfunction + +function! ale#lsp#ResetConnections() abort + let s:connections = {} +endfunction + +" Used only in tests. +function! ale#lsp#GetConnections() abort + return s:connections +endfunction + +" This is only needed for tests +function! ale#lsp#MarkDocumentAsOpen(id, buffer) abort + let l:conn = get(s:connections, a:id, {}) + + if !empty(l:conn) + let l:conn.open_documents[a:buffer] = -1 + endif +endfunction + +function! ale#lsp#GetNextMessageID() abort + " Use the current ID + let l:id = g:ale_lsp_next_message_id + + " Increment the ID variable. + let g:ale_lsp_next_message_id += 1 + + " When the ID overflows, reset it to 1. By the time we hit the initial ID + " again, the messages will be long gone. + if g:ale_lsp_next_message_id < 1 + let g:ale_lsp_next_message_id = 1 + endif + + return l:id +endfunction + +" TypeScript messages use a different format. +function! s:CreateTSServerMessageData(message) abort + let l:is_notification = a:message[0] + + let l:obj = { + \ 'seq': v:null, + \ 'type': 'request', + \ 'command': a:message[1][3:], + \} + + if !l:is_notification + let l:obj.seq = ale#lsp#GetNextMessageID() + endif + + if len(a:message) > 2 + let l:obj.arguments = a:message[2] + endif + + let l:data = json_encode(l:obj) . "\n" + + return [l:is_notification ? 0 : l:obj.seq, l:data] +endfunction + +" Given a List of one or two items, [method_name] or [method_name, params], +" return a List containing [message_id, message_data] +function! ale#lsp#CreateMessageData(message) abort + if a:message[1][:2] is# 'ts@' + return s:CreateTSServerMessageData(a:message) + endif + + let l:is_notification = a:message[0] + + let l:obj = { + \ 'method': a:message[1], + \ 'jsonrpc': '2.0', + \} + + if !l:is_notification + let l:obj.id = ale#lsp#GetNextMessageID() + endif + + if len(a:message) > 2 + let l:obj.params = a:message[2] + endif + + let l:body = json_encode(l:obj) + let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body + + return [l:is_notification ? 0 : l:obj.id, l:data] +endfunction + +function! ale#lsp#ReadMessageData(data) abort + let l:response_list = [] + let l:remainder = a:data + + while 1 + " Look for the end of the HTTP headers + let l:body_start_index = matchend(l:remainder, "\r\n\r\n") + + if l:body_start_index < 0 + " No header end was found yet. + break + endif + + " Parse the Content-Length header. + let l:header_data = l:remainder[:l:body_start_index - 4] + let l:length_match = matchlist( + \ l:header_data, + \ '\vContent-Length: *(\d+)' + \) + + if empty(l:length_match) + throw "Invalid JSON-RPC header:\n" . l:header_data + endif + + " Split the body and the remainder of the text. + let l:remainder_start_index = l:body_start_index + str2nr(l:length_match[1]) + + if len(l:remainder) < l:remainder_start_index + " We don't have enough data yet. + break + endif + + let l:body = l:remainder[l:body_start_index : l:remainder_start_index - 1] + let l:remainder = l:remainder[l:remainder_start_index :] + + " Parse the JSON object and add it to the list. + call add(l:response_list, json_decode(l:body)) + endwhile + + return [l:remainder, l:response_list] +endfunction + +" Update capabilities from the server, so we know which features the server +" supports. +function! s:UpdateCapabilities(conn, capabilities) abort + if type(a:capabilities) isnot v:t_dict + return + endif + + if get(a:capabilities, 'hoverProvider') is v:true + let a:conn.capabilities.hover = 1 + endif + + if get(a:capabilities, 'referencesProvider') is v:true + let a:conn.capabilities.references = 1 + endif + + if !empty(get(a:capabilities, 'completionProvider')) + let a:conn.capabilities.completion = 1 + endif + + if type(get(a:capabilities, 'completionProvider')) is v:t_dict + let l:chars = get(a:capabilities.completionProvider, 'triggerCharacters') + + if type(l:chars) is v:t_list + let a:conn.capabilities.completion_trigger_characters = l:chars + endif + endif + + if get(a:capabilities, 'definitionProvider') is v:true + let a:conn.capabilities.definition = 1 + endif + + if get(a:capabilities, 'typeDefinitionProvider') is v:true + let a:conn.capabilities.typeDefinition = 1 + endif + + if get(a:capabilities, 'workspaceSymbolProvider') is v:true + let a:conn.capabilities.symbol_search = 1 + endif +endfunction + +" Update a connection's configuration dictionary and notify LSP servers +" of any changes since the last update. Returns 1 if a configuration +" update was sent; otherwise 0 will be returned. +function! ale#lsp#UpdateConfig(conn_id, buffer, config) abort + let l:conn = get(s:connections, a:conn_id, {}) + + if empty(l:conn) || a:config ==# l:conn.config " no-custom-checks + return 0 + endif + + let l:conn.config = a:config + let l:message = ale#lsp#message#DidChangeConfiguration(a:buffer, a:config) + + call ale#lsp#Send(a:conn_id, l:message) + + return 1 +endfunction + + +function! ale#lsp#HandleInitResponse(conn, response) abort + if get(a:response, 'method', '') is# 'initialize' + let a:conn.initialized = 1 + elseif type(get(a:response, 'result')) is v:t_dict + \&& has_key(a:response.result, 'capabilities') + call s:UpdateCapabilities(a:conn, a:response.result.capabilities) + + let a:conn.initialized = 1 + endif + + if !a:conn.initialized + return + endif + + " The initialized message must be sent before everything else. + call ale#lsp#Send(a:conn.id, ale#lsp#message#Initialized()) + + " Call capabilities callbacks queued for the project. + for l:Callback in a:conn.init_queue + call l:Callback() + endfor + + let a:conn.init_queue = [] +endfunction + +function! ale#lsp#HandleMessage(conn_id, message) abort + let l:conn = get(s:connections, a:conn_id, {}) + + if empty(l:conn) + return + endif + + if type(a:message) isnot v:t_string + " Ignore messages that aren't strings. + return + endif + + let l:conn.data .= a:message + + " Parse the objects now if we can, and keep the remaining text. + let [l:conn.data, l:response_list] = ale#lsp#ReadMessageData(l:conn.data) + + " Look for initialize responses first. + if !l:conn.initialized + for l:response in l:response_list + call ale#lsp#HandleInitResponse(l:conn, l:response) + endfor + endif + + " If the connection is marked as initialized, call the callbacks with the + " responses. + if l:conn.initialized + for l:response in l:response_list + " Call all of the registered handlers with the response. + for l:Callback in l:conn.callback_list + call ale#util#GetFunction(l:Callback)(a:conn_id, l:response) + endfor + endfor + endif +endfunction + +" Given a connection ID, mark it as a tsserver connection, so it will be +" handled that way. +function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort + let l:conn = s:connections[a:conn_id] + let l:conn.is_tsserver = 1 + let l:conn.initialized = 1 + " Set capabilities which are supported by tsserver. + let l:conn.capabilities.hover = 1 + let l:conn.capabilities.references = 1 + let l:conn.capabilities.completion = 1 + let l:conn.capabilities.completion_trigger_characters = ['.'] + let l:conn.capabilities.definition = 1 + let l:conn.capabilities.symbol_search = 1 +endfunction + +function! s:SendInitMessage(conn) abort + let [l:init_id, l:init_data] = ale#lsp#CreateMessageData( + \ ale#lsp#message#Initialize( + \ a:conn.root, + \ a:conn.init_options, + \ { + \ 'workspace': { + \ 'applyEdit': v:false, + \ 'didChangeConfiguration': { + \ 'dynamicRegistration': v:false, + \ }, + \ 'symbol': { + \ 'dynamicRegistration': v:false, + \ }, + \ 'workspaceFolders': v:false, + \ 'configuration': v:false, + \ }, + \ 'textDocument': { + \ 'synchronization': { + \ 'dynamicRegistration': v:false, + \ 'willSave': v:false, + \ 'willSaveWaitUntil': v:false, + \ 'didSave': v:true, + \ }, + \ 'completion': { + \ 'dynamicRegistration': v:false, + \ 'completionItem': { + \ 'snippetSupport': v:false, + \ 'commitCharactersSupport': v:false, + \ 'documentationFormat': ['plaintext'], + \ 'deprecatedSupport': v:false, + \ 'preselectSupport': v:false, + \ }, + \ 'contextSupport': v:false, + \ }, + \ 'hover': { + \ 'dynamicRegistration': v:false, + \ 'contentFormat': ['plaintext'], + \ }, + \ 'references': { + \ 'dynamicRegistration': v:false, + \ }, + \ 'documentSymbol': { + \ 'dynamicRegistration': v:false, + \ 'hierarchicalDocumentSymbolSupport': v:false, + \ }, + \ 'definition': { + \ 'dynamicRegistration': v:false, + \ 'linkSupport': v:false, + \ }, + \ 'typeDefinition': { + \ 'dynamicRegistration': v:false, + \ }, + \ 'publishDiagnostics': { + \ 'relatedInformation': v:true, + \ }, + \ 'codeAction': { + \ 'dynamicRegistration': v:false, + \ }, + \ 'rename': { + \ 'dynamicRegistration': v:false, + \ }, + \ }, + \ }, + \ ), + \) + let a:conn.init_request_id = l:init_id + call s:SendMessageData(a:conn, l:init_data) +endfunction + +" Start a program for LSP servers. +" +" 1 will be returned if the program is running, or 0 if the program could +" not be started. +function! ale#lsp#StartProgram(conn_id, executable, command) abort + let l:conn = s:connections[a:conn_id] + let l:started = 0 + + if !has_key(l:conn, 'job_id') || !ale#job#HasOpenChannel(l:conn.job_id) + let l:options = { + \ 'mode': 'raw', + \ 'out_cb': {_, message -> ale#lsp#HandleMessage(a:conn_id, message)}, + \} + + if has('win32') + let l:job_id = ale#job#StartWithCmd(a:command, l:options) + else + let l:job_id = ale#job#Start(a:command, l:options) + endif + + let l:started = 1 + else + let l:job_id = l:conn.job_id + endif + + if l:job_id > 0 + let l:conn.job_id = l:job_id + endif + + if l:started && !l:conn.is_tsserver + call s:SendInitMessage(l:conn) + endif + + return l:job_id > 0 +endfunction + +" Connect to an LSP server via TCP. +" +" 1 will be returned if the connection is running, or 0 if the connection could +" not be opened. +function! ale#lsp#ConnectToAddress(conn_id, address) abort + let l:conn = s:connections[a:conn_id] + let l:started = 0 + + if !has_key(l:conn, 'channel_id') || !ale#socket#IsOpen(l:conn.channel_id) + let l:channel_id = ale#socket#Open(a:address, { + \ 'callback': {_, mess -> ale#lsp#HandleMessage(a:conn_id, mess)}, + \}) + + let l:started = 1 + else + let l:channel_id = l:conn.channel_id + endif + + if l:channel_id >= 0 + let l:conn.channel_id = l:channel_id + endif + + if l:started + call s:SendInitMessage(l:conn) + endif + + return l:channel_id >= 0 +endfunction + +" Given a connection ID and a callback, register that callback for handling +" messages if the connection exists. +function! ale#lsp#RegisterCallback(conn_id, callback) abort + let l:conn = get(s:connections, a:conn_id, {}) + + if !empty(l:conn) + " Add the callback to the List if it's not there already. + call uniq(sort(add(l:conn.callback_list, a:callback))) + endif +endfunction + +" Stop a single LSP connection. +function! ale#lsp#Stop(conn_id) abort + if has_key(s:connections, a:conn_id) + let l:conn = remove(s:connections, a:conn_id) + + if has_key(l:conn, 'channel_id') + call ale#socket#Close(l:conn.channel_id) + elseif has_key(l:conn, 'job_id') + call ale#job#Stop(l:conn.job_id) + endif + endif +endfunction + +function! ale#lsp#CloseDocument(conn_id) abort +endfunction + +" Stop all LSP connections, closing all jobs and channels, and removing any +" queued messages. +function! ale#lsp#StopAll() abort + for l:conn_id in keys(s:connections) + call ale#lsp#Stop(l:conn_id) + endfor +endfunction + +function! s:SendMessageData(conn, data) abort + if has_key(a:conn, 'job_id') + call ale#job#SendRaw(a:conn.job_id, a:data) + elseif has_key(a:conn, 'channel_id') && ale#socket#IsOpen(a:conn.channel_id) + " Send the message to the server + call ale#socket#Send(a:conn.channel_id, a:data) + else + return 0 + endif + + return 1 +endfunction + +" Send a message to an LSP server. +" Notifications do not need to be handled. +" +" Returns -1 when a message is sent, but no response is expected +" 0 when the message is not sent and +" >= 1 with the message ID when a response is expected. +function! ale#lsp#Send(conn_id, message) abort + let l:conn = get(s:connections, a:conn_id, {}) + + if empty(l:conn) + return 0 + endif + + if !l:conn.initialized + throw 'LSP server not initialized yet!' + endif + + let [l:id, l:data] = ale#lsp#CreateMessageData(a:message) + call s:SendMessageData(l:conn, l:data) + + return l:id == 0 ? -1 : l:id +endfunction + +" Notify LSP servers or tsserver if a document is opened, if needed. +" If a document is opened, 1 will be returned, otherwise 0 will be returned. +function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort + let l:conn = get(s:connections, a:conn_id, {}) + let l:opened = 0 + + if !empty(l:conn) && !has_key(l:conn.open_documents, a:buffer) + if l:conn.is_tsserver + let l:message = ale#lsp#tsserver_message#Open(a:buffer) + else + let l:message = ale#lsp#message#DidOpen(a:buffer, a:language_id) + endif + + call ale#lsp#Send(a:conn_id, l:message) + let l:conn.open_documents[a:buffer] = getbufvar(a:buffer, 'changedtick') + let l:opened = 1 + endif + + return l:opened +endfunction + +" Notify LSP servers or tsserver that a document is closed, if opened before. +" If a document is closed, 1 will be returned, otherwise 0 will be returned. +" +" Only the buffer number is required here. A message will be sent to every +" language server that was notified previously of the document being opened. +function! ale#lsp#CloseDocument(buffer) abort + let l:closed = 0 + + " The connection keys are sorted so the messages are easier to test, and + " so messages are sent in a consistent order. + for l:conn_id in sort(keys(s:connections)) + let l:conn = s:connections[l:conn_id] + + if l:conn.initialized && has_key(l:conn.open_documents, a:buffer) + if l:conn.is_tsserver + let l:message = ale#lsp#tsserver_message#Close(a:buffer) + else + let l:message = ale#lsp#message#DidClose(a:buffer) + endif + + call ale#lsp#Send(l:conn_id, l:message) + call remove(l:conn.open_documents, a:buffer) + let l:closed = 1 + endif + endfor + + return l:closed +endfunction + +" Notify LSP servers or tsserver that a document has changed, if needed. +" If a notification is sent, 1 will be returned, otherwise 0 will be returned. +function! ale#lsp#NotifyForChanges(conn_id, buffer) abort + let l:conn = get(s:connections, a:conn_id, {}) + let l:notified = 0 + + if !empty(l:conn) && has_key(l:conn.open_documents, a:buffer) + let l:new_tick = getbufvar(a:buffer, 'changedtick') + + if l:conn.open_documents[a:buffer] < l:new_tick + if l:conn.is_tsserver + let l:message = ale#lsp#tsserver_message#Change(a:buffer) + else + let l:message = ale#lsp#message#DidChange(a:buffer) + endif + + call ale#lsp#Send(a:conn_id, l:message) + let l:conn.open_documents[a:buffer] = l:new_tick + let l:notified = 1 + endif + endif + + return l:notified +endfunction + +" Wait for an LSP server to be initialized. +function! ale#lsp#OnInit(conn_id, Callback) abort + let l:conn = get(s:connections, a:conn_id, {}) + + if empty(l:conn) + return + endif + + if l:conn.initialized + call a:Callback() + else + call add(l:conn.init_queue, a:Callback) + endif +endfunction + +" Check if an LSP has a given capability. +function! ale#lsp#HasCapability(conn_id, capability) abort + let l:conn = get(s:connections, a:conn_id, {}) + + if empty(l:conn) + return 0 + endif + + if type(get(l:conn.capabilities, a:capability, v:null)) isnot v:t_number + throw 'Invalid capability ' . a:capability + endif + + return l:conn.capabilities[a:capability] +endfunction diff --git a/pack/acp/start/ale/autoload/ale/lsp/message.vim b/pack/acp/start/ale/autoload/ale/lsp/message.vim new file mode 100644 index 0000000..b6b14a2 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/lsp/message.vim @@ -0,0 +1,164 @@ +" Author: w0rp +" Description: Language Server Protocol message implementations +" +" Messages in this movie will be returned in the format +" [is_notification, method_name, params?] +" +" All functions which accept line and column arguments expect them to be 1-based +" (the same format as being returned by getpos() and friends), those then +" will be converted to 0-based as specified by LSP. +let g:ale_lsp_next_version_id = 1 + +" The LSP protocols demands that we send every change to a document, including +" undo, with incrementing version numbers, so we'll just use one incrementing +" ID for everything. +function! ale#lsp#message#GetNextVersionID() abort + " Use the current ID + let l:id = g:ale_lsp_next_version_id + + " Increment the ID variable. + let g:ale_lsp_next_version_id += 1 + + " When the ID overflows, reset it to 1. By the time we hit the initial ID + " again, the messages will be long gone. + if g:ale_lsp_next_version_id < 1 + let g:ale_lsp_next_version_id = 1 + endif + + return l:id +endfunction + +function! ale#lsp#message#Initialize(root_path, options, capabilities) abort + " NOTE: rootPath is deprecated in favour of rootUri + return [0, 'initialize', { + \ 'processId': getpid(), + \ 'rootPath': a:root_path, + \ 'capabilities': a:capabilities, + \ 'initializationOptions': a:options, + \ 'rootUri': ale#path#ToURI(a:root_path), + \}] +endfunction + +function! ale#lsp#message#Initialized() abort + return [1, 'initialized', {}] +endfunction + +function! ale#lsp#message#Shutdown() abort + return [0, 'shutdown'] +endfunction + +function! ale#lsp#message#Exit() abort + return [1, 'exit'] +endfunction + +function! ale#lsp#message#DidOpen(buffer, language_id) abort + let l:lines = getbufline(a:buffer, 1, '$') + + return [1, 'textDocument/didOpen', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ 'languageId': a:language_id, + \ 'version': ale#lsp#message#GetNextVersionID(), + \ 'text': join(l:lines, "\n") . "\n", + \ }, + \}] +endfunction + +function! ale#lsp#message#DidChange(buffer) abort + let l:lines = getbufline(a:buffer, 1, '$') + + " For changes, we simply send the full text of the document to the server. + return [1, 'textDocument/didChange', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ 'version': ale#lsp#message#GetNextVersionID(), + \ }, + \ 'contentChanges': [{'text': join(l:lines, "\n") . "\n"}] + \}] +endfunction + +function! ale#lsp#message#DidSave(buffer) abort + return [1, 'textDocument/didSave', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \}] +endfunction + +function! ale#lsp#message#DidClose(buffer) abort + return [1, 'textDocument/didClose', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \}] +endfunction + +let s:COMPLETION_TRIGGER_INVOKED = 1 +let s:COMPLETION_TRIGGER_CHARACTER = 2 + +function! ale#lsp#message#Completion(buffer, line, column, trigger_character) abort + let l:message = [0, 'textDocument/completion', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \ 'position': {'line': a:line - 1, 'character': a:column - 1}, + \}] + + if !empty(a:trigger_character) + let l:message[2].context = { + \ 'triggerKind': s:COMPLETION_TRIGGER_CHARACTER, + \ 'triggerCharacter': a:trigger_character, + \} + endif + + return l:message +endfunction + +function! ale#lsp#message#Definition(buffer, line, column) abort + return [0, 'textDocument/definition', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \ 'position': {'line': a:line - 1, 'character': a:column - 1}, + \}] +endfunction + +function! ale#lsp#message#TypeDefinition(buffer, line, column) abort + return [0, 'textDocument/typeDefinition', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \ 'position': {'line': a:line - 1, 'character': a:column - 1}, + \}] +endfunction + +function! ale#lsp#message#References(buffer, line, column) abort + return [0, 'textDocument/references', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \ 'position': {'line': a:line - 1, 'character': a:column - 1}, + \ 'context': {'includeDeclaration': v:false}, + \}] +endfunction + +function! ale#lsp#message#Symbol(query) abort + return [0, 'workspace/symbol', { + \ 'query': a:query, + \}] +endfunction + +function! ale#lsp#message#Hover(buffer, line, column) abort + return [0, 'textDocument/hover', { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), + \ }, + \ 'position': {'line': a:line - 1, 'character': a:column - 1}, + \}] +endfunction + +function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort + return [1, 'workspace/didChangeConfiguration', { + \ 'settings': a:config, + \}] +endfunction diff --git a/pack/acp/start/ale/autoload/ale/lsp/reset.vim b/pack/acp/start/ale/autoload/ale/lsp/reset.vim new file mode 100644 index 0000000..2fc7f0a --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/lsp/reset.vim @@ -0,0 +1,25 @@ +" Stop all LSPs and remove all of the data for them. +function! ale#lsp#reset#StopAllLSPs() abort + call ale#lsp#StopAll() + + if exists('*ale#definition#ClearLSPData') + " Clear the mapping for connections, etc. + call ale#definition#ClearLSPData() + endif + + if exists('*ale#lsp_linter#ClearLSPData') + " Clear the mapping for connections, etc. + call ale#lsp_linter#ClearLSPData() + + " Remove the problems for all of the LSP linters in every buffer. + for l:buffer_string in keys(g:ale_buffer_info) + let l:buffer = str2nr(l:buffer_string) + + for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype')) + if !empty(l:linter.lsp) + call ale#engine#HandleLoclist(l:linter.name, l:buffer, [], 0) + endif + endfor + endfor + endif +endfunction diff --git a/pack/acp/start/ale/autoload/ale/lsp/response.vim b/pack/acp/start/ale/autoload/ale/lsp/response.vim new file mode 100644 index 0000000..30da77e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/lsp/response.vim @@ -0,0 +1,151 @@ +" Author: w0rp +" Description: Parsing and transforming of LSP server responses. + +" Constants for error codes. +" Defined by JSON RPC +let s:PARSE_ERROR = -32700 +let s:INVALID_REQUEST = -32600 +let s:METHOD_NOT_FOUND = -32601 +let s:INVALID_PARAMS = -32602 +let s:INTERNAL_ERROR = -32603 +let s:SERVER_ERROR_START = -32099 +let s:SERVER_ERROR_END = -32000 +let s:SERVER_NOT_INITIALIZED = -32002 +let s:UNKNOWN_ERROR_CODE = -32001 +" Defined by the protocol. +let s:REQUEST_CANCELLED = -32800 + +" Constants for message severity codes. +let s:SEVERITY_ERROR = 1 +let s:SEVERITY_WARNING = 2 +let s:SEVERITY_INFORMATION = 3 +let s:SEVERITY_HINT = 4 + +" Parse the message for textDocument/publishDiagnostics +function! ale#lsp#response#ReadDiagnostics(response) abort + let l:loclist = [] + + for l:diagnostic in a:response.params.diagnostics + let l:severity = get(l:diagnostic, 'severity', 0) + let l:loclist_item = { + \ 'text': substitute(l:diagnostic.message, '\(\r\n\|\n\|\r\)', ' ', 'g'), + \ 'type': 'E', + \ 'lnum': l:diagnostic.range.start.line + 1, + \ 'col': l:diagnostic.range.start.character + 1, + \ 'end_lnum': l:diagnostic.range.end.line + 1, + \ 'end_col': l:diagnostic.range.end.character, + \} + + if l:severity == s:SEVERITY_WARNING + let l:loclist_item.type = 'W' + elseif l:severity == s:SEVERITY_INFORMATION + " TODO: Use 'I' here in future. + let l:loclist_item.type = 'W' + elseif l:severity == s:SEVERITY_HINT + " TODO: Use 'H' here in future + let l:loclist_item.type = 'W' + endif + + if has_key(l:diagnostic, 'code') + if type(l:diagnostic.code) == v:t_string + let l:loclist_item.code = l:diagnostic.code + elseif type(l:diagnostic.code) == v:t_number && l:diagnostic.code != -1 + let l:loclist_item.code = string(l:diagnostic.code) + let l:loclist_item.nr = l:diagnostic.code + endif + endif + + if has_key(l:diagnostic, 'relatedInformation') + let l:related = deepcopy(l:diagnostic.relatedInformation) + call map(l:related, {key, val -> + \ ale#path#FromURI(val.location.uri) . + \ ':' . (val.location.range.start.line + 1) . + \ ':' . (val.location.range.start.character + 1) . + \ ":\n\t" . val.message + \}) + let l:loclist_item.detail = l:diagnostic.message . "\n" . join(l:related, "\n") + endif + + if has_key(l:diagnostic, 'source') + let l:loclist_item.detail = printf( + \ '[%s] %s', + \ l:diagnostic.source, + \ l:diagnostic.message + \) + endif + + call add(l:loclist, l:loclist_item) + endfor + + return l:loclist +endfunction + +function! ale#lsp#response#ReadTSServerDiagnostics(response) abort + let l:loclist = [] + + for l:diagnostic in a:response.body.diagnostics + let l:loclist_item = { + \ 'text': l:diagnostic.text, + \ 'type': 'E', + \ 'lnum': l:diagnostic.start.line, + \ 'col': l:diagnostic.start.offset, + \ 'end_lnum': l:diagnostic.end.line, + \ 'end_col': l:diagnostic.end.offset - 1, + \} + + if has_key(l:diagnostic, 'code') + if type(l:diagnostic.code) == v:t_string + let l:loclist_item.code = l:diagnostic.code + elseif type(l:diagnostic.code) == v:t_number && l:diagnostic.code != -1 + let l:loclist_item.code = string(l:diagnostic.code) + let l:loclist_item.nr = l:diagnostic.code + endif + endif + + if get(l:diagnostic, 'category') is# 'warning' + let l:loclist_item.type = 'W' + endif + + if get(l:diagnostic, 'category') is# 'suggestion' + let l:loclist_item.type = 'I' + endif + + call add(l:loclist, l:loclist_item) + endfor + + return l:loclist +endfunction + +function! ale#lsp#response#GetErrorMessage(response) abort + if type(get(a:response, 'error', 0)) isnot v:t_dict + return '' + endif + + let l:code = get(a:response.error, 'code') + + " Only report things for these error codes. + if l:code isnot s:INVALID_PARAMS && l:code isnot s:INTERNAL_ERROR + return '' + endif + + let l:message = get(a:response.error, 'message', '') + + if empty(l:message) + return '' + endif + + " Include the traceback or error data as details, if present. + let l:error_data = get(a:response.error, 'data', {}) + + if type(l:error_data) is v:t_string + let l:message .= "\n" . l:error_data + elseif type(l:error_data) is v:t_dict + let l:traceback = get(l:error_data, 'traceback', []) + + if type(l:traceback) is v:t_list && !empty(l:traceback) + let l:message .= "\n" . join(l:traceback, "\n") + endif + endif + + return l:message +endfunction diff --git a/pack/acp/start/ale/autoload/ale/lsp/tsserver_message.vim b/pack/acp/start/ale/autoload/ale/lsp/tsserver_message.vim new file mode 100644 index 0000000..d691951 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/lsp/tsserver_message.vim @@ -0,0 +1,79 @@ +" Author: w0rp +" Description: tsserver message implementations +" +" Messages in this movie will be returned in the format +" [is_notification, command_name, params?] +" +" Every command must begin with the string 'ts@', which will be used to +" detect the different message format for tsserver, and this string will +" be removed from the actual command name, + +function! ale#lsp#tsserver_message#Open(buffer) abort + return [1, 'ts@open', {'file': expand('#' . a:buffer . ':p')}] +endfunction + +function! ale#lsp#tsserver_message#Close(buffer) abort + return [1, 'ts@close', {'file': expand('#' . a:buffer . ':p')}] +endfunction + +function! ale#lsp#tsserver_message#Change(buffer) abort + let l:lines = getbufline(a:buffer, 1, '$') + + " We will always use a very high endLine number, so we can delete + " lines from files. tsserver will gladly accept line numbers beyond the + " end. + return [1, 'ts@change', { + \ 'file': expand('#' . a:buffer . ':p'), + \ 'line': 1, + \ 'offset': 1, + \ 'endLine': 1073741824, + \ 'endOffset': 1, + \ 'insertString': join(l:lines, "\n") . "\n", + \}] +endfunction + +function! ale#lsp#tsserver_message#Geterr(buffer) abort + return [1, 'ts@geterr', {'files': [expand('#' . a:buffer . ':p')]}] +endfunction + +function! ale#lsp#tsserver_message#Completions(buffer, line, column, prefix) abort + return [0, 'ts@completions', { + \ 'line': a:line, + \ 'offset': a:column, + \ 'file': expand('#' . a:buffer . ':p'), + \ 'prefix': a:prefix, + \}] +endfunction + +function! ale#lsp#tsserver_message#CompletionEntryDetails(buffer, line, column, entry_names) abort + return [0, 'ts@completionEntryDetails', { + \ 'line': a:line, + \ 'offset': a:column, + \ 'file': expand('#' . a:buffer . ':p'), + \ 'entryNames': a:entry_names, + \}] +endfunction + +function! ale#lsp#tsserver_message#Definition(buffer, line, column) abort + return [0, 'ts@definition', { + \ 'line': a:line, + \ 'offset': a:column, + \ 'file': expand('#' . a:buffer . ':p'), + \}] +endfunction + +function! ale#lsp#tsserver_message#References(buffer, line, column) abort + return [0, 'ts@references', { + \ 'line': a:line, + \ 'offset': a:column, + \ 'file': expand('#' . a:buffer . ':p'), + \}] +endfunction + +function! ale#lsp#tsserver_message#Quickinfo(buffer, line, column) abort + return [0, 'ts@quickinfo', { + \ 'line': a:line, + \ 'offset': a:column, + \ 'file': expand('#' . a:buffer . ':p'), + \}] +endfunction diff --git a/pack/acp/start/ale/autoload/ale/lsp_linter.vim b/pack/acp/start/ale/autoload/ale/lsp_linter.vim new file mode 100644 index 0000000..190a16b --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/lsp_linter.vim @@ -0,0 +1,466 @@ +" Author: w0rp +" Description: Integration between linters and LSP/tsserver. + +" This code isn't loaded if a user never users LSP features or linters. + +" Associates LSP connection IDs with linter names. +if !has_key(s:, 'lsp_linter_map') + let s:lsp_linter_map = {} +endif + +" A Dictionary to track one-shot handlers for custom LSP requests +let s:custom_handlers_map = get(s:, 'custom_handlers_map', {}) + +" Check if diagnostics for a particular linter should be ignored. +function! s:ShouldIgnore(buffer, linter_name) abort + " Ignore all diagnostics if LSP integration is disabled. + if ale#Var(a:buffer, 'disable_lsp') + return 1 + endif + + let l:config = ale#Var(a:buffer, 'linters_ignore') + + " Don't load code for ignoring diagnostics if there's nothing to ignore. + if empty(l:config) + return 0 + endif + + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:ignore_list = ale#engine#ignore#GetList(l:filetype, l:config) + + return index(l:ignore_list, a:linter_name) >= 0 +endfunction + +function! s:HandleLSPDiagnostics(conn_id, response) abort + let l:linter_name = s:lsp_linter_map[a:conn_id] + let l:filename = ale#path#FromURI(a:response.params.uri) + let l:buffer = bufnr('^' . l:filename . '$') + let l:info = get(g:ale_buffer_info, l:buffer, {}) + + if empty(l:info) + return + endif + + if s:ShouldIgnore(l:buffer, l:linter_name) + return + endif + + let l:loclist = ale#lsp#response#ReadDiagnostics(a:response) + + call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0) +endfunction + +function! s:HandleTSServerDiagnostics(response, error_type) abort + let l:linter_name = 'tsserver' + let l:buffer = bufnr('^' . a:response.body.file . '$') + let l:info = get(g:ale_buffer_info, l:buffer, {}) + + if empty(l:info) + return + endif + + call ale#engine#MarkLinterInactive(l:info, l:linter_name) + + if s:ShouldIgnore(l:buffer, l:linter_name) + return + endif + + let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response) + let l:no_changes = 0 + + " tsserver sends syntax and semantic errors in separate messages, so we + " have to collect the messages separately for each buffer and join them + " back together again. + if a:error_type is# 'syntax' + if len(l:thislist) is 0 && len(get(l:info, 'syntax_loclist', [])) is 0 + let l:no_changes = 1 + endif + + let l:info.syntax_loclist = l:thislist + else + if len(l:thislist) is 0 && len(get(l:info, 'semantic_loclist', [])) is 0 + let l:no_changes = 1 + endif + + let l:info.semantic_loclist = l:thislist + endif + + if l:no_changes + return + endif + + let l:loclist = get(l:info, 'semantic_loclist', []) + \ + get(l:info, 'syntax_loclist', []) + + call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0) +endfunction + +function! s:HandleLSPErrorMessage(linter_name, response) abort + if !g:ale_history_enabled || !g:ale_history_log_output + return + endif + + if empty(a:linter_name) + return + endif + + let l:message = ale#lsp#response#GetErrorMessage(a:response) + + if empty(l:message) + return + endif + + " This global variable is set here so we don't load the debugging.vim file + " until someone uses :ALEInfo. + let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {}) + + if !has_key(g:ale_lsp_error_messages, a:linter_name) + let g:ale_lsp_error_messages[a:linter_name] = [] + endif + + call add(g:ale_lsp_error_messages[a:linter_name], l:message) +endfunction + +function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort + let l:method = get(a:response, 'method', '') + + if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error') + let l:linter_name = get(s:lsp_linter_map, a:conn_id, '') + + call s:HandleLSPErrorMessage(l:linter_name, a:response) + elseif l:method is# 'textDocument/publishDiagnostics' + call s:HandleLSPDiagnostics(a:conn_id, a:response) + elseif get(a:response, 'type', '') is# 'event' + \&& get(a:response, 'event', '') is# 'semanticDiag' + call s:HandleTSServerDiagnostics(a:response, 'semantic') + elseif get(a:response, 'type', '') is# 'event' + \&& get(a:response, 'event', '') is# 'syntaxDiag' + call s:HandleTSServerDiagnostics(a:response, 'syntax') + endif +endfunction + +function! ale#lsp_linter#GetOptions(buffer, linter) abort + if has_key(a:linter, 'initialization_options_callback') + return ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer) + endif + + if has_key(a:linter, 'initialization_options') + let l:Options = a:linter.initialization_options + + if type(l:Options) is v:t_func + let l:Options = l:Options(a:buffer) + endif + + return l:Options + endif + + return {} +endfunction + +function! ale#lsp_linter#GetConfig(buffer, linter) abort + if has_key(a:linter, 'lsp_config_callback') + return ale#util#GetFunction(a:linter.lsp_config_callback)(a:buffer) + endif + + if has_key(a:linter, 'lsp_config') + let l:Config = a:linter.lsp_config + + if type(l:Config) is v:t_func + let l:Config = l:Config(a:buffer) + endif + + return l:Config + endif + + return {} +endfunction + +function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort + let l:buffer_ale_root = getbufvar(a:buffer, 'ale_lsp_root', {}) + + if type(l:buffer_ale_root) is v:t_string + return l:buffer_ale_root + endif + + " Try to get a buffer-local setting for the root + if has_key(l:buffer_ale_root, a:linter.name) + let l:Root = l:buffer_ale_root[a:linter.name] + + if type(l:Root) is v:t_func + return l:Root(a:buffer) + else + return l:Root + endif + endif + + " Try to get a global setting for the root + if has_key(g:ale_lsp_root, a:linter.name) + let l:Root = g:ale_lsp_root[a:linter.name] + + if type(l:Root) is v:t_func + return l:Root(a:buffer) + else + return l:Root + endif + endif + + " Fall back to the linter-specific configuration + if has_key(a:linter, 'project_root') + let l:Root = a:linter.project_root + + return type(l:Root) is v:t_func ? l:Root(a:buffer) : l:Root + endif + + return ale#util#GetFunction(a:linter.project_root_callback)(a:buffer) +endfunction + +" This function is accessible so tests can call it. +function! ale#lsp_linter#OnInit(linter, details, Callback) abort + let l:buffer = a:details.buffer + let l:conn_id = a:details.connection_id + let l:command = a:details.command + + let l:config = ale#lsp_linter#GetConfig(l:buffer, a:linter) + let l:language_id = ale#util#GetFunction(a:linter.language_callback)(l:buffer) + + call ale#lsp#UpdateConfig(l:conn_id, l:buffer, l:config) + + if ale#lsp#OpenDocument(l:conn_id, l:buffer, l:language_id) + if g:ale_history_enabled && !empty(l:command) + call ale#history#Add(l:buffer, 'started', l:conn_id, l:command) + endif + endif + + " The change message needs to be sent for tsserver before doing anything. + if a:linter.lsp is# 'tsserver' + call ale#lsp#NotifyForChanges(l:conn_id, l:buffer) + endif + + call a:Callback(a:linter, a:details) +endfunction + +function! s:StartLSP(options, address, executable, command) abort + let l:buffer = a:options.buffer + let l:linter = a:options.linter + let l:root = a:options.root + let l:Callback = a:options.callback + + let l:init_options = ale#lsp_linter#GetOptions(l:buffer, l:linter) + + if l:linter.lsp is# 'socket' + let l:conn_id = ale#lsp#Register(a:address, l:root, l:init_options) + let l:ready = ale#lsp#ConnectToAddress(l:conn_id, a:address) + let l:command = '' + else + let l:conn_id = ale#lsp#Register(a:executable, l:root, l:init_options) + + " tsserver behaves differently, so tell the LSP API that it is tsserver. + if l:linter.lsp is# 'tsserver' + call ale#lsp#MarkConnectionAsTsserver(l:conn_id) + endif + + let l:command = ale#command#FormatCommand(l:buffer, a:executable, a:command, 0, v:false)[1] + let l:command = ale#job#PrepareCommand(l:buffer, l:command) + let l:ready = ale#lsp#StartProgram(l:conn_id, a:executable, l:command) + endif + + if !l:ready + if g:ale_history_enabled && !empty(a:command) + call ale#history#Add(l:buffer, 'failed', l:conn_id, a:command) + endif + + return 0 + endif + + let l:details = { + \ 'buffer': l:buffer, + \ 'connection_id': l:conn_id, + \ 'command': l:command, + \ 'project_root': l:root, + \} + + call ale#lsp#OnInit(l:conn_id, {-> + \ ale#lsp_linter#OnInit(l:linter, l:details, l:Callback) + \}) + + return 1 +endfunction + +function! s:StartWithAddress(options, address) abort + if ale#command#IsDeferred(a:address) + let a:address.result_callback = { + \ address -> s:StartWithAddress(a:options, address) + \} + + return 1 + endif + + if empty(a:address) + return 0 + endif + + return s:StartLSP(a:options, a:address, '', '') +endfunction + +function! s:StartWithCommand(options, executable, command) abort + if ale#command#IsDeferred(a:command) + let a:command.result_callback = { + \ command -> s:StartWithCommand(a:options, a:executable, command) + \} + + return 1 + endif + + if empty(a:command) + return 0 + endif + + return s:StartLSP(a:options, '', a:executable, a:command) +endfunction + +function! s:StartIfExecutable(options, executable) abort + if ale#command#IsDeferred(a:executable) + let a:executable.result_callback = { + \ executable -> s:StartIfExecutable(a:options, executable) + \} + + return 1 + endif + + if !ale#engine#IsExecutable(a:options.buffer, a:executable) + return 0 + endif + + let l:command = ale#linter#GetCommand(a:options.buffer, a:options.linter) + + return s:StartWithCommand(a:options, a:executable, l:command) +endfunction + +" Given a buffer, an LSP linter, start up an LSP linter and get ready to +" receive messages for the document. +function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort + let l:command = '' + let l:address = '' + let l:root = ale#lsp_linter#FindProjectRoot(a:buffer, a:linter) + + if empty(l:root) && a:linter.lsp isnot# 'tsserver' + " If there's no project root, then we can't check files with LSP, + " unless we are using tsserver, which doesn't use project roots. + return 0 + endif + + let l:options = { + \ 'buffer': a:buffer, + \ 'linter': a:linter, + \ 'callback': a:Callback, + \ 'root': l:root, + \} + + if a:linter.lsp is# 'socket' + let l:address = ale#linter#GetAddress(a:buffer, a:linter) + + return s:StartWithAddress(l:options, l:address) + endif + + let l:executable = ale#linter#GetExecutable(a:buffer, a:linter) + + return s:StartIfExecutable(l:options, l:executable) +endfunction + +function! s:CheckWithLSP(linter, details) abort + let l:buffer = a:details.buffer + let l:info = get(g:ale_buffer_info, l:buffer) + + if empty(l:info) + return + endif + + let l:id = a:details.connection_id + + " Register a callback now for handling errors now. + let l:Callback = function('ale#lsp_linter#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + " Remember the linter this connection is for. + let s:lsp_linter_map[l:id] = a:linter.name + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#Geterr(l:buffer) + let l:notified = ale#lsp#Send(l:id, l:message) != 0 + + if l:notified + call ale#engine#MarkLinterActive(l:info, a:linter) + endif + else + let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer) + endif + + " If this was a file save event, also notify the server of that. + if a:linter.lsp isnot# 'tsserver' + \&& getbufvar(l:buffer, 'ale_save_event_fired', 0) + let l:save_message = ale#lsp#message#DidSave(l:buffer) + let l:notified = ale#lsp#Send(l:id, l:save_message) != 0 + endif +endfunction + +function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort + return ale#lsp_linter#StartLSP(a:buffer, a:linter, function('s:CheckWithLSP')) +endfunction + +" Clear LSP linter data for the linting engine. +function! ale#lsp_linter#ClearLSPData() abort + let s:lsp_linter_map = {} + let s:custom_handlers_map = {} +endfunction + +" Just for tests. +function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort + let s:lsp_linter_map = a:replacement_map +endfunction + +function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort + if has_key(a:response, 'id') + \&& has_key(s:custom_handlers_map, a:response.id) + let l:Handler = remove(s:custom_handlers_map, a:response.id) + call l:Handler(a:response) + endif +endfunction + +function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort + let l:id = a:lsp_details.connection_id + let l:request_id = ale#lsp#Send(l:id, a:args.message) + + if l:request_id > 0 && has_key(a:args, 'handler') + let l:Callback = function('s:HandleLSPResponseToCustomRequests') + call ale#lsp#RegisterCallback(l:id, l:Callback) + let s:custom_handlers_map[l:request_id] = a:args.handler + endif +endfunction + +" Send a custom request to an LSP linter. +function! ale#lsp_linter#SendRequest(buffer, linter_name, message, ...) abort + let l:filetype = ale#linter#ResolveFiletype(getbufvar(a:buffer, '&filetype')) + let l:linter_list = ale#linter#GetAll(l:filetype) + let l:linter_list = filter(l:linter_list, {_, v -> v.name is# a:linter_name}) + + if len(l:linter_list) < 1 + throw 'Linter "' . a:linter_name . '" not found!' + endif + + let l:linter = l:linter_list[0] + + if empty(l:linter.lsp) + throw 'Linter "' . a:linter_name . '" does not support LSP!' + endif + + let l:is_notification = a:message[0] + let l:callback_args = {'message': a:message} + + if !l:is_notification && a:0 + let l:callback_args.handler = a:1 + endif + + let l:Callback = function('s:OnReadyForCustomRequests', [l:callback_args]) + + return ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/node.vim b/pack/acp/start/ale/autoload/ale/node.vim new file mode 100644 index 0000000..6906012 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/node.vim @@ -0,0 +1,42 @@ +" Author: w0rp +" Description: Functions for working with Node executables. + +call ale#Set('windows_node_executable_path', 'node.exe') + +" Given a buffer number, a base variable name, and a list of paths to search +" for in ancestor directories, detect the executable path for a Node program. +" +" The use_global and executable options for the relevant program will be used. +function! ale#node#FindExecutable(buffer, base_var_name, path_list) abort + if ale#Var(a:buffer, a:base_var_name . '_use_global') + return ale#Var(a:buffer, a:base_var_name . '_executable') + endif + + for l:path in a:path_list + let l:executable = ale#path#FindNearestFile(a:buffer, l:path) + + if !empty(l:executable) + return l:executable + endif + endfor + + return ale#Var(a:buffer, a:base_var_name . '_executable') +endfunction + +" Create a executable string which executes a Node.js script command with a +" Node.js executable if needed. +" +" The executable string should not be escaped before passing it to this +" function, the executable string will be escaped when returned by this +" function. +" +" The executable is only prefixed for Windows machines +function! ale#node#Executable(buffer, executable) abort + if has('win32') && a:executable =~? '\.js$' + let l:node = ale#Var(a:buffer, 'windows_node_executable_path') + + return ale#Escape(l:node) . ' ' . ale#Escape(a:executable) + endif + + return ale#Escape(a:executable) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/other_source.vim b/pack/acp/start/ale/autoload/ale/other_source.vim new file mode 100644 index 0000000..1a09203 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/other_source.vim @@ -0,0 +1,21 @@ +" Tell ALE that another source has started checking a buffer. +function! ale#other_source#StartChecking(buffer, linter_name) abort + call ale#engine#InitBufferInfo(a:buffer) + let l:list = g:ale_buffer_info[a:buffer].active_other_sources_list + + call add(l:list, a:linter_name) + call uniq(sort(l:list)) +endfunction + +" Show some results, and stop checking a buffer. +" To clear results or cancel checking a buffer, an empty List can be given. +function! ale#other_source#ShowResults(buffer, linter_name, loclist) abort + call ale#engine#InitBufferInfo(a:buffer) + let l:info = g:ale_buffer_info[a:buffer] + + " Remove this linter name from the active list. + let l:list = l:info.active_other_sources_list + call filter(l:list, 'v:val isnot# a:linter_name') + + call ale#engine#HandleLoclist(a:linter_name, a:buffer, a:loclist, 1) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/path.vim b/pack/acp/start/ale/autoload/ale/path.vim new file mode 100644 index 0000000..84c26d0 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/path.vim @@ -0,0 +1,224 @@ +" Author: w0rp +" Description: Functions for working with paths in the filesystem. + +" simplify a path, and fix annoying issues with paths on Windows. +" +" Forward slashes are changed to back slashes so path equality works better +" on Windows. Back slashes are changed to forward slashes on Unix. +" +" Unix paths can technically contain back slashes, but in practice no path +" should, and replacing back slashes with forward slashes makes linters work +" in environments like MSYS. +" +" Paths starting with more than one forward slash are changed to only one +" forward slash, to prevent the paths being treated as special MSYS paths. +function! ale#path#Simplify(path) abort + if has('unix') + let l:unix_path = substitute(a:path, '\\', '/', 'g') + + return substitute(simplify(l:unix_path), '^//\+', '/', 'g') " no-custom-checks + endif + + let l:win_path = substitute(a:path, '/', '\\', 'g') + + return substitute(simplify(l:win_path), '^\\\+', '\', 'g') " no-custom-checks +endfunction + +" Given a buffer and a filename, find the nearest file by searching upwards +" through the paths relative to the given buffer. +function! ale#path#FindNearestFile(buffer, filename) abort + let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p') + let l:buffer_filename = fnameescape(l:buffer_filename) + + let l:relative_path = findfile(a:filename, l:buffer_filename . ';') + + if !empty(l:relative_path) + return fnamemodify(l:relative_path, ':p') + endif + + return '' +endfunction + +" Given a buffer and a directory name, find the nearest directory by searching upwards +" through the paths relative to the given buffer. +function! ale#path#FindNearestDirectory(buffer, directory_name) abort + let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p') + let l:buffer_filename = fnameescape(l:buffer_filename) + + let l:relative_path = finddir(a:directory_name, l:buffer_filename . ';') + + if !empty(l:relative_path) + return fnamemodify(l:relative_path, ':p') + endif + + return '' +endfunction + +" Given a buffer, a string to search for, an a global fallback for when +" the search fails, look for a file in parent paths, and if that fails, +" use the global fallback path instead. +function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abort + " Search for a locally installed file first. + let l:path = ale#path#FindNearestFile(a:buffer, a:search_string) + + " If the serach fails, try the global executable instead. + if empty(l:path) + let l:path = a:global_fallback + endif + + return l:path +endfunction + +" Output 'cd && ' +" This function can be used changing the directory for a linter command. +function! ale#path#CdString(directory) abort + if has('win32') + return 'cd /d ' . ale#Escape(a:directory) . ' && ' + else + return 'cd ' . ale#Escape(a:directory) . ' && ' + endif +endfunction + +" Output 'cd && ' +" This function can be used changing the directory for a linter command. +function! ale#path#BufferCdString(buffer) abort + return ale#path#CdString(fnamemodify(bufname(a:buffer), ':p:h')) +endfunction + +" Return 1 if a path is an absolute path. +function! ale#path#IsAbsolute(filename) abort + if has('win32') && a:filename[:0] is# '\' + return 1 + endif + + " Check for /foo and C:\foo, etc. + return a:filename[:0] is# '/' || a:filename[1:2] is# ':\' +endfunction + +let s:temp_dir = ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h')) + +" Given a filename, return 1 if the file represents some temporary file +" created by Vim. +function! ale#path#IsTempName(filename) abort + return ale#path#Simplify(a:filename)[:len(s:temp_dir) - 1] is# s:temp_dir +endfunction + +" Given a base directory, which must not have a trailing slash, and a +" filename, which may have an absolute path a path relative to the base +" directory, return the absolute path to the file. +function! ale#path#GetAbsPath(base_directory, filename) abort + if ale#path#IsAbsolute(a:filename) + return ale#path#Simplify(a:filename) + endif + + let l:sep = has('win32') ? '\' : '/' + + return ale#path#Simplify(a:base_directory . l:sep . a:filename) +endfunction + +" Given a path, return the directory name for that path, with no trailing +" slashes. If the argument is empty(), return an empty string. +function! ale#path#Dirname(path) abort + if empty(a:path) + return '' + endif + + " For /foo/bar/ we need :h:h to get /foo + if a:path[-1:] is# '/' + return fnamemodify(a:path, ':h:h') + endif + + return fnamemodify(a:path, ':h') +endfunction + +" Given a buffer number and a relative or absolute path, return 1 if the +" two paths represent the same file on disk. +function! ale#path#IsBufferPath(buffer, complex_filename) abort + " If the path is one of many different names for stdin, we have a match. + if a:complex_filename is# '-' + \|| a:complex_filename is# 'stdin' + \|| a:complex_filename[:0] is# '<' + return 1 + endif + + let l:test_filename = ale#path#Simplify(a:complex_filename) + + if l:test_filename[:1] is# './' + let l:test_filename = l:test_filename[2:] + endif + + if l:test_filename[:1] is# '..' + " Remove ../../ etc. from the front of the path. + let l:test_filename = substitute(l:test_filename, '\v^(\.\.[/\\])+', '/', '') + endif + + " Use the basename for temporary files, as they are likely our files. + if ale#path#IsTempName(l:test_filename) + let l:test_filename = fnamemodify(l:test_filename, ':t') + endif + + let l:buffer_filename = expand('#' . a:buffer . ':p') + + return l:buffer_filename is# l:test_filename + \ || l:buffer_filename[-len(l:test_filename):] is# l:test_filename +endfunction + +" Given a path, return every component of the path, moving upwards. +function! ale#path#Upwards(path) abort + let l:pattern = has('win32') ? '\v/+|\\+' : '\v/+' + let l:sep = has('win32') ? '\' : '/' + let l:parts = split(ale#path#Simplify(a:path), l:pattern) + let l:path_list = [] + + while !empty(l:parts) + call add(l:path_list, join(l:parts, l:sep)) + let l:parts = l:parts[:-2] + endwhile + + if has('win32') && a:path =~# '^[a-zA-z]:\' + " Add \ to C: for C:\, etc. + let l:path_list[-1] .= '\' + elseif a:path[0] is# '/' + " If the path starts with /, even on Windows, add / and / to all paths. + call map(l:path_list, '''/'' . v:val') + call add(l:path_list, '/') + endif + + return l:path_list +endfunction + +" Convert a filesystem path to a file:// URI +" relatives paths will not be prefixed with the protocol. +" For Windows paths, the `:` in C:\ etc. will not be percent-encoded. +function! ale#path#ToURI(path) abort + let l:has_drive_letter = a:path[1:2] is# ':\' + + return substitute( + \ ((l:has_drive_letter || a:path[:0] is# '/') ? 'file://' : '') + \ . (l:has_drive_letter ? '/' . a:path[:2] : '') + \ . ale#uri#Encode(l:has_drive_letter ? a:path[3:] : a:path), + \ '\\', + \ '/', + \ 'g', + \) +endfunction + +function! ale#path#FromURI(uri) abort + if a:uri[:6] is? 'file://' + let l:encoded_path = a:uri[7:] + elseif a:uri[:4] is? 'file:' + let l:encoded_path = a:uri[5:] + else + let l:encoded_path = a:uri + endif + + let l:path = ale#uri#Decode(l:encoded_path) + + " If the path is like /C:/foo/bar, it should be C:\foo\bar instead. + if has('win32') && l:path =~# '^/[a-zA-Z][:|]' + let l:path = substitute(l:path[1:], '/', '\\', 'g') + let l:path = l:path[0] . ':' . l:path[2:] + endif + + return l:path +endfunction diff --git a/pack/acp/start/ale/autoload/ale/pattern_options.vim b/pack/acp/start/ale/autoload/ale/pattern_options.vim new file mode 100644 index 0000000..14e2142 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/pattern_options.vim @@ -0,0 +1,47 @@ +" Author: w0rp +" Description: Set options in files based on regex patterns. + +" These variables are used to cache the sorting of patterns below. +let s:last_pattern_options = {} +let s:sorted_items = [] + +function! s:CmpPatterns(left_item, right_item) abort + if a:left_item[0] < a:right_item[0] + return -1 + endif + + if a:left_item[0] > a:right_item[0] + return 1 + endif + + return 0 +endfunction + +function! ale#pattern_options#SetOptions(buffer) abort + let l:pattern_options = get(g:, 'ale_pattern_options', {}) + + if empty(l:pattern_options) + " Stop if no options are set. + return + endif + + " The items will only be sorted whenever the patterns change. + if l:pattern_options != s:last_pattern_options + let s:last_pattern_options = deepcopy(l:pattern_options) + " The patterns are sorted, so they are applied consistently. + let s:sorted_items = sort( + \ items(l:pattern_options), + \ function('s:CmpPatterns') + \) + endif + + let l:filename = expand('#' . a:buffer . ':p') + + for [l:pattern, l:options] in s:sorted_items + if match(l:filename, l:pattern) >= 0 + for [l:key, l:value] in items(l:options) + call setbufvar(a:buffer, l:key, l:value) + endfor + endif + endfor +endfunction diff --git a/pack/acp/start/ale/autoload/ale/powershell.vim b/pack/acp/start/ale/autoload/ale/powershell.vim new file mode 100644 index 0000000..8c16320 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/powershell.vim @@ -0,0 +1,32 @@ +" Author: zigford +" Description: Functions for integrating with Powershell linters. + +" Write a powershell script to a temp file for execution +" return the command used to execute it +function! s:TemporaryPSScript(buffer, input) abort + let l:filename = 'script.ps1' + " Create a temp dir to house our temp .ps1 script + " a temp dir is needed as powershell needs the .ps1 + " extension + let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/') + let l:tempscript = l:tempdir . l:filename + " Create the temporary directory for the file, unreadable by 'other' + " users. + call mkdir(l:tempdir, '', 0750) + " Automatically delete the directory later. + call ale#command#ManageDirectory(a:buffer, l:tempdir) + " Write the script input out to a file. + call ale#util#Writefile(a:buffer, a:input, l:tempscript) + + return l:tempscript +endfunction + +function! ale#powershell#RunPowerShell(buffer, base_var_name, command) abort + let l:executable = ale#Var(a:buffer, a:base_var_name . '_executable') + let l:tempscript = s:TemporaryPSScript(a:buffer, a:command) + + return ale#Escape(l:executable) + \ . ' -Exe Bypass -NoProfile -File ' + \ . ale#Escape(l:tempscript) + \ . ' %t' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/preview.vim b/pack/acp/start/ale/autoload/ale/preview.vim new file mode 100644 index 0000000..6d58aca --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/preview.vim @@ -0,0 +1,98 @@ +" Author: w0rp +" Description: Preview windows for showing whatever information in. + +" Open a preview window and show some lines in it. +" A second argument can be passed as a Dictionary with options. They are... +" +" filetype - The filetype to use, defaulting to 'ale-preview' +" stay_here - If 1, stay in the window you came from. +function! ale#preview#Show(lines, ...) abort + let l:options = get(a:000, 0, {}) + + silent pedit ALEPreviewWindow + wincmd P + + setlocal modifiable + setlocal noreadonly + setlocal nobuflisted + setlocal buftype=nofile + setlocal bufhidden=wipe + :%d + call setline(1, a:lines) + setlocal nomodifiable + setlocal readonly + let &l:filetype = get(l:options, 'filetype', 'ale-preview') + + if get(l:options, 'stay_here') + wincmd p + endif +endfunction + +" Close the preview window if the filetype matches the given one. +function! ale#preview#CloseIfTypeMatches(filetype) abort + for l:win in getwininfo() + let l:wintype = gettabwinvar(l:win.tabnr, l:win.winnr, '&filetype') + + if l:wintype is# a:filetype + silent! pclose! + endif + endfor +endfunction + +" Show a location selection preview window, given some items. +" Each item should have 'filename', 'line', and 'column' keys. +function! ale#preview#ShowSelection(item_list, ...) abort + let l:options = get(a:000, 0, {}) + let l:sep = has('win32') ? '\' : '/' + let l:lines = [] + + " Create lines to display to users. + for l:item in a:item_list + let l:match = get(l:item, 'match', '') + let l:filename = l:item.filename + + if get(l:options, 'use_relative_paths') + let l:cwd = getcwd() " no-custom-checks + let l:filename = substitute(l:filename, '^' . l:cwd . l:sep, '', '') + endif + + call add( + \ l:lines, + \ l:filename + \ . ':' . l:item.line + \ . ':' . l:item.column + \ . (!empty(l:match) ? ' ' . l:match : ''), + \) + endfor + + call ale#preview#Show(l:lines, {'filetype': 'ale-preview-selection'}) + let b:ale_preview_item_list = a:item_list +endfunction + +function! s:Open(open_in_tab) abort + let l:item_list = get(b:, 'ale_preview_item_list', []) + let l:item = get(l:item_list, getpos('.')[1] - 1, {}) + + if empty(l:item) + return + endif + + if !a:open_in_tab + :q! + endif + + call ale#util#Open( + \ l:item.filename, + \ l:item.line, + \ l:item.column, + \ {'open_in_tab': a:open_in_tab}, + \) +endfunction + +function! ale#preview#OpenSelectionInBuffer() abort + call s:Open(0) +endfunction + +function! ale#preview#OpenSelectionInTab() abort + call s:Open(1) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/python.vim b/pack/acp/start/ale/autoload/ale/python.vim new file mode 100644 index 0000000..7ed2236 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/python.vim @@ -0,0 +1,157 @@ +" Author: w0rp +" Description: Functions for integrating with Python linters. + +call ale#Set('python_auto_pipenv', '0') + +let s:sep = has('win32') ? '\' : '/' +" bin is used for Unix virtualenv directories, and Scripts is for Windows. +let s:bin_dir = has('unix') ? 'bin' : 'Scripts' +let g:ale_virtualenv_dir_names = get(g:, 'ale_virtualenv_dir_names', [ +\ '.env', +\ '.venv', +\ 'env', +\ 've-py3', +\ 've', +\ 'virtualenv', +\ 'venv', +\]) + +function! ale#python#FindProjectRootIni(buffer) abort + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + " If you change this, update ale-python-root documentation. + if filereadable(l:path . '/MANIFEST.in') + \|| filereadable(l:path . '/setup.cfg') + \|| filereadable(l:path . '/pytest.ini') + \|| filereadable(l:path . '/tox.ini') + \|| filereadable(l:path . '/mypy.ini') + \|| filereadable(l:path . '/pycodestyle.cfg') + \|| filereadable(l:path . '/.flake8') + \|| filereadable(l:path . '/.flake8rc') + \|| filereadable(l:path . '/pylama.ini') + \|| filereadable(l:path . '/pylintrc') + \|| filereadable(l:path . '/.pylintrc') + \|| filereadable(l:path . '/Pipfile') + \|| filereadable(l:path . '/Pipfile.lock') + return l:path + endif + endfor + + return '' +endfunction + +" Given a buffer number, find the project root directory for Python. +" The root directory is defined as the first directory found while searching +" upwards through paths, including the current directory, until a path +" containing an init file (one from MANIFEST.in, setup.cfg, pytest.ini, +" tox.ini) is found. If it is not possible to find the project root directory +" via init file, then it will be defined as the first directory found +" searching upwards through paths, including the current directory, until no +" __init__.py files is found. +function! ale#python#FindProjectRoot(buffer) abort + let l:ini_root = ale#python#FindProjectRootIni(a:buffer) + + if !empty(l:ini_root) + return l:ini_root + endif + + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + if !filereadable(l:path . '/__init__.py') + return l:path + endif + endfor + + return '' +endfunction + +" Given a buffer number, find a virtualenv path for Python. +function! ale#python#FindVirtualenv(buffer) abort + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + " Skip empty path components returned in MSYS. + if empty(l:path) + continue + endif + + for l:dirname in ale#Var(a:buffer, 'virtualenv_dir_names') + let l:venv_dir = ale#path#Simplify( + \ join([l:path, l:dirname], s:sep) + \) + let l:script_filename = ale#path#Simplify( + \ join([l:venv_dir, s:bin_dir, 'activate'], s:sep) + \) + + if filereadable(l:script_filename) + return l:venv_dir + endif + endfor + endfor + + return $VIRTUAL_ENV +endfunction + +" Given a buffer number and a command name, find the path to the executable. +" First search on a virtualenv for Python, if nothing is found, try the global +" command. Returns an empty string if cannot find the executable +function! ale#python#FindExecutable(buffer, base_var_name, path_list) abort + if ale#Var(a:buffer, a:base_var_name . '_use_global') + return ale#Var(a:buffer, a:base_var_name . '_executable') + endif + + let l:virtualenv = ale#python#FindVirtualenv(a:buffer) + + if !empty(l:virtualenv) + for l:path in a:path_list + let l:ve_executable = ale#path#Simplify( + \ join([l:virtualenv, s:bin_dir, l:path], s:sep) + \) + + if executable(l:ve_executable) + return l:ve_executable + endif + endfor + endif + + return ale#Var(a:buffer, a:base_var_name . '_executable') +endfunction + +" Handle traceback.print_exception() output starting in the first a:limit lines. +function! ale#python#HandleTraceback(lines, limit) abort + let l:nlines = len(a:lines) + let l:limit = a:limit > l:nlines ? l:nlines : a:limit + let l:start = 0 + + while l:start < l:limit + if a:lines[l:start] is# 'Traceback (most recent call last):' + break + endif + + let l:start += 1 + endwhile + + if l:start >= l:limit + return [] + endif + + let l:end = l:start + 1 + + " Traceback entries are always prefixed with 2 spaces. + " SyntaxError marker (if present) is prefixed with at least 4 spaces. + " Final exc line starts with exception class name (never a space). + while l:end < l:nlines && a:lines[l:end][0] is# ' ' + let l:end += 1 + endwhile + + let l:exc_line = l:end < l:nlines + \ ? a:lines[l:end] + \ : 'An exception was thrown.' + + return [{ + \ 'lnum': 1, + \ 'text': l:exc_line . ' (See :ALEDetail)', + \ 'detail': join(a:lines[(l:start):(l:end)], "\n"), + \}] +endfunction + +" Detects whether a pipenv environment is present. +function! ale#python#PipenvPresent(buffer) abort + return findfile('Pipfile.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/references.vim b/pack/acp/start/ale/autoload/ale/references.vim new file mode 100644 index 0000000..b9725e1 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/references.vim @@ -0,0 +1,127 @@ +let s:references_map = {} + +" Used to get the references map in tests. +function! ale#references#GetMap() abort + return deepcopy(s:references_map) +endfunction + +" Used to set the references map in tests. +function! ale#references#SetMap(map) abort + let s:references_map = a:map +endfunction + +function! ale#references#ClearLSPData() abort + let s:references_map = {} +endfunction + +function! ale#references#HandleTSServerResponse(conn_id, response) abort + if get(a:response, 'command', '') is# 'references' + \&& has_key(s:references_map, a:response.request_seq) + let l:options = remove(s:references_map, a:response.request_seq) + + if get(a:response, 'success', v:false) is v:true + let l:item_list = [] + + for l:response_item in a:response.body.refs + call add(l:item_list, { + \ 'filename': l:response_item.file, + \ 'line': l:response_item.start.line, + \ 'column': l:response_item.start.offset, + \ 'match': substitute(l:response_item.lineText, '^\s*\(.\{-}\)\s*$', '\1', ''), + \}) + endfor + + if empty(l:item_list) + call ale#util#Execute('echom ''No references found.''') + else + call ale#preview#ShowSelection(l:item_list, l:options) + endif + endif + endif +endfunction + +function! ale#references#HandleLSPResponse(conn_id, response) abort + if has_key(a:response, 'id') + \&& has_key(s:references_map, a:response.id) + let l:options = remove(s:references_map, a:response.id) + + " The result can be a Dictionary item, a List of the same, or null. + let l:result = get(a:response, 'result', []) + let l:item_list = [] + + if type(l:result) is v:t_list + for l:response_item in l:result + call add(l:item_list, { + \ 'filename': ale#path#FromURI(l:response_item.uri), + \ 'line': l:response_item.range.start.line + 1, + \ 'column': l:response_item.range.start.character + 1, + \}) + endfor + endif + + if empty(l:item_list) + call ale#util#Execute('echom ''No references found.''') + else + call ale#preview#ShowSelection(l:item_list, l:options) + endif + endif +endfunction + +function! s:OnReady(line, column, options, linter, lsp_details) abort + let l:id = a:lsp_details.connection_id + + if !ale#lsp#HasCapability(l:id, 'references') + return + endif + + let l:buffer = a:lsp_details.buffer + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#references#HandleTSServerResponse') + \ : function('ale#references#HandleLSPResponse') + + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#References( + \ l:buffer, + \ a:line, + \ a:column + \) + else + " Send a message saying the buffer has changed first, or the + " references position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:buffer) + + let l:message = ale#lsp#message#References(l:buffer, a:line, a:column) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message) + + let s:references_map[l:request_id] = { + \ 'use_relative_paths': has_key(a:options, 'use_relative_paths') ? a:options.use_relative_paths : 0 + \} +endfunction + +function! ale#references#Find(...) abort + let l:options = {} + + if len(a:000) > 0 + for l:option in a:000 + if l:option is? '-relative' + let l:options.use_relative_paths = 1 + endif + endfor + endif + + let l:buffer = bufnr('') + let [l:line, l:column] = getpos('.')[1:2] + let l:column = min([l:column, len(getline(l:line))]) + let l:Callback = function('s:OnReady', [l:line, l:column, l:options]) + + for l:linter in ale#linter#Get(&filetype) + if !empty(l:linter.lsp) + call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) + endif + endfor +endfunction diff --git a/pack/acp/start/ale/autoload/ale/ruby.vim b/pack/acp/start/ale/autoload/ale/ruby.vim new file mode 100644 index 0000000..15e835c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/ruby.vim @@ -0,0 +1,76 @@ +" Author: Eddie Lebow https://github.com/elebow +" Description: Functions for integrating with Ruby tools + +" Find the nearest dir containing "app", "db", and "config", and assume it is +" the root of a Rails app. +function! ale#ruby#FindRailsRoot(buffer) abort + for l:name in ['app', 'config', 'db'] + let l:dir = fnamemodify( + \ ale#path#FindNearestDirectory(a:buffer, l:name), + \ ':h:h' + \) + + if l:dir isnot# '.' + \&& isdirectory(l:dir . '/app') + \&& isdirectory(l:dir . '/config') + \&& isdirectory(l:dir . '/db') + return l:dir + endif + endfor + + return '' +endfunction + +" Find the nearest dir containing a potential ruby project. +function! ale#ruby#FindProjectRoot(buffer) abort + let l:dir = ale#ruby#FindRailsRoot(a:buffer) + + if isdirectory(l:dir) + return l:dir + endif + + for l:name in ['.solargraph.yml', 'Rakefile', 'Gemfile'] + let l:dir = fnamemodify( + \ ale#path#FindNearestFile(a:buffer, l:name), + \ ':h' + \) + + if l:dir isnot# '.' && isdirectory(l:dir) + return l:dir + endif + endfor + + return '' +endfunction + +" Handle output from rubocop and linters that depend on it (e.b. standardrb) +function! ale#ruby#HandleRubocopOutput(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, + \ 'code': l:error['cop_name'], + \ 'text': l:error['message'], + \ 'type': ale_linters#ruby#rubocop#GetType(l:error['severity']), + \}) + endfor + + return l:output +endfunction + diff --git a/pack/acp/start/ale/autoload/ale/semver.vim b/pack/acp/start/ale/autoload/ale/semver.vim new file mode 100644 index 0000000..e3eb49c --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/semver.vim @@ -0,0 +1,78 @@ +let s:version_cache = {} + +" Reset the version cache used for parsing the version. +function! ale#semver#ResetVersionCache() abort + let s:version_cache = {} +endfunction + +function! ale#semver#ParseVersion(version_lines) abort + for l:line in a:version_lines + let l:match = matchlist(l:line, '\v(\d+)\.(\d+)(\.(\d+))?') + + if !empty(l:match) + return [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0] + endif + endfor + + return [] +endfunction + +" Given an executable name and some lines of output, which can be empty, +" parse the version from the lines of output, or return the cached version +" triple [major, minor, patch] +" +" If the version cannot be found, an empty List will be returned instead. +function! s:GetVersion(executable, version_lines) abort + let l:version = get(s:version_cache, a:executable, []) + let l:parsed_version = ale#semver#ParseVersion(a:version_lines) + + if !empty(l:parsed_version) + let l:version = l:parsed_version + let s:version_cache[a:executable] = l:version + endif + + return l:version +endfunction + +function! ale#semver#RunWithVersionCheck(buffer, executable, command, Callback) abort + if empty(a:executable) + return '' + endif + + let l:cache = s:version_cache + + if has_key(s:version_cache, a:executable) + return a:Callback(a:buffer, s:version_cache[a:executable]) + endif + + return ale#command#Run( + \ a:buffer, + \ a:command, + \ {_, output -> a:Callback(a:buffer, s:GetVersion(a:executable, output))}, + \ {'output_stream': 'both', 'executable': a:executable} + \) +endfunction + +" Given two triples of integers [major, minor, patch], compare the triples +" and return 1 if the LHS is greater than or equal to the RHS. +" +" Pairs of [major, minor] can also be used for either argument. +" +" 0 will be returned if the LHS is an empty List. +function! ale#semver#GTE(lhs, rhs) abort + if empty(a:lhs) + return 0 + endif + + if a:lhs[0] > a:rhs[0] + return 1 + elseif a:lhs[0] == a:rhs[0] + if a:lhs[1] > a:rhs[1] + return 1 + elseif a:lhs[1] == a:rhs[1] + return get(a:lhs, 2) >= get(a:rhs, 2) + endif + endif + + return 0 +endfunction diff --git a/pack/acp/start/ale/autoload/ale/sign.vim b/pack/acp/start/ale/autoload/ale/sign.vim new file mode 100644 index 0000000..7395b0e --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/sign.vim @@ -0,0 +1,388 @@ +scriptencoding utf8 +" Author: w0rp +" Description: Draws error and warning signs into signcolumn + +" This flag can be set to some integer to control the maximum number of signs +" that ALE will set. +let g:ale_max_signs = get(g:, 'ale_max_signs', -1) +" This flag can be set to 1 to enable changing the sign column colors when +" there are errors. +let g:ale_change_sign_column_color = get(g:, 'ale_change_sign_column_color', 0) +" These variables dictate what signs are used to indicate errors and warnings. +let g:ale_sign_error = get(g:, 'ale_sign_error', '>>') +let g:ale_sign_style_error = get(g:, 'ale_sign_style_error', g:ale_sign_error) +let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--') +let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning) +let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning) +" This variable sets an offset which can be set for sign IDs. +" This ID can be changed depending on what IDs are set for other plugins. +" The dummy sign will use the ID exactly equal to the offset. +let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000) +" This flag can be set to 1 to keep sign gutter always open +let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0) + +if !hlexists('ALEErrorSign') + highlight link ALEErrorSign error +endif + +if !hlexists('ALEStyleErrorSign') + highlight link ALEStyleErrorSign ALEErrorSign +endif + +if !hlexists('ALEWarningSign') + highlight link ALEWarningSign todo +endif + +if !hlexists('ALEStyleWarningSign') + highlight link ALEStyleWarningSign ALEWarningSign +endif + +if !hlexists('ALEInfoSign') + highlight link ALEInfoSign ALEWarningSign +endif + +if !hlexists('ALESignColumnWithErrors') + highlight link ALESignColumnWithErrors error +endif + +function! ale#sign#SetUpDefaultColumnWithoutErrorsHighlight() abort + redir => l:output + 0verbose silent highlight SignColumn + redir end + + let l:highlight_syntax = join(split(l:output)[2:]) + let l:match = matchlist(l:highlight_syntax, '\vlinks to (.+)$') + + if !empty(l:match) + execute 'highlight link ALESignColumnWithoutErrors ' . l:match[1] + elseif l:highlight_syntax isnot# 'cleared' + execute 'highlight ALESignColumnWithoutErrors ' . l:highlight_syntax + endif +endfunction + +if !hlexists('ALESignColumnWithoutErrors') + call ale#sign#SetUpDefaultColumnWithoutErrorsHighlight() +endif + +" Spaces and backslashes need to be escaped for signs. +function! s:EscapeSignText(sign_text) abort + return substitute(substitute(a:sign_text, ' *$', '', ''), '\\\| ', '\\\0', 'g') +endfunction + +" Signs show up on the left for error markers. +execute 'sign define ALEErrorSign text=' . s:EscapeSignText(g:ale_sign_error) +\ . ' texthl=ALEErrorSign linehl=ALEErrorLine' +execute 'sign define ALEStyleErrorSign text=' . s:EscapeSignText(g:ale_sign_style_error) +\ . ' texthl=ALEStyleErrorSign linehl=ALEErrorLine' +execute 'sign define ALEWarningSign text=' . s:EscapeSignText(g:ale_sign_warning) +\ . ' texthl=ALEWarningSign linehl=ALEWarningLine' +execute 'sign define ALEStyleWarningSign text=' . s:EscapeSignText(g:ale_sign_style_warning) +\ . ' texthl=ALEStyleWarningSign linehl=ALEWarningLine' +execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info) +\ . ' texthl=ALEInfoSign linehl=ALEInfoLine' +sign define ALEDummySign + +function! ale#sign#GetSignName(sublist) abort + let l:priority = g:ale#util#style_warning_priority + + " Determine the highest priority item for the line. + for l:item in a:sublist + let l:item_priority = ale#util#GetItemPriority(l:item) + + if l:item_priority > l:priority + let l:priority = l:item_priority + endif + endfor + + if l:priority is# g:ale#util#error_priority + return 'ALEErrorSign' + endif + + if l:priority is# g:ale#util#warning_priority + return 'ALEWarningSign' + endif + + if l:priority is# g:ale#util#style_error_priority + return 'ALEStyleErrorSign' + endif + + if l:priority is# g:ale#util#style_warning_priority + return 'ALEStyleWarningSign' + endif + + if l:priority is# g:ale#util#info_priority + return 'ALEInfoSign' + endif + + " Use the error sign for invalid severities. + return 'ALEErrorSign' +endfunction + +" Read sign data for a buffer to a list of lines. +function! ale#sign#ReadSigns(buffer) abort + redir => l:output + silent execute 'sign place buffer=' . a:buffer + redir end + + return split(l:output, "\n") +endfunction + +" Given a list of lines for sign output, return a List of [line, id, group] +function! ale#sign#ParseSigns(line_list) abort + " Matches output like : + " line=4 id=1 name=ALEErrorSign + " строка=1 id=1000001 имя=ALEErrorSign + " 行=1 識別子=1000001 名前=ALEWarningSign + " línea=12 id=1000001 nombre=ALEWarningSign + " riga=1 id=1000001, nome=ALEWarningSign + let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)' + let l:result = [] + let l:is_dummy_sign_set = 0 + + for l:line in a:line_list + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) > 0 + if l:match[3] is# 'ALEDummySign' + let l:is_dummy_sign_set = 1 + else + call add(l:result, [ + \ str2nr(l:match[1]), + \ str2nr(l:match[2]), + \ l:match[3], + \]) + endif + endif + endfor + + return [l:is_dummy_sign_set, l:result] +endfunction + +function! ale#sign#FindCurrentSigns(buffer) abort + let l:line_list = ale#sign#ReadSigns(a:buffer) + + return ale#sign#ParseSigns(l:line_list) +endfunction + +" Given a loclist, group the List into with one List per line. +function! s:GroupLoclistItems(buffer, loclist) abort + let l:grouped_items = [] + let l:last_lnum = -1 + + for l:obj in a:loclist + if l:obj.bufnr != a:buffer + continue + endif + + " Create a new sub-List when we hit a new line. + if l:obj.lnum != l:last_lnum + call add(l:grouped_items, []) + endif + + call add(l:grouped_items[-1], l:obj) + let l:last_lnum = l:obj.lnum + endfor + + return l:grouped_items +endfunction + +function! s:UpdateLineNumbers(buffer, current_sign_list, loclist) abort + let l:line_map = {} + let l:line_numbers_changed = 0 + + for [l:line, l:sign_id, l:name] in a:current_sign_list + let l:line_map[l:sign_id] = l:line + endfor + + for l:item in a:loclist + if l:item.bufnr == a:buffer + let l:lnum = get(l:line_map, get(l:item, 'sign_id', 0), 0) + + if l:lnum && l:item.lnum != l:lnum + let l:item.lnum = l:lnum + let l:line_numbers_changed = 1 + endif + endif + endfor + + " When the line numbers change, sort the list again + if l:line_numbers_changed + call sort(a:loclist, 'ale#util#LocItemCompare') + endif +endfunction + +function! s:BuildSignMap(buffer, current_sign_list, grouped_items) abort + let l:max_signs = ale#Var(a:buffer, 'max_signs') + + if l:max_signs is 0 + let l:selected_grouped_items = [] + elseif type(l:max_signs) is v:t_number && l:max_signs > 0 + let l:selected_grouped_items = a:grouped_items[:l:max_signs - 1] + else + let l:selected_grouped_items = a:grouped_items + endif + + let l:sign_map = {} + let l:sign_offset = g:ale_sign_offset + + for [l:line, l:sign_id, l:name] in a:current_sign_list + let l:sign_info = get(l:sign_map, l:line, { + \ 'current_id_list': [], + \ 'current_name_list': [], + \ 'new_id': 0, + \ 'new_name': '', + \ 'items': [], + \}) + + " Increment the sign offset for new signs, by the maximum sign ID. + if l:sign_id > l:sign_offset + let l:sign_offset = l:sign_id + endif + + " Remember the sign names and IDs in separate Lists, so they are easy + " to work with. + call add(l:sign_info.current_id_list, l:sign_id) + call add(l:sign_info.current_name_list, l:name) + + let l:sign_map[l:line] = l:sign_info + endfor + + for l:group in l:selected_grouped_items + let l:line = l:group[0].lnum + let l:sign_info = get(l:sign_map, l:line, { + \ 'current_id_list': [], + \ 'current_name_list': [], + \ 'new_id': 0, + \ 'new_name': '', + \ 'items': [], + \}) + + let l:sign_info.new_name = ale#sign#GetSignName(l:group) + let l:sign_info.items = l:group + + let l:index = index( + \ l:sign_info.current_name_list, + \ l:sign_info.new_name + \) + + if l:index >= 0 + " We have a sign with this name already, so use the same ID. + let l:sign_info.new_id = l:sign_info.current_id_list[l:index] + else + " This sign name replaces the previous name, so use a new ID. + let l:sign_info.new_id = l:sign_offset + 1 + let l:sign_offset += 1 + endif + + let l:sign_map[l:line] = l:sign_info + endfor + + return l:sign_map +endfunction + +function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort + let l:command_list = [] + let l:is_dummy_sign_set = a:was_sign_set + + " Set the dummy sign if we need to. + " The dummy sign is needed to keep the sign column open while we add + " and remove signs. + if !l:is_dummy_sign_set && (!empty(a:sign_map) || g:ale_sign_column_always) + call add(l:command_list, 'sign place ' + \ . g:ale_sign_offset + \ . ' line=1 name=ALEDummySign buffer=' + \ . a:buffer + \) + let l:is_dummy_sign_set = 1 + endif + + " Place new items first. + for [l:line_str, l:info] in items(a:sign_map) + if l:info.new_id + " Save the sign IDs we are setting back on our loclist objects. + " These IDs will be used to preserve items which are set many times. + for l:item in l:info.items + let l:item.sign_id = l:info.new_id + endfor + + if index(l:info.current_id_list, l:info.new_id) < 0 + call add(l:command_list, 'sign place ' + \ . (l:info.new_id) + \ . ' line=' . l:line_str + \ . ' name=' . (l:info.new_name) + \ . ' buffer=' . a:buffer + \) + endif + endif + endfor + + " Remove signs without new IDs. + for l:info in values(a:sign_map) + for l:current_id in l:info.current_id_list + if l:current_id isnot l:info.new_id + call add(l:command_list, 'sign unplace ' + \ . l:current_id + \ . ' buffer=' . a:buffer + \) + endif + endfor + endfor + + " Remove the dummy sign to close the sign column if we need to. + if l:is_dummy_sign_set && !g:ale_sign_column_always + call add(l:command_list, 'sign unplace ' + \ . g:ale_sign_offset + \ . ' buffer=' . a:buffer + \) + endif + + return l:command_list +endfunction + +" This function will set the signs which show up on the left. +function! ale#sign#SetSigns(buffer, loclist) abort + if !bufexists(str2nr(a:buffer)) + " Stop immediately when attempting to set signs for a buffer which + " does not exist. + return + endif + + " Find the current markers + let [l:is_dummy_sign_set, l:current_sign_list] = + \ ale#sign#FindCurrentSigns(a:buffer) + + " Update the line numbers for items from before which may have moved. + call s:UpdateLineNumbers(a:buffer, l:current_sign_list, a:loclist) + + " Group items after updating the line numbers. + let l:grouped_items = s:GroupLoclistItems(a:buffer, a:loclist) + + " Build a map of current and new signs, with the lines as the keys. + let l:sign_map = s:BuildSignMap( + \ a:buffer, + \ l:current_sign_list, + \ l:grouped_items, + \) + + let l:command_list = ale#sign#GetSignCommands( + \ a:buffer, + \ l:is_dummy_sign_set, + \ l:sign_map, + \) + + " Change the sign column color if the option is on. + if g:ale_change_sign_column_color && !empty(a:loclist) + highlight clear SignColumn + highlight link SignColumn ALESignColumnWithErrors + endif + + for l:command in l:command_list + silent! execute l:command + endfor + + " Reset the sign column color when there are no more errors. + if g:ale_change_sign_column_color && empty(a:loclist) + highlight clear SignColumn + highlight link SignColumn ALESignColumnWithoutErrors + endif +endfunction diff --git a/pack/acp/start/ale/autoload/ale/socket.vim b/pack/acp/start/ale/autoload/ale/socket.vim new file mode 100644 index 0000000..7e069fb --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/socket.vim @@ -0,0 +1,152 @@ +" Author: w0rp +" Description: APIs for working with asynchronous sockets, with an API +" normalised between Vim 8 and NeoVim. Socket connections only work in NeoVim +" 0.3+, and silently do nothing in earlier NeoVim versions. +" +" Important functions are described below. They are: +" +" ale#socket#Open(address, options) -> channel_id (>= 0 if successful) +" ale#socket#IsOpen(channel_id) -> 1 if open, 0 otherwise +" ale#socket#Close(channel_id) +" ale#socket#Send(channel_id, data) +" ale#socket#GetAddress(channel_id) -> Return the address for a job + +let s:channel_map = get(s:, 'channel_map', {}) + +function! s:VimOutputCallback(channel, data) abort + let l:channel_id = ch_info(a:channel).id + + " Only call the callbacks for jobs which are valid. + if l:channel_id >= 0 && has_key(s:channel_map, l:channel_id) + call ale#util#GetFunction(s:channel_map[l:channel_id].callback)(l:channel_id, a:data) + endif +endfunction + +function! s:NeoVimOutputCallback(channel_id, data, event) abort + let l:info = s:channel_map[a:channel_id] + + if a:event is# 'data' + let l:info.last_line = ale#util#JoinNeovimOutput( + \ a:channel_id, + \ l:info.last_line, + \ a:data, + \ l:info.mode, + \ ale#util#GetFunction(l:info.callback), + \) + endif +endfunction + +" Open a socket for a given address. The following options are accepted: +" +" callback - A callback for receiving input. (required) +" +" A non-negative number representing a channel ID will be returned is the +" connection was successful. 0 is a valid channel ID in Vim, so test if the +" connection ID is >= 0. +function! ale#socket#Open(address, options) abort + let l:mode = get(a:options, 'mode', 'raw') + let l:Callback = a:options.callback + + let l:channel_info = { + \ 'address': a:address, + \ 'mode': l:mode, + \ 'callback': a:options.callback, + \} + + if !has('nvim') + " Vim + let l:channel_options = { + \ 'mode': l:mode, + \ 'waittime': 0, + \ 'callback': function('s:VimOutputCallback'), + \} + + " Use non-blocking writes for Vim versions that support the option. + if has('patch-8.1.350') + let l:channel_options.noblock = 1 + endif + + let l:channel_info.channel = ch_open(a:address, l:channel_options) + let l:vim_info = ch_info(l:channel_info.channel) + let l:channel_id = !empty(l:vim_info) ? l:vim_info.id : -1 + elseif exists('*chansend') && exists('*sockconnect') + " NeoVim 0.3+ + try + let l:channel_id = sockconnect('tcp', a:address, { + \ 'on_data': function('s:NeoVimOutputCallback'), + \}) + let l:channel_info.last_line = '' + catch /connection failed/ + let l:channel_id = -1 + endtry + + " 0 means the connection failed some times in NeoVim, so make the ID + " invalid to match Vim. + if l:channel_id is 0 + let l:channel_id = -1 + endif + + let l:channel_info.channel = l:channel_id + else + " Other Vim versions. + let l:channel_id = -1 + endif + + if l:channel_id >= 0 + let s:channel_map[l:channel_id] = l:channel_info + endif + + return l:channel_id +endfunction + +" Return 1 is a channel is open, 0 otherwise. +function! ale#socket#IsOpen(channel_id) abort + if !has_key(s:channel_map, a:channel_id) + return 0 + endif + + if has('nvim') + " In NeoVim, we have to check if this channel is in the global list. + return index(map(nvim_list_chans(), 'v:val.id'), a:channel_id) >= 0 + endif + + let l:channel = s:channel_map[a:channel_id].channel + + return ch_status(l:channel) is# 'open' +endfunction + +" Close a socket, if it's still open. +function! ale#socket#Close(channel_id) abort + " IsRunning isn't called here, so we don't check nvim_list_chans() + if !has_key(s:channel_map, a:channel_id) + return 0 + endif + + let l:channel = remove(s:channel_map, a:channel_id).channel + + if has('nvim') + silent! call chanclose(l:channel) + elseif ch_status(l:channel) is# 'open' + call ch_close(l:channel) + endif +endfunction + +" Send some data to a socket. +function! ale#socket#Send(channel_id, data) abort + if !has_key(s:channel_map, a:channel_id) + return + endif + + let l:channel = s:channel_map[a:channel_id].channel + + if has('nvim') + call chansend(l:channel, a:data) + else + call ch_sendraw(l:channel, a:data) + endif +endfunction + +" Get an address for a channel, or an empty string. +function! ale#socket#GetAddress(channel_id) abort + return get(get(s:channel_map, a:channel_id, {}), 'address', '') +endfunction diff --git a/pack/acp/start/ale/autoload/ale/statusline.vim b/pack/acp/start/ale/autoload/ale/statusline.vim new file mode 100644 index 0000000..6b93ba5 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/statusline.vim @@ -0,0 +1,135 @@ +" Author: KabbAmine +" Additions by: petpetpetpet +" Description: Statusline related function(s) + +function! s:CreateCountDict() abort + " Keys 0 and 1 are for backwards compatibility. + " The count object used to be a List of [error_count, warning_count]. + return { + \ '0': 0, + \ '1': 0, + \ 'error': 0, + \ 'warning': 0, + \ 'info': 0, + \ 'style_error': 0, + \ 'style_warning': 0, + \ 'total': 0, + \} +endfunction + +" Update the buffer error/warning count with data from loclist. +function! ale#statusline#Update(buffer, loclist) abort + if !exists('g:ale_buffer_info') || !has_key(g:ale_buffer_info, a:buffer) + return + endif + + let l:loclist = filter(copy(a:loclist), 'v:val.bufnr == a:buffer') + let l:count = s:CreateCountDict() + let l:count.total = len(l:loclist) + + " Allows easy access to the first instance of each problem type. + let l:first_problems = {} + + for l:entry in l:loclist + if l:entry.type is# 'W' + if get(l:entry, 'sub_type', '') is# 'style' + let l:count.style_warning += 1 + + if l:count.style_warning == 1 + let l:first_problems.style_warning = l:entry + endif + else + let l:count.warning += 1 + + if l:count.warning == 1 + let l:first_problems.warning = l:entry + endif + endif + elseif l:entry.type is# 'I' + let l:count.info += 1 + + if l:count.info == 1 + let l:first_problems.info = l:entry + endif + elseif get(l:entry, 'sub_type', '') is# 'style' + let l:count.style_error += 1 + + if l:count.style_error == 1 + let l:first_problems.style_error = l:entry + endif + else + let l:count.error += 1 + + if l:count.error == 1 + let l:first_problems.error = l:entry + endif + endif + endfor + + " Set keys for backwards compatibility. + let l:count[0] = l:count.error + l:count.style_error + let l:count[1] = l:count.total - l:count[0] + + let g:ale_buffer_info[a:buffer].count = l:count + let g:ale_buffer_info[a:buffer].first_problems = l:first_problems +endfunction + +" Get the counts for the buffer, and update the counts if needed. +function! s:UpdateCacheIfNecessary(buffer) abort + " Cache is cold, so manually ask for an update. + if !has_key(g:ale_buffer_info[a:buffer], 'count') + call ale#statusline#Update( + \ a:buffer, + \ g:ale_buffer_info[a:buffer].loclist + \) + endif +endfunction + +function! s:BufferCacheExists(buffer) abort + if !exists('g:ale_buffer_info') || !has_key(g:ale_buffer_info, a:buffer) + return 0 + endif + + return 1 +endfunction + +" Get the counts for the buffer, and update the counts if needed. +function! s:GetCounts(buffer) abort + if !s:BufferCacheExists(a:buffer) + return s:CreateCountDict() + endif + + call s:UpdateCacheIfNecessary(a:buffer) + + return g:ale_buffer_info[a:buffer].count +endfunction + +" Get the dict of first_problems, update the buffer info cache if necessary. +function! s:GetFirstProblems(buffer) abort + if !s:BufferCacheExists(a:buffer) + return {} + endif + + call s:UpdateCacheIfNecessary(a:buffer) + + return g:ale_buffer_info[a:buffer].first_problems +endfunction + +" Returns a Dictionary with counts for use in third party integrations. +function! ale#statusline#Count(buffer) abort + " The Dictionary is copied here before exposing it to other plugins. + return copy(s:GetCounts(a:buffer)) +endfunction + +" Returns a copy of the *first* locline instance of the specified problem +" type. (so this would allow an external integration to know all the info +" about the first style warning in the file, for example.) +function! ale#statusline#FirstProblem(buffer, type) abort + let l:first_problems = s:GetFirstProblems(a:buffer) + + if !empty(l:first_problems) && has_key(l:first_problems, a:type) + return copy(l:first_problems[a:type]) + endif + + return {} +endfunction diff --git a/pack/acp/start/ale/autoload/ale/swift.vim b/pack/acp/start/ale/autoload/ale/swift.vim new file mode 100644 index 0000000..b31b8dc --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/swift.vim @@ -0,0 +1,13 @@ +" Author: Dan Loman +" Description: Functions for integrating with Swift tools + +" Find the nearest dir containing a Package.swift file and assume it is the root of the Swift project. +function! ale#swift#FindProjectRoot(buffer) abort + let l:swift_config = ale#path#FindNearestFile(a:buffer, 'Package.swift') + + if !empty(l:swift_config) + return fnamemodify(l:swift_config, ':h') + endif + + return '' +endfunction diff --git a/pack/acp/start/ale/autoload/ale/symbol.vim b/pack/acp/start/ale/autoload/ale/symbol.vim new file mode 100644 index 0000000..ae4151a --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/symbol.vim @@ -0,0 +1,110 @@ +let s:symbol_map = {} + +" Used to get the symbol map in tests. +function! ale#symbol#GetMap() abort + return deepcopy(s:symbol_map) +endfunction + +" Used to set the symbol map in tests. +function! ale#symbol#SetMap(map) abort + let s:symbol_map = a:map +endfunction + +function! ale#symbol#ClearLSPData() abort + let s:symbol_map = {} +endfunction + +function! ale#symbol#HandleLSPResponse(conn_id, response) abort + if has_key(a:response, 'id') + \&& has_key(s:symbol_map, a:response.id) + let l:options = remove(s:symbol_map, a:response.id) + + let l:result = get(a:response, 'result', v:null) + let l:item_list = [] + + if type(l:result) is v:t_list + " Each item looks like this: + " { + " 'name': 'foo', + " 'kind': 123, + " 'deprecated': v:false, + " 'location': { + " 'uri': 'file://...', + " 'range': { + " 'start': {'line': 0, 'character': 0}, + " 'end': {'line': 0, 'character': 0}, + " }, + " }, + " 'containerName': 'SomeContainer', + " } + for l:response_item in l:result + let l:location = l:response_item.location + + call add(l:item_list, { + \ 'filename': ale#path#FromURI(l:location.uri), + \ 'line': l:location.range.start.line + 1, + \ 'column': l:location.range.start.character + 1, + \ 'match': l:response_item.name, + \}) + endfor + endif + + if empty(l:item_list) + call ale#util#Execute('echom ''No symbols found.''') + else + call ale#preview#ShowSelection(l:item_list, l:options) + endif + endif +endfunction + +function! s:OnReady(query, options, linter, lsp_details) abort + let l:id = a:lsp_details.connection_id + + if !ale#lsp#HasCapability(l:id, 'symbol_search') + return + endif + + let l:buffer = a:lsp_details.buffer + + " If we already made a request, stop here. + if getbufvar(l:buffer, 'ale_symbol_request_made', 0) + return + endif + + let l:Callback = function('ale#symbol#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + let l:message = ale#lsp#message#Symbol(a:query) + let l:request_id = ale#lsp#Send(l:id, l:message) + + call setbufvar(l:buffer, 'ale_symbol_request_made', 1) + let s:symbol_map[l:request_id] = { + \ 'buffer': l:buffer, + \ 'use_relative_paths': has_key(a:options, 'use_relative_paths') ? a:options.use_relative_paths : 0 + \} +endfunction + +function! ale#symbol#Search(args) abort + let [l:opts, l:query] = ale#args#Parse(['relative'], a:args) + + if empty(l:query) + throw 'A non-empty string must be provided!' + endif + + let l:buffer = bufnr('') + let l:options = {} + + if has_key(l:opts, 'relative') + let l:options.use_relative_paths = 1 + endif + + " Set a flag so we only make one request. + call setbufvar(l:buffer, 'ale_symbol_request_made', 0) + let l:Callback = function('s:OnReady', [l:query, l:options]) + + for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype')) + if !empty(l:linter.lsp) && l:linter.lsp isnot# 'tsserver' + call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) + endif + endfor +endfunction diff --git a/pack/acp/start/ale/autoload/ale/test.vim b/pack/acp/start/ale/autoload/ale/test.vim new file mode 100644 index 0000000..082d91f --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/test.vim @@ -0,0 +1,187 @@ +" Author: w0rp +" Description: Functions for making testing ALE easier. +" +" This file should not typically be loaded during the normal execution of ALE. + +" Change the directory for checking things in particular test directories +" +" This function will set the g:dir variable, which represents the working +" directory after changing the path. This variable allows a test to change +" directories, and then switch back to a directory at the start of the test +" run. +" +" This function should be run in a Vader Before: block. +function! ale#test#SetDirectory(docker_path) abort + if a:docker_path[:len('/testplugin/') - 1] isnot# '/testplugin/' + throw 'docker_path must start with /testplugin/!' + endif + + " Try to switch directory, which will fail when running tests directly, + " and not through the Docker image. + silent! execute 'cd ' . fnameescape(a:docker_path) + let g:dir = getcwd() " no-custom-checks +endfunction + +" When g:dir is defined, switch back to the directory we saved, and then +" delete that variable. +" +" The filename will be reset to dummy.txt +" +" This function should be run in a Vader After: block. +function! ale#test#RestoreDirectory() abort + call ale#test#SetFilename('dummy.txt') + silent execute 'cd ' . fnameescape(g:dir) + unlet! g:dir +endfunction + +" Change the filename for the current buffer using a relative path to +" the script without running autocmd commands. +" +" If a g:dir variable is set, it will be used as the path to the directory +" containing the test file. +function! ale#test#SetFilename(path) abort + let l:dir = get(g:, 'dir', '') + + if empty(l:dir) + let l:dir = getcwd() " no-custom-checks + endif + + let l:full_path = ale#path#IsAbsolute(a:path) + \ ? a:path + \ : l:dir . '/' . a:path + + silent! noautocmd execute 'file ' . fnameescape(ale#path#Simplify(l:full_path)) +endfunction + +function! s:RemoveModule(results) abort + for l:item in a:results + if has_key(l:item, 'module') + call remove(l:item, 'module') + endif + endfor +endfunction + +" Return loclist data without the module string, only in newer Vim versions. +function! ale#test#GetLoclistWithoutModule() abort + let l:results = getloclist(0) + call s:RemoveModule(l:results) + + return l:results +endfunction + +function! ale#test#GetQflistWithoutModule() abort + let l:results = getqflist() + call s:RemoveModule(l:results) + + return l:results +endfunction + +function! ale#test#GetPreviewWindowText() abort + for l:window in range(1, winnr('$')) + if getwinvar(l:window, '&previewwindow', 0) + let l:buffer = winbufnr(l:window) + + return getbufline(l:buffer, 1, '$') + endif + endfor +endfunction + +" This function can be called with a timeout to wait for all jobs to finish. +" If the jobs to not finish in the given number of milliseconds, +" an exception will be thrown. +" +" The time taken will be a very rough approximation, and more time may be +" permitted than is specified. +function! ale#test#WaitForJobs(deadline) abort + let l:start_time = ale#events#ClockMilliseconds() + + if l:start_time == 0 + throw 'Failed to read milliseconds from the clock!' + endif + + let l:job_list = [] + + " Gather all of the jobs from every buffer. + for [l:buffer, l:data] in items(ale#command#GetData()) + call extend(l:job_list, map(keys(l:data.jobs), 'str2nr(v:val)')) + endfor + + " NeoVim has a built-in API for this, so use that. + if has('nvim') + let l:nvim_code_list = jobwait(l:job_list, a:deadline) + + if index(l:nvim_code_list, -1) >= 0 + throw 'Jobs did not complete on time!' + endif + + return + endif + + let l:should_wait_more = 1 + + while l:should_wait_more + let l:should_wait_more = 0 + + for l:job_id in l:job_list + if ale#job#IsRunning(l:job_id) + let l:now = ale#events#ClockMilliseconds() + + if l:now - l:start_time > a:deadline + " Stop waiting after a timeout, so we don't wait forever. + throw 'Jobs did not complete on time!' + endif + + " Wait another 10 milliseconds + let l:should_wait_more = 1 + sleep 10ms + break + endif + endfor + endwhile + + " Sleep for a small amount of time after all jobs finish. + " This seems to be enough to let handlers after jobs end run, and + " prevents the occasional failure where this function exits after jobs + " end, but before handlers are run. + sleep 10ms + + " We must check the buffer data again to see if new jobs started + " for command_chain linters. + let l:has_new_jobs = 0 + + " Check again to see if any jobs are running. + for l:info in values(g:ale_buffer_info) + for [l:job_id, l:linter] in get(l:info, 'job_list', []) + if ale#job#IsRunning(l:job_id) + let l:has_new_jobs = 1 + break + endif + endfor + endfor + + if l:has_new_jobs + " We have to wait more. Offset the timeout by the time taken so far. + let l:now = ale#events#ClockMilliseconds() + let l:new_deadline = a:deadline - (l:now - l:start_time) + + if l:new_deadline <= 0 + " Enough time passed already, so stop immediately. + throw 'Jobs did not complete on time!' + endif + + call ale#test#WaitForJobs(l:new_deadline) + endif +endfunction + +function! ale#test#FlushJobs() abort + " The variable is checked for in a loop, as calling one series of + " callbacks can trigger a further series of callbacks. + while exists('g:ale_run_synchronously_callbacks') + let l:callbacks = g:ale_run_synchronously_callbacks + unlet g:ale_run_synchronously_callbacks + + for l:Callback in l:callbacks + call l:Callback() + endfor + endwhile +endfunction diff --git a/pack/acp/start/ale/autoload/ale/toggle.vim b/pack/acp/start/ale/autoload/ale/toggle.vim new file mode 100644 index 0000000..1311e52 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/toggle.vim @@ -0,0 +1,100 @@ +function! s:EnablePreamble() abort + " Set pattern options again, if enabled. + if get(g:, 'ale_pattern_options_enabled', 0) + call ale#pattern_options#SetOptions(bufnr('')) + endif + + " Lint immediately, including running linters against the file. + call ale#Queue(0, 'lint_file') +endfunction + +function! s:DisablePostamble() abort + " Remove highlights for the current buffer now. + if g:ale_set_highlights + call ale#highlight#UpdateHighlights() + endif + + if g:ale_virtualtext_cursor + call ale#virtualtext#Clear() + endif +endfunction + +function! ale#toggle#Toggle() abort + let g:ale_enabled = !get(g:, 'ale_enabled') + + if g:ale_enabled + call s:EnablePreamble() + + if g:ale_set_balloons + call ale#balloon#Enable() + endif + else + call ale#engine#CleanupEveryBuffer() + call s:DisablePostamble() + + if exists('*ale#balloon#Disable') + call ale#balloon#Disable() + endif + endif + + call ale#events#Init() +endfunction + +function! ale#toggle#Enable() abort + if !g:ale_enabled + call ale#toggle#Toggle() + endif +endfunction + +function! ale#toggle#Disable() abort + if g:ale_enabled + call ale#toggle#Toggle() + endif +endfunction + +function! ale#toggle#Reset() abort + call ale#engine#CleanupEveryBuffer() + call ale#highlight#UpdateHighlights() +endfunction + +function! ale#toggle#ToggleBuffer(buffer) abort + " Get the new value for the toggle. + let l:enabled = !getbufvar(a:buffer, 'ale_enabled', 1) + + " Disabling ALE globally removes autocmd events, so we cannot enable + " linting locally when linting is disabled globally + if l:enabled && !g:ale_enabled + execute 'echom ''ALE cannot be enabled locally when disabled globally''' + + return + endif + + call setbufvar(a:buffer, 'ale_enabled', l:enabled) + + if l:enabled + call s:EnablePreamble() + else + " Stop all jobs and clear the results for everything, and delete + " all of the data we stored for the buffer. + call ale#engine#Cleanup(a:buffer) + call s:DisablePostamble() + endif +endfunction + +function! ale#toggle#EnableBuffer(buffer) abort + " ALE is enabled by default for all buffers. + if !getbufvar(a:buffer, 'ale_enabled', 1) + call ale#toggle#ToggleBuffer(a:buffer) + endif +endfunction + +function! ale#toggle#DisableBuffer(buffer) abort + if getbufvar(a:buffer, 'ale_enabled', 1) + call ale#toggle#ToggleBuffer(a:buffer) + endif +endfunction + +function! ale#toggle#ResetBuffer(buffer) abort + call ale#engine#Cleanup(a:buffer) + call ale#highlight#UpdateHighlights() +endfunction diff --git a/pack/acp/start/ale/autoload/ale/uri.vim b/pack/acp/start/ale/autoload/ale/uri.vim new file mode 100644 index 0000000..934637d --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/uri.vim @@ -0,0 +1,18 @@ +" This probably doesn't handle Unicode characters well. +function! ale#uri#Encode(value) abort + return substitute( + \ a:value, + \ '\([^a-zA-Z0-9\\/$\-_.!*''(),]\)', + \ '\=printf(''%%%02x'', char2nr(submatch(1)))', + \ 'g' + \) +endfunction + +function! ale#uri#Decode(value) abort + return substitute( + \ a:value, + \ '%\(\x\x\)', + \ '\=nr2char(''0x'' . submatch(1))', + \ 'g' + \) +endfunction diff --git a/pack/acp/start/ale/autoload/ale/util.vim b/pack/acp/start/ale/autoload/ale/util.vim new file mode 100644 index 0000000..e756360 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/util.vim @@ -0,0 +1,479 @@ +" Author: w0rp +" Description: Contains miscellaneous functions + +" A wrapper function for mode() so we can test calls for it. +function! ale#util#Mode(...) abort + return call('mode', a:000) +endfunction + +" A wrapper function for feedkeys so we can test calls for it. +function! ale#util#FeedKeys(...) abort + return call('feedkeys', a:000) +endfunction + +" Show a message in as small a window as possible. +" +" Vim 8 does not support echoing long messages from asynchronous callbacks, +" but NeoVim does. Small messages can be echoed in Vim 8, and larger messages +" have to be shown in preview windows. +function! ale#util#ShowMessage(string) abort + if !has('nvim') + call ale#preview#CloseIfTypeMatches('ale-preview.message') + endif + + " We have to assume the user is using a monospace font. + if has('nvim') || (a:string !~? "\n" && len(a:string) < &columns) + execute 'echo a:string' + else + call ale#preview#Show(split(a:string, "\n"), { + \ 'filetype': 'ale-preview.message', + \ 'stay_here': 1, + \}) + endif +endfunction + +" A wrapper function for execute, so we can test executing some commands. +function! ale#util#Execute(expr) abort + execute a:expr +endfunction + +if !exists('g:ale#util#nul_file') + " A null file for sending output to nothing. + let g:ale#util#nul_file = '/dev/null' + + if has('win32') + let g:ale#util#nul_file = 'nul' + endif +endif + +" Given a job, a buffered line of data, a list of parts of lines, a mode data +" is being read in, and a callback, join the lines of output for a NeoVim job +" or socket together, and call the callback with the joined output. +" +" Note that jobs and IDs are the same thing on NeoVim. +function! ale#util#JoinNeovimOutput(job, last_line, data, mode, callback) abort + if a:mode is# 'raw' + call a:callback(a:job, join(a:data, "\n")) + + return '' + endif + + let l:lines = a:data[:-2] + + if len(a:data) > 1 + let l:lines[0] = a:last_line . l:lines[0] + let l:new_last_line = a:data[-1] + else + let l:new_last_line = a:last_line . get(a:data, 0, '') + endif + + for l:line in l:lines + call a:callback(a:job, l:line) + endfor + + return l:new_last_line +endfunction + +" Return the number of lines for a given buffer. +function! ale#util#GetLineCount(buffer) abort + return len(getbufline(a:buffer, 1, '$')) +endfunction + +function! ale#util#GetFunction(string_or_ref) abort + if type(a:string_or_ref) is v:t_string + return function(a:string_or_ref) + endif + + return a:string_or_ref +endfunction + +" Open the file (at the given line). +" options['open_in'] can be: +" current-buffer (default) +" tab +" vertical-split +" horizontal-split +function! ale#util#Open(filename, line, column, options) abort + let l:open_in = get(a:options, 'open_in', 'current-buffer') + let l:args_to_open = '+' . a:line . ' ' . fnameescape(a:filename) + + if l:open_in is# 'tab' + call ale#util#Execute('tabedit ' . l:args_to_open) + elseif l:open_in is# 'horizontal-split' + call ale#util#Execute('split ' . l:args_to_open) + elseif l:open_in is# 'vertical-split' + call ale#util#Execute('vsplit ' . l:args_to_open) + elseif bufnr(a:filename) isnot bufnr('') + " Open another file only if we need to. + call ale#util#Execute('edit ' . l:args_to_open) + else + normal! m` + endif + + call cursor(a:line, a:column) + normal! zz +endfunction + +let g:ale#util#error_priority = 5 +let g:ale#util#warning_priority = 4 +let g:ale#util#info_priority = 3 +let g:ale#util#style_error_priority = 2 +let g:ale#util#style_warning_priority = 1 + +function! ale#util#GetItemPriority(item) abort + if a:item.type is# 'I' + return g:ale#util#info_priority + endif + + if a:item.type is# 'W' + if get(a:item, 'sub_type', '') is# 'style' + return g:ale#util#style_warning_priority + endif + + return g:ale#util#warning_priority + endif + + if get(a:item, 'sub_type', '') is# 'style' + return g:ale#util#style_error_priority + endif + + return g:ale#util#error_priority +endfunction + +" Compare two loclist items for ALE, sorted by their buffers, filenames, and +" line numbers and column numbers. +function! ale#util#LocItemCompare(left, right) abort + if a:left.bufnr < a:right.bufnr + return -1 + endif + + if a:left.bufnr > a:right.bufnr + return 1 + endif + + if a:left.bufnr == -1 + if a:left.filename < a:right.filename + return -1 + endif + + if a:left.filename > a:right.filename + return 1 + endif + endif + + if a:left.lnum < a:right.lnum + return -1 + endif + + if a:left.lnum > a:right.lnum + return 1 + endif + + if a:left.col < a:right.col + return -1 + endif + + if a:left.col > a:right.col + return 1 + endif + + " When either of the items lacks a problem type, then the two items should + " be considered equal. This is important for loclist jumping. + if !has_key(a:left, 'type') || !has_key(a:right, 'type') + return 0 + endif + + let l:left_priority = ale#util#GetItemPriority(a:left) + let l:right_priority = ale#util#GetItemPriority(a:right) + + if l:left_priority < l:right_priority + return -1 + endif + + if l:left_priority > l:right_priority + return 1 + endif + + return 0 +endfunction + +" Compare two loclist items, including the text for the items. +" +" This function can be used for de-duplicating lists. +function! ale#util#LocItemCompareWithText(left, right) abort + let l:cmp_value = ale#util#LocItemCompare(a:left, a:right) + + if l:cmp_value + return l:cmp_value + endif + + if a:left.text < a:right.text + return -1 + endif + + if a:left.text > a:right.text + return 1 + endif + + return 0 +endfunction + +" This function will perform a binary search and a small sequential search +" on the list to find the last problem in the buffer and line which is +" on or before the column. The index of the problem will be returned. +" +" -1 will be returned if nothing can be found. +function! ale#util#BinarySearch(loclist, buffer, line, column) abort + let l:min = 0 + let l:max = len(a:loclist) - 1 + + while 1 + if l:max < l:min + return -1 + endif + + let l:mid = (l:min + l:max) / 2 + let l:item = a:loclist[l:mid] + + " Binary search for equal buffers, equal lines, then near columns. + if l:item.bufnr < a:buffer + let l:min = l:mid + 1 + elseif l:item.bufnr > a:buffer + let l:max = l:mid - 1 + elseif l:item.lnum < a:line + let l:min = l:mid + 1 + elseif l:item.lnum > a:line + let l:max = l:mid - 1 + else + " This part is a small sequential search. + let l:index = l:mid + + " Search backwards to find the first problem on the line. + while l:index > 0 + \&& a:loclist[l:index - 1].bufnr == a:buffer + \&& a:loclist[l:index - 1].lnum == a:line + let l:index -= 1 + endwhile + + " Find the last problem on or before this column. + while l:index < l:max + \&& a:loclist[l:index + 1].bufnr == a:buffer + \&& a:loclist[l:index + 1].lnum == a:line + \&& a:loclist[l:index + 1].col <= a:column + let l:index += 1 + endwhile + + " Scan forwards to find the last item on the column for the item + " we found, which will have the most serious problem. + let l:item_column = a:loclist[l:index].col + + while l:index < l:max + \&& a:loclist[l:index + 1].bufnr == a:buffer + \&& a:loclist[l:index + 1].lnum == a:line + \&& a:loclist[l:index + 1].col == l:item_column + let l:index += 1 + endwhile + + return l:index + endif + endwhile +endfunction + +" A function for testing if a function is running inside a sandbox. +" See :help sandbox +function! ale#util#InSandbox() abort + try + let &l:equalprg=&l:equalprg + catch /E48/ + " E48 is the sandbox error. + return 1 + endtry + + return 0 +endfunction + +function! ale#util#Tempname() abort + let l:clear_tempdir = 0 + + if exists('$TMPDIR') && empty($TMPDIR) + let l:clear_tempdir = 1 + let $TMPDIR = '/tmp' + endif + + try + let l:name = tempname() " no-custom-checks + finally + if l:clear_tempdir + let $TMPDIR = '' + endif + endtry + + return l:name +endfunction + +" Given a single line, or a List of lines, and a single pattern, or a List +" of patterns, return all of the matches for the lines(s) from the given +" patterns, using matchlist(). +" +" Only the first pattern which matches a line will be returned. +function! ale#util#GetMatches(lines, patterns) abort + let l:matches = [] + let l:lines = type(a:lines) is v:t_list ? a:lines : [a:lines] + let l:patterns = type(a:patterns) is v:t_list ? a:patterns : [a:patterns] + + for l:line in l:lines + for l:pattern in l:patterns + let l:match = matchlist(l:line, l:pattern) + + if !empty(l:match) + call add(l:matches, l:match) + break + endif + endfor + endfor + + return l:matches +endfunction + +function! s:LoadArgCount(function) abort + let l:Function = a:function + + redir => l:output + silent! function Function + redir END + + if !exists('l:output') + return 0 + endif + + let l:match = matchstr(split(l:output, "\n")[0], '\v\([^)]+\)')[1:-2] + let l:arg_list = filter(split(l:match, ', '), 'v:val isnot# ''...''') + + return len(l:arg_list) +endfunction + +" Given the name of a function, a Funcref, or a lambda, return the number +" of named arguments for a function. +function! ale#util#FunctionArgCount(function) abort + let l:Function = ale#util#GetFunction(a:function) + let l:count = s:LoadArgCount(l:Function) + + " If we failed to get the count, forcibly load the autoload file, if the + " function is an autoload function. autoload functions aren't normally + " defined until they are called. + if l:count == 0 + let l:function_name = matchlist(string(l:Function), 'function([''"]\(.\+\)[''"])')[1] + + if l:function_name =~# '#' + execute 'runtime autoload/' . join(split(l:function_name, '#')[:-2], '/') . '.vim' + let l:count = s:LoadArgCount(l:Function) + endif + endif + + return l:count +endfunction + +" Escape a string so the characters in it will be safe for use inside of PCRE +" or RE2 regular expressions without characters having special meanings. +function! ale#util#EscapePCRE(unsafe_string) abort + return substitute(a:unsafe_string, '\([\-\[\]{}()*+?.^$|]\)', '\\\1', 'g') +endfunction + +" Escape a string so that it can be used as a literal string inside an evaled +" vim command. +function! ale#util#EscapeVim(unsafe_string) abort + return "'" . substitute(a:unsafe_string, "'", "''", 'g') . "'" +endfunction + + +" Given a String or a List of String values, try and decode the string(s) +" as a JSON value which can be decoded with json_decode. If the JSON string +" is invalid, the default argument value will be returned instead. +" +" This function is useful in code where the data can't be trusted to be valid +" JSON, and where throwing exceptions is mostly just irritating. +function! ale#util#FuzzyJSONDecode(data, default) abort + if empty(a:data) + return a:default + endif + + let l:str = type(a:data) is v:t_string ? a:data : join(a:data, '') + + try + let l:result = json_decode(l:str) + + " Vim 8 only uses the value v:none for decoding blank strings. + if !has('nvim') && l:result is v:none + return a:default + endif + + return l:result + catch /E474/ + return a:default + endtry +endfunction + +" Write a file, including carriage return characters for DOS files. +" +" The buffer number is required for determining the fileformat setting for +" the buffer. +function! ale#util#Writefile(buffer, lines, filename) abort + let l:corrected_lines = getbufvar(a:buffer, '&fileformat') is# 'dos' + \ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')') + \ : a:lines + + call writefile(l:corrected_lines, a:filename, 'S') " no-custom-checks +endfunction + +if !exists('s:patial_timers') + let s:partial_timers = {} +endif + +function! s:ApplyPartialTimer(timer_id) abort + if has_key(s:partial_timers, a:timer_id) + let [l:Callback, l:args] = remove(s:partial_timers, a:timer_id) + call call(l:Callback, [a:timer_id] + l:args) + endif +endfunction + +" Given a delay, a callback, a List of arguments, start a timer with +" timer_start() and call the callback provided with [timer_id] + args. +" +" The timer must not be stopped with timer_stop(). +" Use ale#util#StopPartialTimer() instead, which can stop any timer, and will +" clear any arguments saved for executing callbacks later. +function! ale#util#StartPartialTimer(delay, callback, args) abort + let l:timer_id = timer_start(a:delay, function('s:ApplyPartialTimer')) + let s:partial_timers[l:timer_id] = [a:callback, a:args] + + return l:timer_id +endfunction + +function! ale#util#StopPartialTimer(timer_id) abort + call timer_stop(a:timer_id) + + if has_key(s:partial_timers, a:timer_id) + call remove(s:partial_timers, a:timer_id) + endif +endfunction + +" Given a possibly multi-byte string and a 1-based character position on a +" line, return the 1-based byte position on that line. +function! ale#util#Col(str, chr) abort + if a:chr < 2 + return a:chr + endif + + return strlen(join(split(a:str, '\zs')[0:a:chr - 2], '')) + 1 +endfunction + +function! ale#util#FindItemAtCursor(buffer) abort + let l:info = get(g:ale_buffer_info, a:buffer, {}) + let l:loclist = get(l:info, 'loclist', []) + let l:pos = getpos('.') + let l:index = ale#util#BinarySearch(l:loclist, a:buffer, l:pos[1], l:pos[2]) + let l:loc = l:index >= 0 ? l:loclist[l:index] : {} + + return [l:info, l:loc] +endfunction + diff --git a/pack/acp/start/ale/autoload/ale/virtualtext.vim b/pack/acp/start/ale/autoload/ale/virtualtext.vim new file mode 100644 index 0000000..d7c5360 --- /dev/null +++ b/pack/acp/start/ale/autoload/ale/virtualtext.vim @@ -0,0 +1,135 @@ +scriptencoding utf-8 +" Author: w0rp +" Author: Luan Santos +" Description: Shows lint message for the current line as virtualtext, if any + +" Controls the milliseconds delay before showing a message. +let g:ale_virtualtext_delay = get(g:, 'ale_virtualtext_delay', 10) +let s:cursor_timer = -1 +let s:last_pos = [0, 0, 0] + +if has('nvim-0.3.2') + let s:ns_id = nvim_create_namespace('ale') +endif + +if !hlexists('ALEVirtualTextError') + highlight link ALEVirtualTextError ALEError +endif + +if !hlexists('ALEVirtualTextStyleError') + highlight link ALEVirtualTextStyleError ALEVirtualTextError +endif + +if !hlexists('ALEVirtualTextWarning') + highlight link ALEVirtualTextWarning ALEWarning +endif + +if !hlexists('ALEVirtualTextStyleWarning') + highlight link ALEVirtualTextStyleWarning ALEVirtualTextWarning +endif + +if !hlexists('ALEVirtualTextInfo') + highlight link ALEVirtualTextInfo ALEVirtualTextWarning +endif + +function! ale#virtualtext#Clear() abort + if !has('nvim-0.3.2') + return + endif + + let l:buffer = bufnr('') + + call nvim_buf_clear_highlight(l:buffer, s:ns_id, 0, -1) +endfunction + +function! ale#virtualtext#ShowMessage(message, hl_group) abort + if !has('nvim-0.3.2') + return + endif + + let l:line = line('.') + let l:buffer = bufnr('') + let l:prefix = get(g:, 'ale_virtualtext_prefix', '> ') + + call nvim_buf_set_virtual_text(l:buffer, s:ns_id, l:line-1, [[l:prefix.a:message, a:hl_group]], {}) +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#virtualtext#ShowCursorWarning(...) abort + if !g:ale_virtualtext_cursor + return + endif + + let l:buffer = bufnr('') + + if mode(1) isnot# 'n' + return + endif + + if ale#ShouldDoNothing(l:buffer) + return + endif + + let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer) + + call ale#virtualtext#Clear() + + if !empty(l:loc) + let l:msg = l:loc.text + let l:hl_group = 'ALEVirtualTextInfo' + let l:type = get(l:loc, 'type', 'E') + + if l:type is# 'E' + if get(l:loc, 'sub_type', '') is# 'style' + let l:hl_group = 'ALEVirtualTextStyleError' + else + let l:hl_group = 'ALEVirtualTextError' + endif + elseif l:type is# 'W' + if get(l:loc, 'sub_type', '') is# 'style' + let l:hl_group = 'ALEVirtualTextStyleWarning' + else + let l:hl_group = 'ALEVirtualTextWarning' + endif + endif + + call ale#virtualtext#ShowMessage(l:msg, l:hl_group) + endif +endfunction + +function! ale#virtualtext#ShowCursorWarningWithDelay() abort + let l:buffer = bufnr('') + + if !g:ale_virtualtext_cursor + return + endif + + if mode(1) isnot# 'n' + return + endif + + call s:StopCursorTimer() + + let l:pos = getpos('.')[0:2] + + " Check the current buffer, line, and column number against the last + " recorded position. If the position has actually changed, *then* + " we should show something. Otherwise we can end up doing processing + " the show message far too frequently. + if l:pos != s:last_pos + let l:delay = ale#Var(l:buffer, 'virtualtext_delay') + + let s:last_pos = l:pos + let s:cursor_timer = timer_start( + \ l:delay, + \ function('ale#virtualtext#ShowCursorWarning') + \) + endif +endfunction + diff --git a/pack/acp/start/ale/doc/ale-ada.txt b/pack/acp/start/ale/doc/ale-ada.txt new file mode 100644 index 0000000..93e3261 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-ada.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE Ada Integration *ale-ada-options* + + +=============================================================================== +gcc *ale-ada-gcc* + +g:ale_ada_gcc_executable *g:ale_ada_gcc_executable* + *b:ale_ada_gcc_executable* + Type: |String| + Default: `'gcc'` + +This variable can be changed to use a different executable for gcc. + + +g:ale_ada_gcc_options *g:ale_ada_gcc_options* + *b:ale_ada_gcc_options* + Type: |String| + Default: `'-gnatwa -gnatq'` + + This variable can be set to pass additional options to gcc. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-ansible.txt b/pack/acp/start/ale/doc/ale-ansible.txt new file mode 100644 index 0000000..3a4efaa --- /dev/null +++ b/pack/acp/start/ale/doc/ale-ansible.txt @@ -0,0 +1,16 @@ +=============================================================================== +ALE Ansible Integration *ale-ansible-options* + + +=============================================================================== +ansible-lint *ale-ansible-ansible-lint* + +g:ale_ansible_ansible_lint_executable *g:ale_ansible_ansible_lint_executable* + *b:ale_ansible_ansible_lint_executable* + Type: |String| + Default: `'ansible-lint'` + + This variable can be changed to modify the executable used for ansible-lint. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-asciidoc.txt b/pack/acp/start/ale/doc/ale-asciidoc.txt new file mode 100644 index 0000000..86629fd --- /dev/null +++ b/pack/acp/start/ale/doc/ale-asciidoc.txt @@ -0,0 +1,18 @@ +=============================================================================== +ALE AsciiDoc Integration *ale-asciidoc-options* + + +=============================================================================== +write-good *ale-asciidoc-write-good* + +See |ale-write-good-options| + + +=============================================================================== +textlint *ale-asciidoc-textlint* + +See |ale-text-textlint| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-asm.txt b/pack/acp/start/ale/doc/ale-asm.txt new file mode 100644 index 0000000..a97c6d0 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-asm.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE ASM Integration *ale-asm-options* + + +=============================================================================== +gcc *ale-asm-gcc* + +g:ale_asm_gcc_executable *g:ale_asm_gcc_executable* + *b:ale_asm_gcc_executable* + Type: |String| + Default: `'gcc'` + +This variable can be changed to use a different executable for gcc. + + +g:ale_asm_gcc_options *g:ale_asm_gcc_options* + *b:ale_asm_gcc_options* + Type: |String| + Default: `'-Wall'` + + This variable can be set to pass additional options to gcc. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-awk.txt b/pack/acp/start/ale/doc/ale-awk.txt new file mode 100644 index 0000000..b9c5c34 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-awk.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE Awk Integration *ale-awk-options* + + +=============================================================================== +gawk *ale-awk-gawk* + +g:ale_awk_gawk_executable *g:ale_awk_gawk_executable* + *b:ale_awk_gawk_executable* + Type: |String| + Default: `'gawk'` + + This variable sets executable used for gawk. + + +g:ale_awk_gawk_options *g:ale_awk_gawk_options* + *b:ale_awk_gawk_options* + Type: |String| + Default: `''` + + With this variable we are able to pass extra arguments for gawk + for invocation. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-bib.txt b/pack/acp/start/ale/doc/ale-bib.txt new file mode 100644 index 0000000..35998c3 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-bib.txt @@ -0,0 +1,19 @@ +=============================================================================== +ALE BibTeX Integration *ale-bib-options* + + +=============================================================================== +bibclean *ale-bib-bibclean* + +g:ale_bib_bibclean_executable *g:ale_bib_bibclean_executable* + + Type: |String| + Default: `'bibclean'` + +g:ale_bib_bibclean_options *g:ale_bib_bibclean_options* + + Type: |String| + Default: `'-align-equals'` + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-c.txt b/pack/acp/start/ale/doc/ale-c.txt new file mode 100644 index 0000000..ec7304f --- /dev/null +++ b/pack/acp/start/ale/doc/ale-c.txt @@ -0,0 +1,324 @@ +=============================================================================== +ALE C Integration *ale-c-options* + + +=============================================================================== +Global Options + +g:ale_c_build_dir_names *g:ale_c_build_dir_names* + *b:ale_c_build_dir_names* + + Type: |List| + Default: `['build', 'bin']` + + A list of directory names to be used when searching upwards from cpp + files to discover compilation databases with. For directory named `'foo'`, + ALE will search for `'foo/compile_commands.json'` in all directories on and above + the directory containing the cpp file to find path to compilation database. + This feature is useful for the clang tools wrapped around LibTooling (namely + here, clang-tidy) + + +g:ale_c_build_dir *g:ale_c_build_dir* + *b:ale_c_build_dir* + + Type: |String| + Default: `''` + + For programs that can read `compile_commands.json` files, this option can be + set to the directory containing the file for the project. ALE will try to + determine the location of `compile_commands.json` automatically, but if your + file exists in some other directory, you can set this option so ALE will + know where it is. + + This directory will be searched instead of |g:ale_c_build_dir_names|. + + +g:ale_c_parse_compile_commands *g:ale_c_parse_compile_commands* + *b:ale_c_parse_compile_commands* + Type: |Number| + Default: `0` + + If set to `1`, ALE will parse `compile_commands.json` files to automatically + determine flags for C or C++ compilers. ALE will first search for the + nearest `compile_commands.json` file, and then look for + `compile_commands.json` files in the directories for + |g:ale_c_build_dir_names|. + + If |g:ale_c_parse_makefile| or |b:ale_c_parse_makefile| is set to `1`, the + output of `make -n` will be preferred over `compile_commands.json` files. + + +g:ale_c_parse_makefile *g:ale_c_parse_makefile* + *b:ale_c_parse_makefile* + Type: |Number| + Default: `0` + + If set to `1`, ALE will run `make -n` to automatically determine flags to + set for C or C++ compilers. This can make it easier to determine the correct + build flags to use for different files. + + +=============================================================================== +clang *ale-c-clang* + +g:ale_c_clang_executable *g:ale_c_clang_executable* + *b:ale_c_clang_executable* + Type: |String| + Default: `'clang'` + + This variable can be changed to use a different executable for clang. + + +g:ale_c_clang_options *g:ale_c_clang_options* + *b:ale_c_clang_options* + Type: |String| + Default: `'-std=c11 -Wall'` + + This variable can be changed to modify flags given to clang. + + +=============================================================================== +clangd *ale-c-clangd* + +g:ale_c_clangd_executable *g:ale_c_clangd_executable* + *b:ale_c_clangd_executable* + Type: |String| + Default: `'clangd'` + + This variable can be changed to use a different executable for clangd. + + +g:ale_c_clangd_options *g:ale_c_clangd_options* + *b:ale_c_clangd_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clangd. + + +=============================================================================== +clang-format *ale-c-clangformat* + +g:ale_c_clangformat_executable *g:ale_c_clangformat_executable* + *b:ale_c_clangformat_executable* + Type: |String| + Default: `'clang-format'` + + This variable can be changed to use a different executable for clang-format. + + +g:ale_c_clangformat_options *g:ale_c_clangformat_options* + *b:ale_c_clangformat_options* + Type: |String| + Default: `''` + + This variable can be change to modify flags given to clang-format. + + +=============================================================================== +clangtidy *ale-c-clangtidy* + +`clang-tidy` will be run only when files are saved to disk, so that +`compile_commands.json` files can be used. It is recommended to use this +linter in combination with `compile_commands.json` files. +Therefore, `clang-tidy` linter reads the options |g:ale_c_build_dir| and +|g:ale_c_build_dir_names|. Also, setting |g:ale_c_build_dir| actually +overrides |g:ale_c_build_dir_names|. + + +g:ale_c_clangtidy_checks *g:ale_c_clangtidy_checks* + *b:ale_c_clangtidy_checks* + Type: |List| + Default: `[]` + + The checks to enable for clang-tidy with the `-checks` argument. + + All options will be joined with commas, and escaped appropriately for + the shell. The `-checks` flag can be removed entirely by setting this + option to an empty List. + + Not all of clangtidy checks are applicable for C. You should consult the + clang documentation for an up-to-date list of compatible checks: + http://clang.llvm.org/extra/clang-tidy/checks/list.html + + +g:ale_c_clangtidy_executable *g:ale_c_clangtidy_executable* + *b:ale_c_clangtidy_executable* + Type: |String| + Default: `'clang-tidy'` + + This variable can be changed to use a different executable for clangtidy. + + +g:ale_c_clangtidy_options *g:ale_c_clangtidy_options* + *b:ale_c_clangtidy_options* + Type: |String| + Default: `''` + + This variable can be changed to modify compiler flags given to clang-tidy. + + - Setting this variable to a non-empty string, + - and working in a buffer where no compilation database is found using + |g:ale_c_build_dir_names| or |g:ale_c_build_dir|, + will cause the `--` argument to be passed to `clang-tidy`, which will mean + that detection of `compile_commands.json` files for compile command + databases will be disabled. + Only set this option if you want to control compiler flags + entirely manually, and no `compile_commands.json` file is in one + of the |g:ale_c_build_dir_names| directories of the project tree. + + +g:ale_c_clangtidy_extra_options *g:ale_c_clangtidy_extra_options* + *b:ale_c_clangtidy_extra_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clang-tidy. + + +=============================================================================== +cppcheck *ale-c-cppcheck* + +g:ale_c_cppcheck_executable *g:ale_c_cppcheck_executable* + *b:ale_c_cppcheck_executable* + Type: |String| + Default: `'cppcheck'` + + This variable can be changed to use a different executable for cppcheck. + + +g:ale_c_cppcheck_options *g:ale_c_cppcheck_options* + *b:ale_c_cppcheck_options* + Type: |String| + Default: `'--enable=style'` + + This variable can be changed to modify flags given to cppcheck. + + +=============================================================================== +cquery *ale-c-cquery* + +g:ale_c_cquery_executable *g:ale_c_cquery_executable* + *b:ale_c_cquery_executable* + Type: |String| + Default: `'cquery'` + + This variable can be changed to use a different executable for cquery. + + +g:ale_cpp_cquery_cache_directory *g:ale_c_cquery_cache_directory* + *b:ale_c_cquery_cache_directory* + Type: |String| + Default: `'~/.cache/cquery'` + + This variable can be changed to decide which directory cquery uses for its +cache. + + +=============================================================================== +flawfinder *ale-c-flawfinder* + +g:ale_c_flawfinder_executable *g:ale_c_flawfinder_executable* + *b:ale_c_flawfinder_executable* + Type: |String| + Default: `'flawfinder'` + + This variable can be changed to use a different executable for flawfinder. + + +g:ale_c_flawfinder_minlevel *g:ale_c_flawfinder_minlevel* + *b:ale_c_flawfinder_minlevel* + Type: |Number| + Default: `1` + + This variable can be changed to ignore risks under the given risk threshold. + + +g:ale_c_flawfinder_options *g:ale-c-flawfinder* + *b:ale-c-flawfinder* + Type: |String| + Default: `''` + + This variable can be used to pass extra options into the flawfinder command. + +g:ale_c_flawfinder_error_severity *g:ale_c_flawfinder_error_severity* + *b:ale_c_flawfinder_error_severity* + Type: |Number| + Default: `6` + + This variable can be changed to set the minimum severity to be treated as an + error. This setting also applies to flawfinder for c++. + + +=============================================================================== +gcc *ale-c-gcc* + +g:ale_c_gcc_executable *g:ale_c_gcc_executable* + *b:ale_c_gcc_executable* + Type: |String| + Default: `'gcc'` + + This variable can be changed to use a different executable for gcc. + + +g:ale_c_gcc_options *g:ale_c_gcc_options* + *b:ale_c_gcc_options* + Type: |String| + Default: `'-std=c11 -Wall'` + + This variable can be change to modify flags given to gcc. + + +=============================================================================== +uncrustify *ale-c-uncrustify* + +g:ale_c_uncrustify_executable *g:ale_c_uncrustify_executable* + *b:ale_c_uncrustify_executable* + Type: |String| + Default: `'uncrustify'` + + This variable can be changed to use a different executable for uncrustify. + + +g:ale_c_uncrustify_options *g:ale_c_uncrustify_options* + *b:ale_c_uncrustify_options* + Type: |String| + Default: `''` + + This variable can be change to modify flags given to uncrustify. + + +=============================================================================== +ccls *ale-c-ccls* + +g:ale_c_ccls_executable *g:ale_c_ccls_executable* + *b:ale_c_ccls_executable* + Type: |String| + Default: `'ccls'` + + This variable can be changed to use a different executable for ccls. + + +g:ale_c_ccls_init_options *g:ale_c_ccls_init_options* + *b:ale_c_ccls_init_options* + Type: |Dictionary| + Default: `{}` + + This variable can be changed to customize ccls initialization options. + Example: > + { + \ 'cacheDirectory': '/tmp/ccls', + \ 'cacheFormat': 'binary', + \ 'diagnostics': { + \ 'onOpen': 0, + \ 'opChange': 1000, + \ }, + \ } +< + Visit https://github.com/MaskRay/ccls/wiki/Initialization-options for all + available options and explanations. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-chef.txt b/pack/acp/start/ale/doc/ale-chef.txt new file mode 100644 index 0000000..75e144e --- /dev/null +++ b/pack/acp/start/ale/doc/ale-chef.txt @@ -0,0 +1,46 @@ +=============================================================================== +ALE Chef Integration *ale-chef-options* + + +=============================================================================== +cookstyle *ale-chef-cookstyle* + +g:ale_chef_cookstyle_options *g:ale_chef_cookstyle_options* + *b:ale_chef_cookstyle_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to cookstyle. + + +g:ale_chef_cookstyle_executable *g:ale_chef_cookstyle_executable* + *b:ale_chef_cookstyle_executable* + Type: |String| + Default: `'cookstyle'` + + This variable can be changed to point to the cookstyle binary in case it's + not on the $PATH or a specific version/path must be used. + + +=============================================================================== +foodcritic *ale-chef-foodcritic* + +g:ale_chef_foodcritic_options *g:ale_chef_foodcritic_options* + *b:ale_chef_foodcritic_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to foodcritic. + + +g:ale_chef_foodcritic_executable *g:ale_chef_foodcritic_executable* + *b:ale_chef_foodcritic_executable* + Type: |String| + Default: `'foodcritic'` + + This variable can be changed to point to the foodcritic binary in case it's + not on the $PATH or a specific version/path must be used. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-clojure.txt b/pack/acp/start/ale/doc/ale-clojure.txt new file mode 100644 index 0000000..2bf00c0 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-clojure.txt @@ -0,0 +1,28 @@ +=============================================================================== +ALE Clojure Integration *ale-clojure-options* + + +=============================================================================== +clj-kondo *ale-clojure-clj-kondo* + +A minimal and opinionated linter for code that sparks joy. + +https://github.com/borkdude/clj-kondo + +=============================================================================== +joker *ale-clojure-joker* + +Joker is a small Clojure interpreter and linter written in Go. + +https://github.com/candid82/joker + +Linting options are not configurable by ale, but instead are controlled by a +`.joker` file in same directory as the file (or current working directory if +linting stdin), a parent directory relative to the file, or the users home +directory. + +see https://github.com/candid82/joker#linter-mode for more information. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/pack/acp/start/ale/doc/ale-cloudformation.txt b/pack/acp/start/ale/doc/ale-cloudformation.txt new file mode 100644 index 0000000..59c6af0 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-cloudformation.txt @@ -0,0 +1,14 @@ +=============================================================================== +ALE CloudFormation Integration *ale-cloudformation-options* + + +=============================================================================== +cfn-python-lint *ale-cloudformation-cfn-python-lint* + +cfn-python-lint is a linter for AWS CloudFormation template file. + +https://github.com/awslabs/cfn-python-lint + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/pack/acp/start/ale/doc/ale-cmake.txt b/pack/acp/start/ale/doc/ale-cmake.txt new file mode 100644 index 0000000..602637b --- /dev/null +++ b/pack/acp/start/ale/doc/ale-cmake.txt @@ -0,0 +1,43 @@ +=============================================================================== +ALE CMake Integration *ale-cmake-options* + + +=============================================================================== +cmakelint *ale-cmake-cmakelint* + +g:ale_cmake_cmakelint_executable *g:ale_cmake_cmakelint_executable* + *b:ale_cmake_cmakelint_executable* + Type: |String| + Default: `'cmakelint'` + + This variable can be set to change the path the cmakelint. + + +g:ale_cmake_cmakelint_options *g:ale_cmake_cmakelint_options* + *b:ale_cmake_cmakelint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to cmakelint. + + +=============================================================================== +cmake-format *ale-cmake-cmakeformat* + +g:ale_cmake_cmakeformat_executable *g:ale_cmake_cmakeformat_executable* + *b:ale_cmake_cmakeformat_executable* + Type: |String| + Default: `'cmakeformat'` + + This variable can be set to change the path the cmake-format. + + +g:ale_cmake_cmakeformat_options *g:ale_cmake_cmakeformat_options* + *b:ale_cmake_cmakeformat_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to cmake-format. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-cpp.txt b/pack/acp/start/ale/doc/ale-cpp.txt new file mode 100644 index 0000000..50855c1 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-cpp.txt @@ -0,0 +1,322 @@ +=============================================================================== +ALE C++ Integration *ale-cpp-options* + + +=============================================================================== +Global Options + +The following C options also apply to some C++ linters too. + +* |g:ale_c_build_dir_names| +* |g:ale_c_build_dir| +* |g:ale_c_parse_makefile| +* |g:ale_c_parse_compile_commands| + + +=============================================================================== +clang *ale-cpp-clang* + +g:ale_cpp_clang_executable *g:ale_cpp_clang_executable* + *b:ale_cpp_clang_executable* + Type: |String| + Default: `'clang++'` + + This variable can be changed to use a different executable for clang. + + +g:ale_cpp_clang_options *g:ale_cpp_clang_options* + *b:ale_cpp_clang_options* + Type: |String| + Default: `'-std=c++14 -Wall'` + + This variable can be changed to modify flags given to clang. + + +=============================================================================== +clangd *ale-cpp-clangd* + +g:ale_cpp_clangd_executable *g:ale_cpp_clangd_executable* + *b:ale_cpp_clangd_executable* + Type: |String| + Default: `'clangd'` + + This variable can be changed to use a different executable for clangd. + + +g:ale_cpp_clangd_options *g:ale_cpp_clangd_options* + *b:ale_cpp_clangd_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clangd. + + +=============================================================================== +clangcheck *ale-cpp-clangcheck* + +`clang-check` will be run only when files are saved to disk, so that +`compile_commands.json` files can be used. It is recommended to use this +linter in combination with `compile_commands.json` files. +Therefore, `clang-check` linter reads the options |g:ale_c_build_dir| and +|g:ale_c_build_dir_names|. Also, setting |g:ale_c_build_dir| actually +overrides |g:ale_c_build_dir_names|. + + +g:ale_cpp_clangcheck_executable *g:ale_cpp_clangcheck_executable* + *b:ale_cpp_clangcheck_executable* + Type: |String| + Default: `'clang-check'` + + This variable can be changed to use a different executable for clangcheck. + + +g:ale_cpp_clangcheck_options *g:ale_cpp_clangcheck_options* + *b:ale_cpp_clangcheck_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clang-check. + + This variable should not be set to point to build subdirectory with + `-p path/to/build` option, as it is handled by the |g:ale_c_build_dir| + option. + + +=============================================================================== +clang-format *ale-cpp-clangformat* + +See |ale-c-clangformat| for information about the available options. +Note that the C options are also used for C++. + + +=============================================================================== +clangtidy *ale-cpp-clangtidy* + +`clang-tidy` will be run only when files are saved to disk, so that +`compile_commands.json` files can be used. It is recommended to use this +linter in combination with `compile_commands.json` files. +Therefore, `clang-tidy` linter reads the options |g:ale_c_build_dir| and +|g:ale_c_build_dir_names|. Also, setting |g:ale_c_build_dir| actually +overrides |g:ale_c_build_dir_names|. + + +g:ale_cpp_clangtidy_checks *g:ale_cpp_clangtidy_checks* + *b:ale_cpp_clangtidy_checks* + Type: |List| + Default: `[]` + + The checks to enable for clang-tidy with the `-checks` argument. + + All options will be joined with commas, and escaped appropriately for + the shell. The `-checks` flag can be removed entirely by setting this + option to an empty List. + + +g:ale_cpp_clangtidy_executable *g:ale_cpp_clangtidy_executable* + *b:ale_cpp_clangtidy_executable* + Type: |String| + Default: `'clang-tidy'` + + This variable can be changed to use a different executable for clangtidy. + + +g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options* + *b:ale_cpp_clangtidy_options* + Type: |String| + Default: `''` + + This variable can be changed to modify compiler flags given to clang-tidy. + + - Setting this variable to a non-empty string, + - and working in a buffer where no compilation database is found using + |g:ale_c_build_dir_names| or |g:ale_c_build_dir|, + will cause the `--` argument to be passed to `clang-tidy`, which will mean + that detection of `compile_commands.json` files for compile command + databases will be disabled. + Only set this option if you want to control compiler flags + entirely manually, and no `compile_commands.json` file is in one + of the |g:ale_c_build_dir_names| directories of the project tree. + + +g:ale_cpp_clangtidy_extra_options *g:ale_cpp_clangtidy_extra_options* + *b:ale_cpp_clangtidy_extra_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clang-tidy. + + +=============================================================================== +clazy *ale-cpp-clazy* + +g:ale_cpp_clazy_executable *g:ale_cpp_clazy_executable* + *b:ale_cpp_clazy_executable* + Type: |String| + Default: `'clazy-standalone'` + + This variable can be changed to use a different executable for clazy. + + +g:ale_cpp_clazy_checks *g:ale_cpp_clazy_checks* + *b:ale_cpp_clazy_checks* + Type: |List| + Default: `['level1']` + + The checks to enable for clazy with the `-checks` argument. + + All options will be joined with commas, and escaped appropriately for + the shell. The `-checks` flag can be removed entirely by setting this + option to an empty List. + + +g:ale_cpp_clazy_options *g:ale_cpp_clazy_options* + *b:ale_cpp_clazy_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clazy. + + +=============================================================================== +cppcheck *ale-cpp-cppcheck* + +g:ale_cpp_cppcheck_executable *g:ale_cpp_cppcheck_executable* + *b:ale_cpp_cppcheck_executable* + Type: |String| + Default: `'cppcheck'` + + This variable can be changed to use a different executable for cppcheck. + + +g:ale_cpp_cppcheck_options *g:ale_cpp_cppcheck_options* + *b:ale_cpp_cppcheck_options* + Type: |String| + Default: `'--enable=style'` + + This variable can be changed to modify flags given to cppcheck. + + +=============================================================================== +cpplint *ale-cpp-cpplint* + +g:ale_cpp_cpplint_executable *g:ale_cpp_cpplint_executable* + *b:ale_cpp_cpplint_executable* + Type: |String| + Default: `'cpplint'` + + This variable can be changed to use a different executable for cpplint. + + +g:ale_cpp_cpplint_options *g:ale_cpp_cpplint_options* + *b:ale_cpp_cpplint_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to cpplint. + + +=============================================================================== +cquery *ale-cpp-cquery* + +g:ale_cpp_cquery_executable *g:ale_cpp_cquery_executable* + *b:ale_cpp_cquery_executable* + Type: |String| + Default: `'cquery'` + + This variable can be changed to use a different executable for cquery. + + +g:ale_cpp_cquery_cache_directory *g:ale_cpp_cquery_cache_directory* + *b:ale_cpp_cquery_cache_directory* + Type: |String| + Default: `'~/.cache/cquery'` + + This variable can be changed to decide which directory cquery uses for its + cache. + + +=============================================================================== +flawfinder *ale-cpp-flawfinder* + +g:ale_cpp_flawfinder_executable *g:ale_cpp_flawfinder_executable* + *b:ale_cpp_flawfinder_executable* + Type: |String| + Default: `'flawfinder'` + + This variable can be changed to use a different executable for flawfinder. + + +g:ale_cpp_flawfinder_minlevel *g:ale_cpp_flawfinder_minlevel* + *b:ale_cpp_flawfinder_minlevel* + Type: |Number| + Default: `1` + + This variable can be changed to ignore risks under the given risk threshold. + + +g:ale_cpp_flawfinder_options *g:ale-cpp-flawfinder* + *b:ale-cpp-flawfinder* + Type: |String| + Default: `''` + + This variable can be used to pass extra options into the flawfinder command. + + +=============================================================================== +gcc *ale-cpp-gcc* + +g:ale_cpp_gcc_executable *g:ale_cpp_gcc_executable* + *b:ale_cpp_gcc_executable* + Type: |String| + Default: `'gcc'` + + This variable can be changed to use a different executable for gcc. + + +g:ale_cpp_gcc_options *g:ale_cpp_gcc_options* + *b:ale_cpp_gcc_options* + Type: |String| + Default: `'-std=c++14 -Wall'` + + This variable can be changed to modify flags given to gcc. + + +=============================================================================== +uncrustify *ale-cpp-uncrustify* + +See |ale-c-uncrustify| for information about the available options. + + +=============================================================================== +ccls *ale-cpp-ccls* + +g:ale_cpp_ccls_executable *g:ale_cpp_ccls_executable* + *b:ale_cpp_ccls_executable* + Type: |String| + Default: `'ccls'` + + This variable can be changed to use a different executable for ccls. + + +g:ale_cpp_ccls_init_options *g:ale_cpp_ccls_init_options* + *b:ale_cpp_ccls_init_options* + Type: |Dictionary| + Default: `{}` + + This variable can be changed to customize ccls initialization options. + Example: > + { + \ 'cacheDirectory': '/tmp/ccls', + \ 'cacheFormat': 'binary', + \ 'diagnostics': { + \ 'onOpen': 0, + \ 'opChange': 1000, + \ }, + \ } +< + Visit https://github.com/MaskRay/ccls/wiki/Initialization-options for all + available options and explanations. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-cs.txt b/pack/acp/start/ale/doc/ale-cs.txt new file mode 100644 index 0000000..01e6348 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-cs.txt @@ -0,0 +1,112 @@ +=============================================================================== +ALE C# Integration *ale-cs-options* + + +In addition to the linters that are provided with ALE, C# code can be checked +with the OmniSharp plugin. See here: https://github.com/OmniSharp/omnisharp-vim + + +=============================================================================== +mcs *ale-cs-mcs* + + The `mcs` linter looks only for syntax errors while you type. See |ale-cs-mcsc| + for the separately configured linter for checking for semantic errors. + + +g:ale_cs_mcs_options *g:ale_cs_mcs_options* + *b:ale_cs_mcs_options* + + Type: String + Default: `''` + + This variable can be changed to pass additional flags given to mcs. + + NOTE: The -unsafe flag is selected implicitly and thus does not need to be + explicitly included in the |g:ale_cs_mcs_options| or |b:ale_cs_mcs_options| + parameter. + + +=============================================================================== +mcsc *ale-cs-mcsc* + + The mcsc linter checks for semantic errors when files are opened or saved + See |ale-lint-file-linters| for more information on linters which do not + check for problems while you type. + + The mcsc linter uses the mono mcs compiler to generate a temporary module + target file (-t:module). The module includes including all '*.cs' files + contained in the directory tree rooted at the path defined by the + |g:ale_cs_mcsc_source| or |b:ale_cs_mcsc_source| variable. + variable and all sub directories. + + The paths to search for additional assembly files can be specified using the + |g:ale_cs_mcsc_assembly_path| or |b:ale_cs_mcsc_assembly_path| variables. + + NOTE: ALE will not find any errors in files apart from syntax errors if any + one of the source files contains a syntax error. Syntax errors must be fixed + first before other errors will be shown. + + +g:ale_cs_mcsc_options *g:ale_cs_mcsc_options* + *b:ale_cs_mcsc_options* + Type: |String| + Default: `''` + + This option can be set to pass additional arguments to the `mcs` compiler. + + For example, to add the dotnet package which is not added per default: > + + let g:ale_cs_mcs_options = '-pkg:dotnet' +< + NOTE: the `-unsafe` option is always passed to `mcs`. + + +g:ale_cs_mcsc_source *g:ale_cs_mcsc_source* + *b:ale_cs_mcsc_source* + Type: |String| + Default: `''` + + This variable defines the root path of the directory tree searched for the + '*.cs' files to be linted. If this option is empty, the source file's + directory will be used. + + NOTE: Currently it is not possible to specify sub directories and + directory sub trees which shall not be searched for *.cs files. + + +g:ale_cs_mcsc_assembly_path *g:ale_cs_mcsc_assembly_path* + *b:ale_cs_mcsc_assembly_path* + Type: |List| + Default: `[]` + + This variable defines a list of path strings to be searched for external + assembly files. The list is passed to the mcs compiler using the `-lib:` + flag. + + +g:ale_cs_mcsc_assemblies *g:ale_cs_mcsc_assemblies* + *b:ale_cs_mcsc_assemblies* + Type: |List| + Default: `[]` + + This variable defines a list of external assembly (*.dll) files required + by the mono mcs compiler to generate a valid module target. The list is + passed the mcs compiler using the `-r:` flag. + + For example: > + + " Compile C# programs with the Unity engine DLL file on Mac. + let g:ale_cs_mcsc_assemblies = [ + \ '/Applications/Unity/Unity.app/Contents/Frameworks/Managed/UnityEngine.dll', + \ 'path-to-unityproject/obj/Debug', + \] +< + +=============================================================================== +uncrustify *ale-cs-uncrustify* + +See |ale-c-uncrustify| for information about the available options. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-css.txt b/pack/acp/start/ale/doc/ale-css.txt new file mode 100644 index 0000000..ff74b26 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-css.txt @@ -0,0 +1,47 @@ +=============================================================================== +ALE CSS Integration *ale-css-options* + + +=============================================================================== +fecs *ale-css-fecs* + +`fecs` options for CSS is the same as the options for JavaScript, and both of +them reads `./.fecsrc` as the default configuration file. See: +|ale-javascript-fecs|. + + +=============================================================================== +prettier *ale-css-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +stylelint *ale-css-stylelint* + +g:ale_css_stylelint_executable *g:ale_css_stylelint_executable* + *b:ale_css_stylelint_executable* + Type: |String| + Default: `'stylelint'` + + See |ale-integrations-local-executables| + + +g:ale_css_stylelint_options *g:ale_css_stylelint_options* + *b:ale_css_stylelint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to stylelint. + + +g:ale_css_stylelint_use_global *g:ale_css_stylelint_use_global* + *b:ale_css_stylelint_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-cuda.txt b/pack/acp/start/ale/doc/ale-cuda.txt new file mode 100644 index 0000000..0e53f75 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-cuda.txt @@ -0,0 +1,32 @@ +=============================================================================== +ALE CUDA Integration *ale-cuda-options* + + +=============================================================================== +nvcc *ale-cuda-nvcc* + +g:ale_cuda_nvcc_executable *g:ale_cuda_nvcc_executable* + *b:ale_cuda_nvcc_executable* + Type: |String| + Default: `'nvcc'` + + This variable can be changed to use a different executable for nvcc. + Currently only nvcc 8.0 is supported. + + +g:ale_cuda_nvcc_options *g:ale_cuda_nvcc_options* + *b:ale_cuda_nvcc_options* + Type: |String| + Default: `'-std=c++11'` + + This variable can be changed to modify flags given to nvcc. + +=============================================================================== +clang-format *ale-cuda-clangformat* + +See |ale-c-clangformat| for information about the available options. +Note that the C options are also used for cuda. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-d.txt b/pack/acp/start/ale/doc/ale-d.txt new file mode 100644 index 0000000..5559606 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-d.txt @@ -0,0 +1,23 @@ +=============================================================================== +ALE D Integration *ale-d-options* + + +=============================================================================== +dls *ale-d-dls* + +g:ale_d_dls_executable *g:ale_d_dls_executable* + *b:ale_d_dls_executable* + Type: |String| + Default: `dls` + +See |ale-integrations-local-executables| + + +=============================================================================== +uncrustify *ale-d-uncrustify* + +See |ale-c-uncrustify| for information about the available options. + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-dart.txt b/pack/acp/start/ale/doc/ale-dart.txt new file mode 100644 index 0000000..a6d88dd --- /dev/null +++ b/pack/acp/start/ale/doc/ale-dart.txt @@ -0,0 +1,71 @@ +=============================================================================== +ALE Dart Integration *ale-dart-options* + + +=============================================================================== +dartanalyzer *ale-dart-dartanalyzer* + +Installation +------------------------------------------------------------------------------- + +Install Dart via whatever means. `dartanalyzer` will be included in the SDK. + +You can add the SDK to `$PATH`, as described here: +https://www.dartlang.org/tools/sdk + +If you have installed Dart on Linux, you can also try the following: > + " Set the executable path for dartanalyzer to the absolute path to it. + let g:ale_dart_dartanalyzer_executable = '/usr/lib/dart/bin/dartanalyzer' +< +... or similarly for wherever your Dart SDK lives. This should work without +having to modify `$PATH`. + +ALE can only check for problems with `dartanalyzer` with the file on disk. +See |ale-lint-file-linters| + +Options +------------------------------------------------------------------------------- + +g:ale_dart_dartanalyzer_executable *g:ale_dart_dartanalyzer_executable* + *b:ale_dart_dartanalyzer_executable* + Type: |String| + Default: `'dartanalyzer'` + + This variable can be set to change the path to dartanalyzer. + + +=============================================================================== +dartfmt *ale-dart-dartfmt* + +Installation +------------------------------------------------------------------------------- + +Installing Dart should probably ensure that `dartfmt` is in your `$PATH`. + +In case it is not, try to set the executable option to its absolute path. : > + " Set the executable path for dartfmt to the absolute path to it. + let g:ale_dart_dartfmt_executable = '/usr/lib/dart/bin/dartfmt' + > + +Options +------------------------------------------------------------------------------- + +g:ale_dart_dartfmt_executable *g:ale_dart_dartfmt_executable* + *b:ale_dart_dartfmt_executable* + Type: |String| + Default: `''` + + This variable can be set to specify an absolute path to the + dartfmt executable (or to specify an alternate executable). + + +g:ale_dart_dartfmt_options *g:ale_dart_dartfmt_options* + *b:ale_dart_dartfmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the dartfmt fixer. + +=============================================================================== + + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-development.txt b/pack/acp/start/ale/doc/ale-development.txt new file mode 100644 index 0000000..16b1648 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-development.txt @@ -0,0 +1,358 @@ +*ale-development.txt* For Vim version 8.0. +*ale-dev* +*ale-development* + +ALE Development Documentation + +=============================================================================== +CONTENTS *ale-development-contents* + + 1. Introduction.........................|ale-development-introduction| + 2. Design Goals.........................|ale-design-goals| + 3. Coding Standards.....................|ale-coding-standards| + 4. Testing ALE..........................|ale-development-tests| + 4.1. Writing Linter Tests.............|ale-development-linter-tests| + 4.2. Writing Fixer Tests..............|ale-development-fixer-tests| + +=============================================================================== +1. Introduction *ale-development-introduction* + +This document contains helpful information for ALE developers, including +design goals, information on how to run the tests, coding standards, and so +on. You should read this document if you want to get involved with ALE +development. + +=============================================================================== +2. Design Goals *ale-design-goals* + +This section lists design goals for ALE, in no particular order. They are as +follows. + +ALE code should be almost 100% VimL. This makes the plugin as portable as +possible. + +ALE should run without needing any other plugins to be installed, to make +installation simple. ALE can integrate with other plugins for more advanced +functionality, non-essential functionality, or improving on basic first party +functionality. + +ALE should check files with as many tools as possible by default, except where +they cause security issues or make excessive use of resources on modern +machines. + +ALE should be free of breaking changes to the public API, which is comprised of +documented functions and options, until a major version is planned. Breaking +changes should be preceded by a deprecation phase complete with warnings. +Changes required for security may be an exception. + +ALE supports Vim 8 and above, and NeoVim 0.2.0 or newer. These are the +earliest versions of Vim and NeoVim which support |job|, |timer|, |closure|, +and |lambda| features. All ALE code should be written so it is compatible with +these versions of Vim, or with version checks so particular features can +degrade or fail gracefully. + +Just about everything should be documented and covered with tests. + +By and large, people shouldn't pay for the functionality they don't use. Care +should be taken when adding new features, so supporting new features doesn't +degrade the general performance of anything ALE does. + +LSP support will become more important as time goes on. ALE should provide +better support for LSP features as time goes on. + +When merging pull requests, you should respond with `Cheers! :beers:`, purely +for comedy value. + +=============================================================================== +3. Coding Standards *ale-coding-standards* + +The following general coding standards should be adhered to for Vim code. + +* Check your Vim code with `Vint` and do everything it says. ALE will check + your Vim code with Vint automatically. See: https://github.com/Kuniwak/vint + Read ALE's `Dockerfile` to see which version of `Vint` it uses. +* Try to write descriptive and concise names for variables and functions. + Names shouldn't be too short or too long. Think about others reading your + code later on. +* Use `snake_case` names for variables and arguments, and `PascalCase` names + for functions. Prefix every variable name with its scope. (`l:`, `g:`, etc.) +* Try to keep lines no longer than 80 characters, but this isn't an absolute + requirement. +* Use 4 spaces for every level of indentation in Vim code. +* Add a blank line before every `function`, `if`, `for`, `while`, or `return`, + which doesn't start a new level of indentation. This makes the logic in + your code easier to follow. +* End every file with a trailing newline character, but not with extra blank + lines. Remove trailing whitespace from the ends of lines. +* Write the full names of commands instead of abbreviations. For example, write + `function` instead of `func`, and `endif` instead of `end`. +* Write functions with `!`, so files can be reloaded. Use the |abort| keyword + for all functions, so functions exit on the first error. +* Make sure to credit yourself in files you have authored with `Author:` + and `Description:` comments. + +In addition to the above general guidelines for the style of your code, you +should also follow some additional rules designed to prevent mistakes. Some of +these are reported with ALE's `custom-linting-rules` script. See +|ale-development-tests|. + +* Don't leave stray `:echo` lines in code. Use `execute 'echo' ...` if you must + echo something. +* For strings use |is#| instead of |==#|, `is?` instead of `==?`, `isnot#` + instead of `!=#`, and `isnot?` instead of `!=?`. This is because `'x' ==# 0` + returns 1, while `'x' is# 0` returns 0, so you will experience fewer issues + when numbers are compared with strings. `is` and `isnot` also do not throw + errors when other objects like List or Dictionaries are compared with + strings. +* Don't use the `getcwd()` function in the ALE codebase. Most of ALE's code + runs from asynchronous callback functions, and these functions can execute + from essentially random buffers. Therefore, the `getcwd()` output is + useless. Use `expand('#' . a:buffer . ':p:h')` instead. Don't use + `expand('%...')` for the same reason. +* Don't use the `simplify()` function. It doesn't simplify paths enough. Use + `ale#path#Simplify()` instead. +* Don't use the `shellescape()` function. It doesn't escape arguments properly + on Windows. Use `ale#Escape()` instead, which will avoid escaping where it + isn't needed, and generally escape arguments better on Windows. +* Don't use the `tempname()` function. It doesn't work when `$TMPDIR` isn't + set. Use `ale#util#Tempname()` instead, which temporarily sets `$TMPDIR` + appropriately where needed. +* Use `snake_case` names for linter names, so they can be used as part of + variable names. You can define `aliases` for linters, for other names people + might try to configure linters with. +* Use |v:t_TYPE| variables instead of `type()`, which are more readable. + +Apply the following guidelines when writing Vader test files. + +* Use 2 spaces for Vader test files, instead of the 4 spaces for Vim files. +* If you write `Before` and `After` blocks, you should typically write them at + the top of the file, so they run for all tests. There may be some tests + where it make sense to modify the `Before` and `After` code part of the way + through the file. +* If you modify any settings or global variables, reset them in `After` + blocks. The Vader `Save` and `Restore` commands can be useful for this + purpose. +* If you load or define linters in tests, write `call ale#linter#Reset()` in + an `After` block. +* Just write `Execute` blocks for Vader tests, and don't bother writing `Then` + blocks. `Then` blocks execute after `After` blocks in older versions, and + that can be confusing. + +Apply the following rules when writing Bash scripts. + +* Run `shellcheck`, and do everything it says. + See: https://github.com/koalaman/shellcheck +* Try to write scripts so they will run on Linux, BSD, or Mac OSX. + +=============================================================================== +4. Testing ALE *ale-development-tests* *ale-dev-tests* *ale-tests* + +ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE +runs tests with the following versions of Vim in the following environments. + +1. Vim 8.0.0027 on Linux via Travis CI. +2. Vim 8.1.0519 on Linux via Travis CI. +3. NeoVim 0.2.0 on Linux via Travis CI. +4. NeoVim 0.3.5 on Linux via Travis CI. +5. Vim 8 (stable builds) on Windows via AppVeyor. + +If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs +tests by installing Docker and running the `run-tests` script. Follow the +instructions on the Docker site for installing Docker. +See: https://docs.docker.com/install/ + +NOTE: Don't forget to add your user to the `docker` group on Linux, or Docker +just won't work. See: https://docs.docker.com/install/linux/linux-postinstall/ + +If you run simply `./run-tests` from the ALE repository root directory, the +latest Docker image for tests will be downloaded if needed, and the script +will run all of the tests in Vader, Vint checks, and several Bash scripts for +finding extra issues. Run `./run-tests --help` to see all of the options the +script supports. Note that the script supports selecting particular test files. + +Generally write tests for any changes you make. The following types of tests +are recommended for the following types of code. + +* New/edited error handler callbacks -> Write tests in `test/handler` +* New/edited command callbacks -> Write tests in `test/command_callback` +* New/edited fixer functions -> Write tests in `test/fixers` + +Look at existing tests in the codebase for examples of how to write tests. +Refer to the Vader documentation for general information on how to write Vader +tests: https://github.com/junegunn/vader.vim + +See |ale-development-linter-tests| for more information on how to write linter +tests. + +When you add new linters or fixers, make sure to add them into the table in +the README, and also into the |ale-support| list in the main help file. If you +forget to keep them both in sync, you should see an error like the following +in Travis CI. > + + ======================================== + diff README.md and doc/ale.txt tables + ======================================== + Differences follow: + + --- /tmp/readme.qLjNhJdB 2018-07-01 16:29:55.590331972 +0100 + +++ /tmp/doc.dAi8zfVE 2018-07-01 16:29:55.582331877 +0100 + @@ -1 +1 @@ + - ASM: gcc, foobar + + ASM: gcc +< +Make sure to list documentation entries for linters and fixers in individual +help files in the table of contents, and to align help tags to the right +margin. For example, if you add a heading for an `aardvark` tool to +`ale-python.txt` with a badly aligned doc tag, you will see errors like so. > + + ======================================== + Look for badly aligned doc tags + ======================================== + Badly aligned tags follow: + + doc/ale-python.txt:aardvark ... + ======================================== + Look for table of contents issues + ======================================== + + Check for bad ToC sorting: + + Check for mismatched ToC and headings: + + --- /tmp/table-of-contents.mwCFOgSI 2018-07-01 16:33:25.068811878 +0100 + +++ /tmp/headings.L4WU0hsO 2018-07-01 16:33:25.076811973 +0100 + @@ -168,6 +168,7 @@ + pyrex (cython), ale-pyrex-options + cython, ale-pyrex-cython + python, ale-python-options + + aardvark, ale-python-aardvark + autopep8, ale-python-autopep8 + black, ale-python-black + flake8, ale-python-flake8 +< +Make sure to make the table of contents match the headings, and to keep the +doc tags on the right margin. + +=============================================================================== +4.1 Writing Linter Tests *ale-development-linter-tests* + +Tests for ALE linters take two forms. + +1. Tests for handling the output of commands. +2. Tests for checking which commands are run, or connections are made. + +Tests of the first form should go in the `test/handler` directory, and should +be written like so. > + + Before: + " Load the file which defines the linter. + runtime ale_linters/filetype/linter_name_here.vim + + After: + " Unload all linters again. + call ale#linter#Reset() + + Execute(The output should be correct): + + " Test that the right loclist items are parsed from the handler. + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'type': 'E', + \ 'text': 'Something went wrong', + \ }, + \ ], + \ ale_linters#filetype#linter_name#Handle(bufnr(''), [ + \ '1:Something went wrong', + \ ] +< +Tests for what ALE runs should go in the `test/command_callback` directory, +and should be written like so. > + + Before: + " Load the linter and set up a series of commands, reset linter variables, + " clear caches, etc. + " + " Vader's 'Save' command will be called here for linter variables. + call ale#assert#SetUpLinterTest('filetype', 'linter_name') + + After: + " Reset linters, variables, etc. + " + " Vader's 'Restore' command will be called here. + call ale#assert#TearDownLinterTest() + + Execute(The default command should be correct): + " AssertLinter checks the executable and command. + " Pass expected_executable, expected_command + AssertLinter 'some-command', ale#Escape('some-command') . ' --foo' + + Execute(Check chained commands): + " GivenCommandOutput can be called with 1 or more list for passing output + " to chained commands. The output for each callback defaults to an empty + " list. + GivenCommandOutput ['v2.1.2'] + " Given a List of commands, check all of them. + " Given a String, only the last command in the chain will be checked. + AssertLinter 'some-command', [ + \ ale#Escape('some-command') . ' --version', + \ ale#Escape('some-command') . ' --foo', + \] +< +The full list of commands that will be temporarily defined for linter tests +given the above setup are as follows. + +`GivenCommandOutput [...]` - Define output for ale#command#Run. +`AssertLinter executable, command` - Check the executable and command. +`AssertLinterNotExecuted` - Check that linters will not be executed. +`AssertLSPLanguage language` - Check the language given to an LSP server. +`AssertLSPOptions options_dict` - Check the options given to an LSP server. +`AssertLSPConfig config_dict` - Check the config given to an LSP server. +`AssertLSPProject project_root` - Check the root given to an LSP server. +`AssertLSPAddress address` - Check the address to an LSP server. + + +=============================================================================== +4.2 Writing Fixer Tests *ale-development-fixer-tests* + +Tests for ALE fixers should go in the `test/fixers` directory, and should +be written like so. > + + Before: + " Load the fixer and set up a series of commands, reset fixer variables, + " clear caches, etc. + " + " Vader's 'Save' command will be called here for fixer variables. + call ale#assert#SetUpFixerTest('filetype', 'fixer_name') + + After: + " Reset fixers, variables, etc. + " + " Vader's 'Restore' command will be called here. + call ale#assert#TearDownFixerTest() + + Execute(The default command should be correct): + " AssertFixer checks the result of the loaded fixer function. + AssertFixer {'command': ale#Escape('some-command') . ' --foo'} + + Execute(Check chained commands): + " Same as above for linter tests. + GivenCommandOutput ['v2.1.2'] + " Given a List of commands, check all of them. + " Given anything else, only the last result will be checked. + AssertFixer [ + \ ale#Escape('some-command') . ' --version', + \ {'command': ale#Escape('some-command') . ' --foo'} + \] +< +The full list of commands that will be temporarily defined for fixer tests +given the above setup are as follows. + +`GivenCommandOutput [...]` - Define output for ale#command#Run. +`AssertFixer results` - Check the fixer results +`AssertFixerNotExecuted` - Check that fixers will not be executed. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-dockerfile.txt b/pack/acp/start/ale/doc/ale-dockerfile.txt new file mode 100644 index 0000000..284c6a1 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-dockerfile.txt @@ -0,0 +1,60 @@ +=============================================================================== +ALE Dockerfile Integration *ale-dockerfile-options* + + +=============================================================================== +dockerfile_lint *ale-dockerfile-dockerfile_lint* + +g:ale_dockerfile_dockerfile_lint_executable + *g:ale_dockerfile_dockerfile_lint_executable* + *b:ale_dockerfile_dockerfile_lint_executable* + Type: |String| + Default: `'dockerfile_lint'` + + This variable can be changed to specify the executable used to run + dockerfile_lint. + + +g:ale_dockerfile_dockerfile_lint_options + *g:ale_dockerfile_dockerfile_lint_options* + *b:ale_dockerfile_dockerfile_lint_options* + Type: |String| + Default: `''` + + This variable can be changed to add additional command-line arguments to + the dockerfile lint invocation - like custom rule file definitions. + + +=============================================================================== +hadolint *ale-dockerfile-hadolint* + + hadolint can be found at: https://github.com/hadolint/hadolint + + +g:ale_dockerfile_hadolint_use_docker *g:ale_dockerfile_hadolint_use_docker* + *b:ale_dockerfile_hadolint_use_docker* + Type: |String| + Default: `'never'` + + This variable controls if docker and the hadolint image are used to run this + linter: if 'never', docker will never be used; 'always' means docker will + always be used; 'yes' and docker will be used if the hadolint executable + cannot be found. + + For now, the default is 'never'. This may change as ale's support for using + docker to lint evolves. + + +g:ale_dockerfile_hadolint_image *g:ale_dockerfile_hadolint_image* + *b:ale_dockerfile_hadolint_image* + Type: |String| + Default: `'hadolint/hadolint'` + + This variable controls the docker image used to run hadolint. The default + is hadolint's author's build, and can be found at: + + https://hub.docker.com/r/hadolint/hadolint/ + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-elixir.txt b/pack/acp/start/ale/doc/ale-elixir.txt new file mode 100644 index 0000000..5864f72 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-elixir.txt @@ -0,0 +1,89 @@ +=============================================================================== +ALE Elixir Integration *ale-elixir-options* + + +=============================================================================== +mix *ale-elixir-mix* + + +The `mix` linter is disabled by default, as it can bee too expensive to run. +See `:help g:ale_linters` + + +g:ale_elixir_mix_options *g:ale_elixir_mix_options* + *b:ale_elixir_mix_options* + Type: |String| + Default: `'mix'` + + + This variable can be changed to specify the mix executable. + +=============================================================================== +mix_format *ale-elixir-mix-format* + +g:ale_elixir_mix_format_options *g:ale_elixir_mix_format_options* + *b:ale_elixir_mix_format_options* + Type: |String| + Default: `''` + + + This variable can be changed to specify the mix options passed to the + mix_format fixer + +=============================================================================== +dialyxir *ale-elixir-dialyxir* + +Dialyzer, a DIscrepancy AnaLYZer for ERlang programs. +http://erlang.org/doc/man/dialyzer.html + +It can be used with elixir through dialyxir +https://github.com/jeremyjh/dialyxir + +Options for dialyzer are not configurable by ale, but they are instead +configured on your project's `mix.exs`. + +See https://github.com/jeremyjh/dialyxir#with-explaining-stuff for more +information. + +=============================================================================== +elixir-ls *ale-elixir-elixir-ls* + +Elixir Language Server (https://github.com/JakeBecker/elixir-ls) + +g:ale_elixir_elixir_ls_release *g:ale_elixir_elixir_ls_release* + *b:ale_elixir_elixir_ls_release* + Type: |String| + Default: `'elixir-ls'` + + Location of the elixir-ls release directory. This directory must contain + the language server scripts (language_server.sh and language_server.bat). + +g:ale_elixir_elixir_ls_config *g:ale_elixir_elixir_ls_config* + *b:ale_elixir_elixir_ls_config* + Type: |Dictionary| + Default: `{}` + + Dictionary containing configuration settings that will be passed to the + language server. For example, to disable Dialyzer: > + { + \ 'elixirLS': { + \ 'dialyzerEnabled': v:false, + \ }, + \ } +< + Consult the ElixirLS documentation for more information about settings. +=============================================================================== +credo *ale-elixir-credo* + +Credo (https://github.com/rrrene/credo) + +g:ale_elixir_credo_strict *g:ale_elixir_credo_strict* + + Type: Integer + Default: 0 + + Tells credo to run in strict mode or suggest mode. Set variable to 1 to + enable --strict mode. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-elm.txt b/pack/acp/start/ale/doc/ale-elm.txt new file mode 100644 index 0000000..bb7a613 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-elm.txt @@ -0,0 +1,68 @@ +=============================================================================== +ALE Elm Integration *ale-elm-options* + + +=============================================================================== +elm-format *ale-elm-elm-format* + +g:ale_elm_format_executable *g:ale_elm_format_executable* + *b:ale_elm_format_executable* + Type: |String| + Default: `'elm-format'` + + See |ale-integrations-local-executables| + + +g:ale_elm_format_use_global *g:ale_elm_format_use_global* + *b:ale_elm_format_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_elm_format_options *g:ale_elm_format_options* + *b:ale_elm_format_options* + Type: |String| + Default: `'--yes'` + + This variable can be set to pass additional options to elm-format. + +=============================================================================== +elm-lsp *ale-elm-elm-lsp* + +g:ale_elm_lsp_executable *g:ale_elm_lsp_executable* + *b:ale_elm_lsp_executable* + Type: |String| + Default: `'elm-lsp'` + + See |ale-integrations-local-executables| + + +g:ale_elm_lsp_use_global *g:ale_elm_lsp_use_global* + *b:ale_elm_lsp_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + +=============================================================================== +elm-make *ale-elm-elm-make* + +g:ale_elm_make_executable *g:ale_elm_make_executable* + *b:ale_elm_make_executable* + Type: |String| + Default: `'elm'` + + See |ale-integrations-local-executables| + + +g:ale_elm_make_use_global *g:ale_elm_make_use_global* + *b:ale_elm_make_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-erlang.txt b/pack/acp/start/ale/doc/ale-erlang.txt new file mode 100644 index 0000000..59993a9 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-erlang.txt @@ -0,0 +1,58 @@ +=============================================================================== +ALE Erlang Integration *ale-erlang-options* + + +=============================================================================== +dialyzer *ale-erlang-dialyzer* + +g:ale_erlang_dialyzer_executable *g:ale_erlang_dialyzer_executable* + *b:ale_erlang_dialyzer_executable* + Type: |String| + Default: `'dialyzer'` + + This variable can be changed to specify the dialyzer executable. + + +g:ale_erlang_dialyzer_plt_file *g:ale_erlang_dialyzer_plt_file* + *b:ale_erlang_dialyzer_plt_file* + Type: |String| + + This variable can be changed to specify the path to the PLT file. By + default, it will search for the PLT file inside the `_build` directory. If + there isn't one, it will fallback to the path `$REBAR_PLT_DIR/dialyzer/plt`. + Otherwise, it will default to `$HOME/.dialyzer_plt`. + + +g:ale_erlang_dialyzer_rebar3_profile *g:ale_erlang_dialyzer_rebar3_profile* + *b:ale_erlang_dialyzer_rebar3_profile* + Type: |String| + Default: `'default'` + + This variable can be changed to specify the profile that is used to + run dialyzer with rebar3. + +------------------------------------------------------------------------------- +erlc *ale-erlang-erlc* + +g:ale_erlang_erlc_options *g:ale_erlang_erlc_options* + *b:ale_erlang_erlc_options* + Type: |String| + Default: `''` + + This variable controls additional parameters passed to `erlc`, such as `-I` + or `-pa`. + + +------------------------------------------------------------------------------- +syntaxerl *ale-erlang-syntaxerl* + +g:ale_erlang_syntaxerl_executable *g:ale_erlang_syntaxerl_executable* + *b:ale_erlang_syntaxerl_executable* + Type: |String| + Default: `'syntaxerl'` + + This variable can be changed to specify the syntaxerl executable. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-eruby.txt b/pack/acp/start/ale/doc/ale-eruby.txt new file mode 100644 index 0000000..d75d386 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-eruby.txt @@ -0,0 +1,37 @@ +=============================================================================== +ALE Eruby Integration *ale-eruby-options* + +There are four linters for `eruby` files: + +- `erb` +- `erubis` +- `erubi` +- `ruumba` + +`erb` is in the Ruby standard library and is mostly universal. `erubis` is the +default parser in Rails between 3.0 and 5.1. `erubi` is the default in Rails +5.1 and later. `ruumba` can extract Ruby from eruby files and run rubocop on +the result. To selectively enable a subset, see |g:ale_linters|. + +=============================================================================== +ruumba *ale-eruby-ruumba* + +g:ale_eruby_ruumba_executable *g:ale_eruby_ruumba_executable* + *b:ale_eruby_ruumba_executable* + Type: String + Default: `'ruumba` + + Override the invoked ruumba binary. This is useful for running ruumba + from binstubs or a bundle. + + +g:ale_eruby_ruumba_options *g:ale_ruby_ruumba_options* + *b:ale_ruby_ruumba_options* + Type: |String| + Default: `''` + + This variable can be change to modify flags given to ruumba. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-fish.txt b/pack/acp/start/ale/doc/ale-fish.txt new file mode 100644 index 0000000..8450b38 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-fish.txt @@ -0,0 +1,14 @@ +=============================================================================== +ALE Fish Integration *ale-fish-options* + +Lints fish files using `fish -n`. + +Note that `fish -n` is not foolproof: it sometimes gives false positives or +errors that are difficult to parse without more context. This integration skips +displaying errors if an error message is not found. + +If ALE is not showing any errors but your file does not run as expected, run +`fish -n ` from the command line. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-fortran.txt b/pack/acp/start/ale/doc/ale-fortran.txt new file mode 100644 index 0000000..c9b7e8e --- /dev/null +++ b/pack/acp/start/ale/doc/ale-fortran.txt @@ -0,0 +1,55 @@ +=============================================================================== +ALE Fortran Integration *ale-fortran-options* + + +=============================================================================== +gcc *ale-fortran-gcc* + +g:ale_fortran_gcc_executable *g:ale_fortran_gcc_executable* + *b:ale_fortran_gcc_executable* + Type: |String| + Default: `'gcc'` + + This variable can be changed to modify the executable used for checking + Fortran code with GCC. + + +g:ale_fortran_gcc_options *g:ale_fortran_gcc_options* + *b:ale_fortran_gcc_options* + Type: |String| + Default: `'-Wall'` + + This variable can be changed to modify flags given to gcc. + + +g:ale_fortran_gcc_use_free_form *g:ale_fortran_gcc_use_free_form* + *b:ale_fortran_gcc_use_free_form* + Type: |Number| + Default: `1` + + When set to `1`, the `-ffree-form` flag will be used for GCC, to check files + with the free form layout. When set to `0`, `-ffixed-form` will be used + instead, for checking files with fixed form layouts. + + +=============================================================================== +language_server *ale-fortran-language-server* + +g:ale_fortran_language_server_executable *g:ale_fortran_language_server_executable* + *b:ale_fortran_language_server_executable* + Type: |String| + Default: `'fortls'` + + This variable can be changed to modify the executable used for the Fortran + Language Server. + +g:ale_fortran_language_server_use_global *g:ale_fortran_language_server_use_global* + *b:ale_fortran_language_server_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-fountain.txt b/pack/acp/start/ale/doc/ale-fountain.txt new file mode 100644 index 0000000..ac0870c --- /dev/null +++ b/pack/acp/start/ale/doc/ale-fountain.txt @@ -0,0 +1,6 @@ +=============================================================================== +ALE Fountain Integration *ale-fountain-options* + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-fuse.txt b/pack/acp/start/ale/doc/ale-fuse.txt new file mode 100644 index 0000000..0849c37 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-fuse.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE FusionScript Integration *ale-fuse-options* + + +=============================================================================== +fusion-lint *ale-fuse-fusionlint* + +g:ale_fusion_fusionlint_executable *g:ale_fuse_fusionlint_executable* + *b:ale_fuse_fusionlint_executable* + Type: |String| + Default: `'fusion-lint'` + + This variable can be changed to change the path to fusion-lint. + + +g:ale_fuse_fusionlint_options *g:ale_fuse_fusionlint_options* + *b:ale_fuse_fusionlint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to fusion-lint. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-gitcommit.txt b/pack/acp/start/ale/doc/ale-gitcommit.txt new file mode 100644 index 0000000..38f3fd9 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-gitcommit.txt @@ -0,0 +1,44 @@ +=============================================================================== +ALE Git Commit Integration *ale-gitcommit-options* + + +=============================================================================== +gitlint *ale-gitcommit-gitlint* + +g:ale_gitcommit_gitlint_executable *g:ale_gitcommit_gitlint_executable* + *b:ale_gitcommit_gitlint_executable* + Type: |String| + Default: `'gitlint'` + + This variable can be changed to modify the executable used for gitlint. + + +g:ale_gitcommit_gitlint_options *g:ale_gitcommit_gitlint_options* + *b:ale_gitcommit_gitlint_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the gitlint + invocation. For example, you can specify the path to a configuration file. > + + let g:ale_gitcommit_gitlint_options = '-C /home/user/.config/gitlint.ini' +< + You can also disable particular error codes using this option. For example, + you can ignore errors for git commits with a missing body. > + + let g:ale_gitcommit_gitlint_options = '--ignore B6' +< + +g:ale_gitcommit_gitlint_use_global *g:ale_gitcommit_gitlint_use_global* + *b:ale_gitcommit_gitlint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable controls whether or not ALE will search for gitlint in a + virtualenv directory first. If this variable is set to `1`, then ALE will + always use |g:ale_gitcommit_gitlint_executable| for the executable path. + + Both variables can be set with `b:` buffer variables instead. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-glsl.txt b/pack/acp/start/ale/doc/ale-glsl.txt new file mode 100644 index 0000000..257de75 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-glsl.txt @@ -0,0 +1,56 @@ +=============================================================================== +ALE GLSL Integration *ale-glsl-options* + *ale-integration-glsl* + +=============================================================================== +Integration Information + + Since Vim does not detect the glsl file types out-of-the-box, you need the + runtime files for glsl from here: https://github.com/tikhomirov/vim-glsl + + Note that the current glslang-based linter expects glslangValidator in + standard paths. If it's not installed system-wide you can set + |g:ale_glsl_glslang_executable| to a specific path. + + +=============================================================================== +glslang *ale-glsl-glslang* + +g:ale_glsl_glslang_executable *g:ale_glsl_glslang_executable* + *b:ale_glsl_glslang_executable* + Type: |String| + Default: `'glslangValidator'` + + This variable can be changed to change the path to glslangValidator. + + +g:ale_glsl_glslang_options *g:ale_glsl_glslang_options* + *b:ale_glsl_glslang_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to glslangValidator. + + +=============================================================================== +glslls *ale-glsl-glslls* + +g:ale_glsl_glslls_executable *g:ale_glsl_glslls_executable* + *b:ale_glsl_glslls_executable* + Type: |String| + Default: `'glslls'` + + This variable can be changed to change the path to glslls. + See |ale-integrations-local-executables| + +g:ale_glsl_glslls_logfile *g:ale_glsl_glslls_logfile* + *b:ale_glsl_glslls_logfile* + Type: |String| + Default: `''` + + Setting this variable to a writeable file path will enable logging to that + file. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-go.txt b/pack/acp/start/ale/doc/ale-go.txt new file mode 100644 index 0000000..611e3fd --- /dev/null +++ b/pack/acp/start/ale/doc/ale-go.txt @@ -0,0 +1,234 @@ +=============================================================================== +ALE Go Integration *ale-go-options* + + +=============================================================================== +Integration Information + +The `gometalinter` linter is disabled by default. ALE enables `gofmt`, +`golint` and `go vet` by default. It also supports `staticcheck`, `go +build`, `gosimple`, `golangserver`. + +To enable `gometalinter`, update |g:ale_linters| as appropriate: +> + " Enable all of the linters you want for Go. + let g:ale_linters = {'go': ['gometalinter', 'gofmt']} +< +A possible configuration is to enable `gometalinter` and `gofmt` but paired +with the `--fast` option, set by |g:ale_go_gometalinter_options|. This gets you +the benefit of running a number of linters, more than ALE would by default, +while ensuring it doesn't run any linters known to be slow or resource +intensive. + +g:ale_go_go_executable *g:ale_go_go_options* + *b:ale_go_go_options* + + Type: |String| + Default: `'go'` + + The executable that will be run for the `gobuild` and `govet` linters, and + the `gomod` fixer. + + +=============================================================================== +bingo *ale-go-bingo* + +g:ale_go_bingo_executable *g:ale_go_bingo_executable* + *b:ale_go_bingo_executable* + Type: |String| + Default: `'bingo'` + + Location of the bingo binary file. + + +g:ale_go_bingo_options *g:ale_go_bingo_options* + *b:ale_go_bingo_options* + Type: |String| + Default: `''` + + +=============================================================================== +gobuild *ale-go-gobuild* + +g:ale_go_gobuild_options *g:ale_go_gobuild_options* + *b:ale_go_gobuild_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the gobuild linter. + They are injected directly after "go test". + + +=============================================================================== +gofmt *ale-go-gofmt* + +g:ale_go_gofmt_options *g:ale_go_gofmt_options* + *b:ale_go_gofmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the gofmt fixer. + + +=============================================================================== +golangci-lint *ale-go-golangci-lint* + +`golangci-lint` is a `lint_file` linter, which only lints files that are +written to disk. This differs from the default behavior of linting the buffer. +See: |ale-lint-file| + +g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable* + *b:ale_go_golangci_lint_executable* + Type: |String| + Default: `'golangci-lint'` + + The executable that will be run for golangci-lint. + + +g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options* + *b:ale_go_golangci_lint_options* + Type: |String| + Default: `'--enable-all'` + + This variable can be changed to alter the command-line arguments to the + golangci-lint invocation. + + +g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package* + *b:ale_go_golangci_lint_package* + Type: |Number| + Default: `0` + + When set to `1`, the whole Go package will be checked instead of only the + current file. + + +=============================================================================== +golangserver *ale-go-golangserver* + +g:ale_go_langserver_executable *g:ale_go_langserver_executable* + *b:ale_go_langserver_executable* + Type: |String| + Default: `'go-langserver'` + + Location of the go-langserver binary file. + + +g:ale_go_langserver_options *g:ale_go_langserver_options* + *b:ale_go_langserver_options* + Type: |String| + Default: `''` + + Additional options passed to the go-langserver command. Note that the + `-gocodecompletion` option is ignored because it is handled automatically + by the |g:ale_completion_enabled| variable. + + +=============================================================================== +golint *ale-go-golint* + +g:ale_go_golint_executable *g:ale_go_golint_executable* + *b:ale_go_golint_executable* + Type: |String| + Default: `'golint'` + + This variable can be set to change the golint executable path. + + +g:ale_go_golint_options *g:ale_go_golint_options* + *b:ale_go_golint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the golint linter. + + +=============================================================================== +gometalinter *ale-go-gometalinter* + +`gometalinter` is a `lint_file` linter, which only lints files that are +written to disk. This differs from the default behavior of linting the buffer. +See: |ale-lint-file| + +g:ale_go_gometalinter_executable *g:ale_go_gometalinter_executable* + *b:ale_go_gometalinter_executable* + Type: |String| + Default: `'gometalinter'` + + The executable that will be run for gometalinter. + + +g:ale_go_gometalinter_options *g:ale_go_gometalinter_options* + *b:ale_go_gometalinter_options* + Type: |String| + Default: `''` + + This variable can be changed to alter the command-line arguments to the + gometalinter invocation. + + Since `gometalinter` runs a number of linters that can consume a lot of + resources it's recommended to set this option to a value of `--fast` if you + use `gometalinter` as one of the linters in |g:ale_linters|. This disables a + number of linters known to be slow or consume a lot of resources. + + +g:ale_go_gometalinter_lint_package *g:ale_go_gometalinter_lint_package* + *b:ale_go_gometalinter_lint_package* + Type: |Number| + Default: `0` + + When set to `1`, the whole Go package will be checked instead of only the + current file. + + +=============================================================================== +gopls *ale-go-gopls* + +g:ale_go_gopls_executable *g:ale_go_gopls_executable* + *b:ale_go_gopls_executable* + Type: |String| + Default: `'gopls'` + + Location of the gopls binary file. + + +g:ale_go_gopls_options *g:ale_go_gopls_options* + *b:ale_go_gopls_options* + Type: |String| + Default: `''` + + +=============================================================================== +govet *ale-go-govet* + +g:ale_go_govet_options *g:ale_go_govet_options* + *b:ale_go_govet_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the go vet linter. + + +=============================================================================== +staticcheck *ale-go-staticcheck* + +g:ale_go_staticcheck_options *g:ale_go_staticcheck_options* + *b:ale_go_staticcheck_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the staticcheck + linter. + + +g:ale_go_staticcheck_lint_package *g:ale_go_staticcheck_lint_package* + *b:ale_go_staticcheck_lint_package* + Type: |Number| + Default: `0` + + When set to `1`, the whole Go package will be checked instead of only the + current file. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-graphql.txt b/pack/acp/start/ale/doc/ale-graphql.txt new file mode 100644 index 0000000..603694b --- /dev/null +++ b/pack/acp/start/ale/doc/ale-graphql.txt @@ -0,0 +1,22 @@ +=============================================================================== +ALE GraphQL Integration *ale-graphql-options* + + +=============================================================================== +eslint *ale-graphql-eslint* + +The `eslint` linter for GraphQL uses the JavaScript options for `eslint`; see: +|ale-javascript-eslint|. + +You will need the GraphQL ESLint plugin installed for this to work. + +=============================================================================== +gqlint *ale-graphql-gqlint* + +=============================================================================== +prettier *ale-graphql-prettier* + +See |ale-javascript-prettier| for information about the available options. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-hack.txt b/pack/acp/start/ale/doc/ale-hack.txt new file mode 100644 index 0000000..4776b8c --- /dev/null +++ b/pack/acp/start/ale/doc/ale-hack.txt @@ -0,0 +1,51 @@ +=============================================================================== +ALE Hack Integration *ale-hack-options* + *ale-integration-hack* + + HHAST is disabled by default, as it executes code in the project root. + + Currently linters must be enabled globally. HHAST can be enabled with: + +> + let g:ale_linters = {'hack': ['hack', 'hhast']} +< + +=============================================================================== +hack *ale-hack-hack* + +g:ale_hack_hack_executable *g:ale_hack_hack_executable* + *b:ale_hack_hack_executable* + + Type: |String| + Default: `'hh_client'` + + This variable can be set to use a specific executable to interact with the + Hack typechecker. + + +=============================================================================== +hackfmt *ale-hack-hackfmt* + +g:ale_hack_hackfmt_options *g:ale_hack_hackfmt_options* + *b:ale_hack_hackfmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the hackfmt fixer. + + +=============================================================================== +hhast *ale-hack-hhast* + +g:ale_hack_hhast_executable *g:ale_hack_hhast_executable* + *b:ale_hack_hhast_executable* + + Type: |String| + Default: `'vendor/bin/hhast-lint'` + + This variable can be set to use a specific executable to interact with the + Hack typechecker. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-handlebars.txt b/pack/acp/start/ale/doc/ale-handlebars.txt new file mode 100644 index 0000000..061c5d3 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-handlebars.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE Handlebars Integration *ale-handlebars-options* + + +=============================================================================== +ember-template-lint *ale-handlebars-embertemplatelint* + +g:ale_handlebars_embertemplatelint_executable + *g:ale_handlebars_embertemplatelint_executable* + Type: |String| *b:ale_handlebars_embertemplatelint_executable* + Default: `'ember-template-lint'` + + See |ale-integrations-local-executables| + + +g:ale_handlebars_embertemplatelint_use_global + *g:ale_handlebars_embertemplatelint_use_global* + Type: |Number| *b:ale_handlebars_embertemplatelint_use_global* + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-haskell.txt b/pack/acp/start/ale/doc/ale-haskell.txt new file mode 100644 index 0000000..e2073e3 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-haskell.txt @@ -0,0 +1,154 @@ +=============================================================================== +ALE Haskell Integration *ale-haskell-options* + + +=============================================================================== +brittany *ale-haskell-brittany* + +g:ale_haskell_brittany_executable *g:ale_haskell_brittany_executable* + *b:ale_haskell_brittany_executable* + Type: |String| + Default: `'brittany'` + + This variable can be changed to use a different executable for brittany. + +=============================================================================== +floskell *ale-haskell-floskell* + +g:ale_haskell_floskell_executable *g:ale_haskell_floskell_executable* + *b:ale_haskell_floskell_executable* + Type: |String| + Default: `'floskell'` + + This variable can be changed to use a different executable for floskell. + +=============================================================================== +ghc *ale-haskell-ghc* + +g:ale_haskell_ghc_options *g:ale_haskell_ghc_options* + *b:ale_haskell_ghc_options* + Type: |String| + Default: `'-fno-code -v0'` + + This variable can be changed to modify flags given to ghc. + +=============================================================================== +ghc-mod *ale-haskell-ghc-mod* + +g:ale_haskell_ghc_mod_executable *g:ale_haskell_ghc_mod_executable* + *b:ale_haskell_ghc_mod_executable* + Type: |String| + Default: `'ghc-mod'` + + This variable can be changed to use a different executable for ghc-mod. + +=============================================================================== +cabal-ghc *ale-haskell-cabal-ghc* + +g:ale_haskell_cabal_ghc_options *g:ale_haskell_cabal_ghc_options* + *b:ale_haskell_cabal_ghc_options* + Type: |String| + Default: `'-fno-code -v0'` + + This variable can be changed to modify flags given to ghc through cabal + exec. + +=============================================================================== +hdevtools *ale-haskell-hdevtools* + +g:ale_haskell_hdevtools_executable *g:ale_haskell_hdevtools_executable* + *b:ale_haskell_hdevtools_executable* + Type: |String| + Default: `'hdevtools'` + + This variable can be changed to use a different executable for hdevtools. + + +g:ale_haskell_hdevtools_options *g:ale_haskell_hdevtools_options* + *b:ale_haskell_hdevtools_options* + Type: |String| + Default: `get(g:, 'hdevtools_options', '-g -Wall')` + + This variable can be changed to modify flags given to hdevtools. + + The hdevtools documentation recommends setting GHC options for `hdevtools` + with `g:hdevtools_options`. ALE will use the value of `g:hdevtools_options` + for the value of `g:ale_haskell_hdevtools_options` by default, so this + option can be respected and overridden specifically for ALE. + + +=============================================================================== +hfmt *ale-haskell-hfmt* + +g:ale_haskell_hfmt_executable *g:ale_haskell_hfmt_executable* + *b:ale_haskell_hfmt_executable* + Type: |String| + Default: `'hfmt'` + + This variable can be changed to use a different executable for hfmt. + +=============================================================================== +hlint *ale-haskell-hlint* + +g:ale_haskell_hlint_executable *g:ale_haskell_hlint_executable* + *b:ale_haskell_hlint_executable* + Type: |String| + Default: `'hlint'` + + This variable can be changed to use a different executable for hlint. + + +g:ale_haskell_hlint_options g:ale_haskell_hlint_options + b:ale_haskell_hlint_options + Type: String + Default: '' + + This variable can be used to pass extra options to the underlying hlint + executable. + +=============================================================================== +stack-build *ale-haskell-stack-build* + +g:ale_haskell_stack_build_options *g:ale_haskell_stack_build_options* + *b:ale_haskell_stack_build_options* + Type: |String| + Default: `'--fast'` + + We default to using `'--fast'`. Since Stack generates binaries, your + programs will be slower unless you separately rebuild them outside of ALE. + +=============================================================================== +stack-ghc *ale-haskell-stack-ghc* + +g:ale_haskell_stack_ghc_options *g:ale_haskell_stack_ghc_options* + *b:ale_haskell_stack_ghc_options* + Type: |String| + Default: `'-fno-code -v0'` + + This variable can be changed to modify flags given to ghc through `stack + ghc` + +=============================================================================== +stylish-haskell *ale-haskell-stylish-haskell* + +g:ale_haskell_stylish_haskell_executable + *g:ale_haskell_stylish_haskell_executable* + *b:ale_haskell_stylish_haskell_executable* + Type: |String| + Default: `'stylish-haskell'` + + This variable can be changed to use a different executable for stylish-haskell. + +=============================================================================== +hie *ale-haskell-hie* + +g:ale_haskell_hie_executable *g:ale_haskell_hie_executable* + *b:ale_haskell_hie_executable* + Type: |String| + Default: `'hie'` + + This variable can be changed to use a different executable for the haskell + ide engine. i.e. `'hie-wrapper'` + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-hcl.txt b/pack/acp/start/ale/doc/ale-hcl.txt new file mode 100644 index 0000000..59b0a9d --- /dev/null +++ b/pack/acp/start/ale/doc/ale-hcl.txt @@ -0,0 +1,11 @@ +=============================================================================== +ALE HCL Integration *ale-hcl-options* + + +=============================================================================== +terraform-fmt *ale-hcl-terraform-fmt* + +See |ale-terraform-fmt-fixer| for information about the available options. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-html.txt b/pack/acp/start/ale/doc/ale-html.txt new file mode 100644 index 0000000..5d6b20e --- /dev/null +++ b/pack/acp/start/ale/doc/ale-html.txt @@ -0,0 +1,130 @@ +=============================================================================== +ALE HTML Integration *ale-html-options* + + +=============================================================================== +fecs *ale-html-fecs* + +`fecs` options for HTMl is the same as the options for JavaScript, +and both of them reads `./.fecsrc` as the default configuration file. +See: |ale-javascript-fecs|. + + +=============================================================================== +htmlhint *ale-html-htmlhint* + +g:ale_html_htmlhint_executable *g:ale_html_htmlhint_executable* + *b:ale_html_htmlhint_executable* + Type: |String| + Default: `'htmlhint'` + + See |ale-integrations-local-executables| + + +g:ale_html_htmlhint_options *g:ale_html_htmlhint_options* + *b:ale_html_htmlhint_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to HTMLHint. + + +g:ale_html_htmlhint_use_global *g:ale_html_htmlhint_use_global* + *b:ale_html_htmlhint_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +tidy *ale-html-tidy* + +`tidy` is a console application which corrects and cleans up HTML and XML +documents by fixing markup errors and upgrading legacy code to modern +standards. + +Note: +`/usr/bin/tidy` on macOS (installed by default) is too old. It was released +on 31 Oct 2006. It does not consider modern HTML specs (HTML5) and shows +outdated warnings. So |ale| ignores `/usr/bin/tidy` on macOS. + +To use `tidy` on macOS, please install the latest version with Homebrew: +> + $ brew install tidy-html5 +< +`/usr/local/bin/tidy` is installed. + +g:ale_html_tidy_executable *g:ale_html_tidy_executable* + *b:ale_html_tidy_executable* + Type: |String| + Default: `'tidy'` + + This variable can be changed to change the path to tidy. + + +g:ale_html_tidy_options *g:ale_html_tidy_options* + *b:ale_html_tidy_options* + Type: |String| + Default: `'-q -e -language en'` + + This variable can be changed to change the arguments provided to the + executable. + + ALE will attempt to automatically detect the appropriate file encoding to + provide to html-tidy, and fall back to UTF-8 when encoding detection fails. + + The recognized file encodings are as follows: ascii, big5, cp1252 (win1252), + cp850 (ibm858), cp932 (shiftjis), iso-2022-jp (iso-2022), latin1, macroman + (mac), sjis (shiftjis), utf-16le, utf-16, utf-8 + + +g:ale_html_tidy_use_global *g:html_tidy_use_global* + + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +prettier *ale-html-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +stylelint *ale-html-stylelint* + +g:ale_html_stylelint_executable *g:ale_html_stylelint_executable* + *b:ale_html_stylelint_executable* + Type: |String| + Default: `'stylelint'` + + See |ale-integrations-local-executables| + + +g:ale_html_stylelint_options *g:ale_html_stylelint_options* + *b:ale_html_stylelint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to stylelint. + + +g:ale_html_stylelint_use_global *g:ale_html_stylelint_use_global* + *b:ale_html_stylelint_use_global* + Type: |String| + Default: `0` + + See |ale-integrations-local-executables| + + +=============================================================================== +write-good *ale-html-write-good* + +See |ale-write-good-options| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-idris.txt b/pack/acp/start/ale/doc/ale-idris.txt new file mode 100644 index 0000000..c7500b0 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-idris.txt @@ -0,0 +1,23 @@ +=============================================================================== +ALE Idris Integration *ale-idris-options* + +=============================================================================== +idris *ale-idris-idris* + +g:ale_idris_idris_executable *g:ale_idris_idris_executable* + *b:ale_idris_idris_executable* + Type: |String| + Default: `'idris'` + + This variable can be changed to change the path to idris. + + +g:ale_idris_idris_options *g:ale_idris_idris_options* + *b:ale_idris_idris_options* + Type: |String| + Default: `'--total --warnpartial --warnreach --warnipkg'` + + This variable can be changed to modify flags given to idris. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-ispc.txt b/pack/acp/start/ale/doc/ale-ispc.txt new file mode 100644 index 0000000..bf30e8e --- /dev/null +++ b/pack/acp/start/ale/doc/ale-ispc.txt @@ -0,0 +1,24 @@ +=============================================================================== +ALE ISPC Integration *ale-ispc-options* + + +=============================================================================== +ispc *ale-ispc-ispc* + +g:ale_ispc_ispc_executable *g:ale_ispc_ispc_executable* + *b:ale_ispc_ispc_executable* + Type: |String| + Default: `'ispc'` + + This variable can be changed to use a different executable for ispc. + + +g:ale_ispc_ispc_options *g:ale_ispc_ispc_options* + *b:ale_ispc_ispc_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to ispc. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-java.txt b/pack/acp/start/ale/doc/ale-java.txt new file mode 100644 index 0000000..a563f1f --- /dev/null +++ b/pack/acp/start/ale/doc/ale-java.txt @@ -0,0 +1,206 @@ +=============================================================================== +ALE Java Integration *ale-java-options* + + +=============================================================================== +checkstyle *ale-java-checkstyle* + +g:ale_java_checkstyle_config *g:ale_java_checkstyle_config* + *b:ale_java_checkstyle_config* + + Type: |String| + Default: `'google_checks.xml'` + + A path to a checkstyle configuration file. + + If a configuration file is specified with |g:ale_java_checkstyle_options|, + it will be preferred over this setting. + + The path to the configuration file can be an absolute path or a relative + path. ALE will search for the relative path in parent directories. + + +g:ale_java_checkstyle_executable *g:ale_java_checkstyle_executable* + *b:ale_java_checkstyle_executable* + + Type: |String| + Default: 'checkstyle' + + This variable can be changed to modify the executable used for checkstyle. + + +g:ale_java_checkstyle_options *g:ale_java_checkstyle_options* + *b:ale_java_checkstyle_options* + + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to checkstyle. + + If a configuration file is specified with `-c`, it will be used instead of + configuration files set with |g:ale_java_checkstyle_config|. + + +=============================================================================== +javac *ale-java-javac* + +g:ale_java_javac_classpath *g:ale_java_javac_classpath* + *b:ale_java_javac_classpath* + Type: |String| + Default: `''` + + This variable can be set to change the global classpath for Java. + + +g:ale_java_javac_executable *g:ale_java_javac_executable* + *b:ale_java_javac_executable* + Type: |String| + Default: `'javac'` + + This variable can be set to change the executable path used for javac. + + +g:ale_java_javac_options *g:ale_java_javac_options* + *b:ale_java_javac_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to javac. + + +=============================================================================== +google-java-format *ale-java-google-java-format* + + +g:ale_java_google_java_format_executable + *g:ale_java_google_java_format_executable* + *b:ale_java_google_java_format_executable* + Type: |String| + Default: `'google-java-format'` + + See |ale-integrations-local-executables| + + +g:ale_java_google_java_format_options *g:ale_java_google_java_format_options* + *b:ale_java_google_java_format_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options + + +=============================================================================== +pmd *ale-java-pmd* + +g:ale_java_pmd_options *g:ale_java_pmd_options* + *b:ale_java_pmd_options* + + Type: String + Default: '-R category/java/bestpractices' + + This variable can be changed to modify flags given to PMD. Do not specify -f + and -d. They are added automatically. + + +=============================================================================== +javalsp *ale-java-javalsp* + +To enable Java LSP linter you need to download and build the vscode-javac +language server from https://github.com/georgewfraser/java-language-server. +Simply download the source code and then build a distribution: + + scripts/link_mac.sh + +or + + scripts/link_windows.sh + +This generates a dist/mac or dist/windows directory that contains the +language server. To let ALE use this language server you need to set the +g:ale_java_javalsp_executable variable to the absolute path of the launcher +executable in this directory. + +g:ale_java_javalsp_executable *g:ale_java_javalsp_executable* + *b:ale_java_javalsp_executable* + Type: |String| + Default: `'launcher'` + +This variable must be set to the absolute path of the language server launcher +executable. For example: +> + let g:ale_java_javalsp_executable=/java-language-server/dist/mac/bin/launcher +< + +=============================================================================== +eclipselsp *ale-java-eclipselsp* + +To enable Eclipse LSP linter you need to clone and build the eclipse.jdt.ls +language server from https://github.com/eclipse/eclipse.jdt.ls. Simply +clone the source code repo and then build the plugin: + + ./mvnw clean verify + +Note: currently, the build can only run when launched with JDK 8. JDK 9 or more +recent versions can be used to run the server though. + +After build completes the files required to run the language server will be +located inside the repository folder `eclipse.jdt.ls`. Please ensure to set +|g:ale_java_eclipselsp_path| to the absolute path of that folder. + +You could customize compiler options and code assists of the server. +Under your project folder, modify the file `.settings/org.eclipse.jdt.core.prefs` +with options presented at +https://help.eclipse.org/neon/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/JavaCore.html. + +g:ale_java_eclipselsp_path *g:ale_java_eclipselsp_path* + *b:ale_java_eclipselsp_path* + + Type: |String| + Default: `'$HOME/eclipse.jdt.ls'` + + Absolute path to the location of the eclipse.jdt.ls repository folder. Or if + you have VSCode extension installed the absolute path to the VSCode extensions + folder (e.g. $HOME/.vscode/extensions/redhat.java-0.4x.0 in Linux). + + +g:ale_java_eclipselsp_executable *g:ale_java_eclipse_executable* + *b:ale_java_eclipse_executable* + Type: |String| + Default: `'java'` + + This variable can be set to change the executable path used for java. + + +g:ale_java_eclipselsp_config_path *g:ale_java_eclipse_config_path* + *b:ale_java_eclipse_config_path* + Type: |String| + Default: `''` + + Set this variable to change the configuration directory path used by + eclipselsp (e.g. `$HOME/.jdtls` in Linux). + By default ALE will attempt to use the configuration within the installation + directory. + This setting is particularly useful when eclipselsp is installed in a + non-writable directory like `/usr/share/java/jdtls`, as is the case when + installed via system package. + + +g:ale_java_eclipselsp_workspace_path *g:ale_java_eclipselsp_workspace_path* + *b:ale_java_eclipselsp_workspace_path* + + Type: |String| + Default: `''` + + If you have Eclipse installed is good idea to set this variable to the + absolute path of the Eclipse workspace. If not set this value will be set to + the parent folder of the project root. + + +=============================================================================== +uncrustify *ale-java-uncrustify* + +See |ale-c-uncrustify| for information about the available options. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-javascript.txt b/pack/acp/start/ale/doc/ale-javascript.txt new file mode 100644 index 0000000..ea0a708 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-javascript.txt @@ -0,0 +1,336 @@ +=============================================================================== +ALE JavaScript Integration *ale-javascript-options* + + *ale-eslint-nested-configuration-files* + +For fixing files with ESLint, nested configuration files with `root: false` +are not supported. This is because ALE fixes files by writing the contents of +buffers to temporary files, and then explicitly sets the configuration file. +Configuration files which are set explicitly must be root configuration files. +If you are using nested configuration files, you should restructure your +project so your configuration files use `extends` instead. + +See the ESLint documentation here: +http://eslint.org/docs/user-guide/configuring#extending-configuration-files + +You should change the structure of your project from this: > + /path/foo/.eslintrc.js # root: true + /path/foo/bar/.eslintrc.js # root: false +< +To this: > + /path/foo/.base-eslintrc.js # Base configuration here + /path/foo/.eslintrc.js # extends: ["/path/foo/.base-eslintrc.js"] + /path/foo/bar/.eslintrc.js # extends: ["/path/foo/.base-eslintrc.js"] +< + +=============================================================================== +eslint *ale-javascript-eslint* + +g:ale_javascript_eslint_executable *g:ale_javascript_eslint_executable* + *b:ale_javascript_eslint_executable* + Type: |String| + Default: `'eslint'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_eslint_options *g:ale_javascript_eslint_options* + *b:ale_javascript_eslint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to eslint. + + +g:ale_javascript_eslint_use_global *g:ale_javascript_eslint_use_global* + *b:ale_javascript_eslint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_javascript_eslint_suppress_eslintignore + *g:ale_javascript_eslint_suppress_eslintignore* + *b:ale_javascript_eslint_suppress_eslintignore* + Type: |Number| + Default: `0` + + This variable can be set to `1` to disable warnings for files being ignored + by eslint. + + +g:ale_javascript_eslint_suppress_missing_config + *g:ale_javascript_eslint_suppress_missing_config* + *b:ale_javascript_eslint_suppress_missing_config* + Type: |Number| + Default: `0` + + This variable can be set to `1` to disable errors for missing eslint + configuration files. + + When turning this option on, eslint will not report any problems when no + configuration files are found. + + +=============================================================================== +fecs *ale-javascript-fecs* + +`fecs` is a lint tool for HTML/CSS/JavaScript, can be installed via: + + `$ npm install --save-dev fecs` + +And the configuration file is located at `./fecsrc`, see http://fecs.baidu.com +for more options. + + +g:ale_javascript_fecs_executable *g:ale_javascript_fecs_executable* + *b:ale_javascript_fecs_executable* + Type: |String| + Default: `'fecs'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_fecs_use_global *g:ale_javascript_fecs_use_global* + *b:ale_javascript_fecs_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +flow *ale-javascript-flow* + +g:ale_javascript_flow_executable *g:ale_javascript_flow_executable* + *b:ale_javascript_flow_executable* + Type: |String| + Default: `'flow'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_flow_use_home_config *g:ale_javascript_flow_use_home_config* + *b:ale_javascript_flow_use_home_config* + Type: |Number| + Default: `0` + + When set to `1`, ALE will allow Flow to be executed with configuration files + from your home directory. ALE will not run Flow with home directory + configuration files by default, as doing so can lead to Vim consuming all of + your RAM and CPU power. + + +g:ale_javascript_flow_use_global *g:ale_javascript_flow_use_global* + *b:ale_javascript_flow_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_javascript_flow_use_respect_pragma + *g:ale_javascript_flow_use_respect_pragma* + *b:ale_javascript_flow_use_respect_pragma* + Type: |Number| + Default: `1` + + By default, ALE will use the `--respect-pragma` option for `flow`, so only + files with the `@flow` pragma are checked by ALE. This option can be set to + `0` to disable that behaviour, so all files can be checked by `flow`. + + +=============================================================================== +importjs *ale-javascript-importjs* + +g:ale_javascript_importjs_executable *g:ale_javascript_importjs_executable* + *b:ale_javascript_importjs_executable* + Type: |String| + Default: `'importjs'` + + +=============================================================================== +jscs *ale-javascript-jscs* + +g:ale_javascript_jscs_executable *g:ale_javascript_jscs_executable* + *b:ale_javascript_jscs_executable* + Type: |String| + Default: `'jscs'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_jscs_use_global *g:ale_javascript_jscs_use_global* + *b:ale_javascript_jscs_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +jshint *ale-javascript-jshint* + +g:ale_javascript_jshint_executable *g:ale_javascript_jshint_executable* + *b:ale_javascript_jshint_executable* + Type: |String| + Default: `'jshint'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_jshint_use_global *g:ale_javascript_jshint_use_global* + *b:ale_javascript_jshint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +prettier *ale-javascript-prettier* + +g:ale_javascript_prettier_executable *g:ale_javascript_prettier_executable* + *b:ale_javascript_prettier_executable* + Type: |String| + Default: `'prettier'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_prettier_options *g:ale_javascript_prettier_options* + *b:ale_javascript_prettier_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to prettier. + + +g:ale_javascript_prettier_use_global *g:ale_javascript_prettier_use_global* + *b:ale_javascript_prettier_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +prettier-eslint *ale-javascript-prettier-eslint* + +g:ale_javascript_prettier_eslint_executable + *g:ale_javascript_prettier_eslint_executable* + *b:ale_javascript_prettier_eslint_executable* + Type: |String| + Default: `'prettier-eslint'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_prettier_eslint_options + *g:ale_javascript_prettier_eslint_options* + *b:ale_javascript_prettier_eslint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to prettier-eslint. + + +g:ale_javascript_prettier_eslint_use_global + *g:ale_javascript_prettier_eslint_use_global* + *b:ale_javascript_prettier_eslint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +prettier-standard *ale-javascript-prettier-standard* + + +g:ale_javascript_prettier_standard_executable + *g:ale_javascript_prettier_standard_executable* + *b:ale_javascript_prettier_standard_executable* + Type: |String| + Default: `'prettier-standard'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_prettier_standard_options + *g:ale_javascript_prettier_standard_options* + *b:ale_javascript_prettier_standard_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to prettier-standard. + + +g:ale_javascript_prettier_standard_use_global + *g:ale_javascript_prettier_standard_use_global* + *b:ale_javascript_prettier_standard_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + + + +=============================================================================== +standard *ale-javascript-standard* + +g:ale_javascript_standard_executable *g:ale_javascript_standard_executable* + *b:ale_javascript_standard_executable* + Type: |String| + Default: `'standard'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_standard_options *g:ale_javascript_standard_options* + *b:ale_javascript_standard_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to standard. + + +g:ale_javascript_standard_use_global *g:ale_javascript_standard_use_global* + *b:ale_javascript_standard_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +xo *ale-javascript-xo* + +g:ale_javascript_xo_executable *g:ale_javascript_xo_executable* + *b:ale_javascript_xo_executable* + Type: |String| + Default: `'xo'` + + See |ale-integrations-local-executables| + + +g:ale_javascript_xo_options *g:ale_javascript_xo_options* + *b:ale_javascript_xo_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to xo. + + +g:ale_javascript_xo_use_global *g:ale_javascript_xo_use_global* + *b:ale_javascript_xo_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-json.txt b/pack/acp/start/ale/doc/ale-json.txt new file mode 100644 index 0000000..96499a0 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-json.txt @@ -0,0 +1,105 @@ +=============================================================================== +ALE JSON Integration *ale-json-options* + + +=============================================================================== +fixjson *ale-json-fixjson* + +fixjson is a JSON file fixer/formatter for humans using (relaxed) JSON5. +It provides: + +- Pretty-prints JSON input +- Fixes various failures while humans writing JSON + - Fixes trailing commas objects or arrays + - Fixes missing commas for elements of objects or arrays + - Adds quotes to keys in objects + - Newlines in strings + - Hex numbers + - Fixes single quotes to double quotes + +You can install it using npm: +> + $ npm install -g fixjson +< +ALE provides fixjson integration as a fixer. See |ale-fix|. + +g:ale_json_fixjson_executable *g:ale_json_fixjson_executable* + *b:ale_json_fixjson_executable* + + Type: |String| + Default: `'fixjson'` + + The executable that will be run for fixjson. + +g:ale_json_fixjson_options *g:ale_json_fixjson_options* + *b:ale_json_fixjson_options* + + Type: |String| + Default: `''` + + This variable can add extra options to the command executed for running + fixjson. + +g:ale_json_fixjson_use_global *g:ale_json_fixjson_use_global* + *b:ale_json_fixjson_use_global* + + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +jsonlint *ale-json-jsonlint* + +g:ale_json_jsonlint_executable *g:ale_json_jsonlint_executable* + *b:ale_json_jsonlint_executable* + + Type: |String| + Default: `'jsonlint'` + + The executable that will be run for jsonlint. + +g:ale_json_jsonlint_use_global *g:ale_json_jsonlint_use_global* + *b:ale_json_jsonlint_use_global* + + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +jq *ale-json-jq* + +g:ale_json_jq_executable *g:ale_json_jq_executable* + *b:ale_json_jq_executable* + Type: |String| + Default: `'jq'` + + This option can be changed to change the path for `jq`. + + +g:ale_json_jq_options *g:ale_json_jq_options* + *b:ale_json_jq_options* + Type: |String| + Default: `''` + + This option can be changed to pass extra options to `jq`. + +g:ale_json_jq_filters *g:ale_json_jq_filters* + *b:ale_json_jq_filters* + Type: |String| + Default: `'.'` + + This option can be changed to pass custom filters to `jq`. + + +=============================================================================== +prettier *ale-json-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-julia.txt b/pack/acp/start/ale/doc/ale-julia.txt new file mode 100644 index 0000000..5153241 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-julia.txt @@ -0,0 +1,20 @@ +=============================================================================== +ALE Julia Integration *ale-julia-options* + +=============================================================================== +languageserver *ale-julia-languageserver* + +To enable Julia LSP linter you need to install the LanguageServer.jl package +within julia. + +g:ale_julia_executable *g:ale_julia_executable* + *b:ale_julia_executable* + + Type: |String| + Default: 'julia' + + Path to the julia exetuable. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/pack/acp/start/ale/doc/ale-kotlin.txt b/pack/acp/start/ale/doc/ale-kotlin.txt new file mode 100644 index 0000000..4028531 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-kotlin.txt @@ -0,0 +1,113 @@ +=============================================================================== +ALE Kotlin Integration *ale-kotlin-options* + *ale-integration-kotlin* + +=============================================================================== +Integration Information + + Make sure your setup has support for the kotlin file type. A filetype plugin + can be found here: https://github.com/udalov/kotlin-vim + + + Note: Make sure you have a working kotlin compiler + + +=============================================================================== +kotlinc *ale-kotlin-kotlinc* + +g:ale_kotlin_kotlinc_options *g:ale_kotlin_kotlinc_options* + Type: |String| + Default: `''` + + Additional options to pass to the kotlin compiler + +g:ale_kotlin_kotlinc_enable_config *g:ale_kotlin_kotlinc_enable_config* + Type: |Number| + Default: `0` + + Setting this variable to `1` tells the linter to load a configuration file. + This should be set in your vimrc + +g:ale_kotlin_kotlinc_config_file *g:ale_kotlin_kotlinc_config_file* + Type: |String| + Default: `'.ale_kotlin_kotlinc_config'` + + Filename of the configuration file. This should be set in your vimrc + +g:ale_kotlin_kotlinc_classpath *g:ale_kotlin_kotlinc_classpath* + Type: |String| + Default: `''` + + A string containing the paths (separated by the appropriate path separator) + of the source directories. + +g:ale_kotlin_kotlinc_sourcepath *g:ale_kotlin_kotlinc_sourcepath* + Type: |String| + Default: `''` + + A string containing the paths (separated by space) of the source + directories. + +g:ale_kotlin_kotlinc_use_module_file *g:ale_kotlin_kotlinc_use_module_file* + Type: |Number| + Default: `0` + + This option indicates whether the linter should use a module file. It is off + by default. + +g:ale_kotlin_kotlinc_module_filename *g:ale_kotlin_kotlinc_module_filename* + Type: |String| + Default: `'module.xml'` + + The filename of the module file that the linter should pass to the kotlin + compiler. + + +=============================================================================== +ktlint *ale-kotlin-ktlint* + +g:ale_kotlin_ktlint_executable *g:ale_kotlin_ktlint_executable* + Type: |String| + Default: `''` + + The Ktlint executable. + + Posix-compliant shell scripts are the only executables that can be found on + Ktlint's github release page. If you are not on such a system, your best + bet will be to download the ktlint jar and set this option to something + similar to `'java -jar /path/to/ktlint.jar'` + +g:ale_kotlin_ktlint_rulesets *g:ale_kotlin_ktlint_rulesets* + Type: |List| of |String|s + Default: [] + + This list should contain paths to ruleset jars and/or strings of maven + artifact triples. Example: + > + let g:ale_kotlin_ktlint_rulesets = ['/path/to/custom-ruleset.jar', + 'com.ktlint.rulesets:mycustomrule:1.0.0'] + +g:ale_kotlin_ktlint_options *g:ale_kotlin_ktlint_options* + Type: |String| + Default: `''` + + Additional options to pass to ktlint for both linting and fixing. Example: + > + let g:ale_kotlin_ktlint_options = '--android' + + +=============================================================================== +languageserver *ale-kotlin-languageserver* + +g:ale_kotlin_languageserver_executable *g:ale_kotlin_languageserver_executable* + Type: |String| + Default: `''` + + The kotlin-language-server executable. + + Executables are located inside the bin/ folder of the language server + release. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-latex.txt b/pack/acp/start/ale/doc/ale-latex.txt new file mode 100644 index 0000000..bedbabc --- /dev/null +++ b/pack/acp/start/ale/doc/ale-latex.txt @@ -0,0 +1,18 @@ +=============================================================================== +ALE LaTeX Integration *ale-latex-options* + + +=============================================================================== +write-good *ale-latex-write-good* + +See |ale-write-good-options| + + +=============================================================================== +textlint *ale-latex-textlint* + +See |ale-text-textlint| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-less.txt b/pack/acp/start/ale/doc/ale-less.txt new file mode 100644 index 0000000..040e511 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-less.txt @@ -0,0 +1,66 @@ +=============================================================================== +ALE Less Integration *ale-less-options* + + +=============================================================================== +lessc *ale-less-lessc* + +g:ale_less_lessc_executable *g:ale_less_lessc_executable* + *b:ale_less_lessc_executable* + Type: |String| + Default: `'lessc'` + + See |ale-integrations-local-executables| + + +g:ale_less_lessc_options *g:ale_less_lessc_options* + *b:ale_less_lessc_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to lessc. + + +g:ale_less_lessc_use_global *g:ale_less_lessc_use_global* + *b:ale_less_lessc_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +prettier *ale-less-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +stylelint *ale-less-stylelint* + +g:ale_less_stylelint_executable *g:ale_less_stylelint_executable* + *b:ale_less_stylelint_executable* + Type: |String| + Default: `'stylelint'` + + See |ale-integrations-local-executables| + + +g:ale_less_stylelint_options *g:ale_less_stylelint_options* + *b:ale_less_stylelint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to stylelint. + + +g:ale_less_stylelint_use_global *g:ale_less_stylelint_use_global* + *b:ale_less_stylelint_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-llvm.txt b/pack/acp/start/ale/doc/ale-llvm.txt new file mode 100644 index 0000000..2f4a46b --- /dev/null +++ b/pack/acp/start/ale/doc/ale-llvm.txt @@ -0,0 +1,19 @@ +=============================================================================== +ALE LLVM Integration *ale-llvm-options* + + +=============================================================================== +llc *ale-llvm-llc* + +g:ale_llvm_llc_executable *g:ale_llvm_llc_executable* + *b:ale_llvm_llc_executable* + + Type: |String| + Default: "llc" + + The command to use for checking. This variable is useful when llc command + has suffix like "llc-5.0". + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-lua.txt b/pack/acp/start/ale/doc/ale-lua.txt new file mode 100644 index 0000000..f1286f8 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-lua.txt @@ -0,0 +1,34 @@ +=============================================================================== +ALE Lua Integration *ale-lua-options* + +=============================================================================== +luac *ale-lua-luac* + +g:ale_lua_luac_executable *g:ale_lua_luac_executable* + *b:ale_lua_luac_executable* + Type: |String| + Default: `'luac'` + + This variable can be changed to change the path to luac. + +=============================================================================== +luacheck *ale-lua-luacheck* + +g:ale_lua_luacheck_executable *g:ale_lua_luacheck_executable* + *b:ale_lua_luacheck_executable* + Type: |String| + Default: `'luacheck'` + + This variable can be changed to change the path to luacheck. + + +g:ale_lua_luacheck_options *g:ale_lua_luacheck_options* + *b:ale_lua_luacheck_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to luacheck. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-markdown.txt b/pack/acp/start/ale/doc/ale-markdown.txt new file mode 100644 index 0000000..4e27eb9 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-markdown.txt @@ -0,0 +1,71 @@ +=============================================================================== +ALE Markdown Integration *ale-markdown-options* + + +=============================================================================== +mdl *ale-markdown-mdl* + +g:ale_markdown_mdl_executable *g:ale_markdown_mdl_executable* + *b:ale_markdown_mdl_executable* + Type: |String| + Default: `'mdl'` + + Override the invoked mdl binary. This is useful for running mdl from + binstubs or a bundle. + + +g:ale_markdown_mdl_options *g:ale_markdown_mdl_options* + *b:ale_markdown_mdl_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to mdl. + + +=============================================================================== +prettier *ale-markdown-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +remark-lint *ale-markdown-remark-lint* + +g:ale_markdown_remark_lint_executable *g:ale_markdown_remark_lint_executable* + *b:ale_markdown_remark_lint_executable* + Type: |String| + Default: `'remark'` + + See |ale-integrations-local-executables| + + +g:ale_markdown_remark_lint_options *g:ale_markdown_remark_lint_options* + *b:ale_markdown_remark_lint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to remark-lint. + + +g:ale_markdown_remark_lint_use_global *g:ale_markdown_remark_lint_use_global* + *b:ale_markdown_remark_lint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +textlint *ale-markdown-textlint* + +See |ale-text-textlint| + + +=============================================================================== +write-good *ale-markdown-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-mercury.txt b/pack/acp/start/ale/doc/ale-mercury.txt new file mode 100644 index 0000000..ca06a0a --- /dev/null +++ b/pack/acp/start/ale/doc/ale-mercury.txt @@ -0,0 +1,26 @@ +=============================================================================== +ALE Mercury Integration *ale-mercury-options* + + +=============================================================================== +mmc *ale-mercury-mmc* + + +g:ale_mercury_mmc_executable *g:ale_mercury_mmc_executable* + *b:ale_mercury_mmc_executable* + Type: |String| + Default: `'mmc'` + + This variable can be changed to use a different executable for mmc. + + +g:ale_mercury_mmc_options *g:ale_mercury_mmc_options* + *b:ale_mercury_mmc_options* + Type: |String| + Default: `'--make --output-compile-error-lines 100'` + + This variable can be set to pass additional options to mmc. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-nasm.txt b/pack/acp/start/ale/doc/ale-nasm.txt new file mode 100644 index 0000000..16c024a --- /dev/null +++ b/pack/acp/start/ale/doc/ale-nasm.txt @@ -0,0 +1,26 @@ +=============================================================================== +ALE NASM Integration *ale-nasm-options* + + +=============================================================================== +nasm *ale-nasm-nasm* + +g:ale_nasm_nasm_executable *g:ale_nasm_nasm_executable* + *b:ale_nasm_nasm_executable* + + Type: |String| + Default `'nasm'` + + This variable can be changed to use different executable for NASM. + + +g:ale_nasm_nasm_options *g:ale_nasm_nasm_options* + *b:ale_nasm_nasm_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to NASM. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-nroff.txt b/pack/acp/start/ale/doc/ale-nroff.txt new file mode 100644 index 0000000..62ec789 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-nroff.txt @@ -0,0 +1,12 @@ +=============================================================================== +ALE nroff Integration *ale-nroff-options* + + +=============================================================================== +write-good *ale-nroff-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-objc.txt b/pack/acp/start/ale/doc/ale-objc.txt new file mode 100644 index 0000000..0163175 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-objc.txt @@ -0,0 +1,73 @@ +=============================================================================== +ALE Objective-C Integration *ale-objc-options* + + +=============================================================================== +clang *ale-objc-clang* + +g:ale_objc_clang_options *g:ale_objc_clang_options* + *b:ale_objc_clang_options* + Type: |String| + Default: `'-std=c11 -Wall'` + + This variable can be changed to modify flags given to clang. + + +=============================================================================== +clangd *ale-objc-clangd* + +g:ale_objc_clangd_executable *g:ale_objc_clangd_executable* + *b:ale_objc_clangd_executable* + Type: |String| + Default: `'clangd'` + + This variable can be changed to use a different executable for clangd. + + +g:ale_objc_clangd_options *g:ale_objc_clangd_options* + *b:ale_objc_clangd_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clangd. + + +=============================================================================== +uncrustify *ale-objc-uncrustify* + +See |ale-c-uncrustify| for information about the available options. + + +=============================================================================== +ccls *ale-objc-ccls* + +g:ale_objc_ccls_executable *g:ale_objc_ccls_executable* + *b:ale_objc_ccls_executable* + Type: |String| + Default: `'ccls'` + + This variable can be changed to use a different executable for ccls. + + +g:ale_objc_ccls_init_options *g:ale_objc_ccls_init_options* + *b:ale_objc_ccls_init_options* + Type: |Dictionary| + Default: `{}` + + This variable can be changed to customize ccls initialization options. + Example: > + { + \ 'cacheDirectory': '/tmp/ccls', + \ 'cacheFormat': 'binary', + \ 'diagnostics': { + \ 'onOpen': 0, + \ 'opChange': 1000, + \ }, + \ } +< + Visit https://github.com/MaskRay/ccls/wiki/Initialization-options for all + available options and explanations. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-objcpp.txt b/pack/acp/start/ale/doc/ale-objcpp.txt new file mode 100644 index 0000000..cd65ab7 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-objcpp.txt @@ -0,0 +1,42 @@ +=============================================================================== +ALE Objective-C++ Integration *ale-objcpp-options* + + +=============================================================================== +clang *ale-objcpp-clang* + +g:ale_objcpp_clang_options *g:ale_objcpp_clang_options* + *b:ale_objcpp_clang_options* + Type: |String| + Default: `'-std=c++14 -Wall'` + + This variable can be changed to modify flags given to clang. + + +=============================================================================== +clangd *ale-objcpp-clangd* + +g:ale_objcpp_clangd_executable *g:ale_objcpp_clangd_executable* + *b:ale_objcpp_clangd_executable* + Type: |String| + Default: `'clangd'` + + This variable can be changed to use a different executable for clangd. + + +g:ale_objcpp_clangd_options *g:ale_objcpp_clangd_options* + *b:ale_objcpp_clangd_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to clangd. + + +=============================================================================== +uncrustify *ale-objcpp-uncrustify* + +See |ale-c-uncrustify| for information about the available options. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-ocaml.txt b/pack/acp/start/ale/doc/ale-ocaml.txt new file mode 100644 index 0000000..8b644c1 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-ocaml.txt @@ -0,0 +1,82 @@ +=============================================================================== +ALE OCaml Integration *ale-ocaml-options* + + +=============================================================================== +merlin *ale-ocaml-merlin* + + To use merlin linter for OCaml source code you need to make sure Merlin for + Vim is correctly configured. See the corresponding Merlin wiki page for + detailed instructions + (https://github.com/the-lambda-church/merlin/wiki/vim-from-scratch). + +=============================================================================== +ols *ale-ocaml-ols* + + The `ocaml-language-server` is the engine that powers OCaml and ReasonML + editor support using the Language Server Protocol. See the installation + instructions: + https://github.com/freebroccolo/ocaml-language-server#installation + +g:ale_ocaml_ols_executable *g:ale_ocaml_ols_executable* + *b:ale_ocaml_ols_executable* + Type: |String| + Default: `'ocaml-language-server'` + + This variable can be set to change the executable path for `ols`. + +g:ale_ocaml_ols_use_global *g:ale_ocaml_ols_use_global* + *b:ale_ocaml_ols_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable can be set to `1` to always use the globally installed + executable. See also |ale-integrations-local-executables|. + +=============================================================================== +ocamlformat *ale-ocaml-ocamlformat* + +g:ale_ocaml_ocamlformat_executable *g:ale_ocaml_ocamlformat_executable* + *b:ale_ocaml_ocamlformat_executable* + Type: |String| + Default: `'ocamlformat'` + + This variable can be set to pass the path of the ocamlformat fixer. + +g:ale_ocaml_ocamlformat_options *g:ale_ocaml_ocamlformat_options* + *b:ale_ocaml_ocamlformat_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the ocamlformat fixer. + +=============================================================================== +ocp-indent *ale-ocaml-ocp-indent* + +g:ale_ocaml_ocp_indent_executable *g:ale_ocaml_ocp_indent_executable* + *b:ale_ocaml_ocp_indent_executable* + Type: |String| + Default: `ocp-indent` + + This variable can be set to pass the path of the ocp-indent. + +g:ale_ocaml_ocp_indent_options *g:ale_ocaml_ocp_indent_options* + *b:ale_ocaml_ocp_indent_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the ocp-indent. + +g:ale_ocaml_ocp_indent_config *g:ale_ocaml_ocp_indent_config* + *b:ale_ocaml_ocp_indent_config* + Type: |String| + Default: `''` + + This variable can be set to pass additional config to the ocp-indent. + Expand after "--config=". + + "ocp-indent" can also be enabled from ocamlformat config. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-pawn.txt b/pack/acp/start/ale/doc/ale-pawn.txt new file mode 100644 index 0000000..f836df9 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-pawn.txt @@ -0,0 +1,12 @@ +=============================================================================== +ALE Pawn Integration *ale-pawn-options* + + +=============================================================================== +uncrustify *ale-pawn-uncrustify* + +See |ale-c-uncrustify| for information about the available options. + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-perl.txt b/pack/acp/start/ale/doc/ale-perl.txt new file mode 100644 index 0000000..761c273 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-perl.txt @@ -0,0 +1,91 @@ +=============================================================================== +ALE Perl Integration *ale-perl-options* + +ALE offers a few ways to check Perl code. Checking code with `perl` is +disabled by default, as `perl` code cannot be checked without executing it. +Specifically, we use the `-c` flag to see if `perl` code compiles. This does +not execute all of the code in a file, but it does run `BEGIN` and `CHECK` +blocks. See `perl --help` and https://stackoverflow.com/a/12908487/406224 + +See |g:ale_linters|. + + +=============================================================================== +perl *ale-perl-perl* + +g:ale_perl_perl_executable *g:ale_perl_perl_executable* + *b:ale_perl_perl_executable* + Type: |String| + Default: `'perl'` + + This variable can be changed to modify the executable used for linting perl. + + +g:ale_perl_perl_options *g:ale_perl_perl_options* + *b:ale_perl_perl_options* + Type: |String| + Default: `'-c -Mwarnings -Ilib'` + + This variable can be changed to alter the command-line arguments to the perl + invocation. + + +=============================================================================== +perlcritic *ale-perl-perlcritic* + +g:ale_perl_perlcritic_executable *g:ale_perl_perlcritic_executable* + *b:ale_perl_perlcritic_executable* + Type: |String| + Default: `'perlcritic'` + + This variable can be changed to modify the perlcritic executable used for + linting perl. + + +g:ale_perl_perlcritic_profile *g:ale_perl_perlcritic_profile* + *b:ale_perl_perlcritic_profile* + Type: |String| + Default: `'.perlcriticrc'` + + This variable can be changed to modify the perlcritic profile used for + linting perl. The current directory is checked for the file, then the + parent directory, etc, until it finds one. If no matching file is found, no + profile is passed to perlcritic. + + Set to an empty string to disable passing a specific profile to perlcritic + with the `'--profile'` option. + + To prevent perlcritic from using any profile, set this variable to an empty + string and pass `'--no-profile'`to perlcritic via the + |g:ale_perl_perlcritic_options| variable. + + +g:ale_perl_perlcritic_options *g:ale_perl_perlcritic_options* + *b:ale_perl_perlcritic_options* + Type: |String| + Default: `''` + + This variable can be changed to supply additional command-line arguments to + the perlcritic invocation. + + +g:ale_perl_perlcritic_showrules *g:ale_perl_perlcritic_showrules* + + Type: |Number| + Default: 0 + + Controls whether perlcritic rule names are shown after the error message. + Defaults to off to reduce length of message. +=============================================================================== +perltidy *ale-perl-perltidy* + +g:ale_perl_perltidy_options *g:ale_perl_perltidy_options* + *b:ale_perl_perltidy_options* + Type: |String| + Default: `''` + + This variable can be changed to alter the command-line arguments to + the perltidy invocation. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-perl6.txt b/pack/acp/start/ale/doc/ale-perl6.txt new file mode 100644 index 0000000..94953db --- /dev/null +++ b/pack/acp/start/ale/doc/ale-perl6.txt @@ -0,0 +1,43 @@ +=============================================================================== +ALE Perl6 Integration *ale-perl6-options* + +Checking code with `perl6` is disabled by default, as `perl6` code cannot be +checked without executing it. Specifically, we use the `-c` flag to see if +`perl6` code compiles. This does not execute all of the code in a file, but it +does run `BEGIN` and `CHECK` blocks. See `perl6 --help` + +Full support requires a perl6 implementation that supports the +PERL6_EXCEPTIONS_HANDLER environment variable and JSON error output, +which was specified in 6.d. Rakudo version 2018.08 is the first rakudo release +that supports this. See `perl6 --version` and +https://docs.perl6.org/programs/03-environment-variables. + +Without this variable, errors and warnings will appear at line 1, and can be +viewed with ALEDetail. This also serves as a fallback for errors and warnings +that do not trigger JSON output. + +See |g:ale_linters|. + + +=============================================================================== +perl6 *ale-perl6-perl6* + +g:ale_perl6_perl6_executable *g:ale_perl6_perl6_executable* + *b:ale_perl6_perl6_executable* + Type: |String| + Default: `'perl6'` + + This variable can be changed to modify the executable used for linting + perl6. + + +g:ale_perl6_perl6_options *g:ale_perl6_perl6_options* + *b:ale_perl6_perl6_options* + Type: |String| + Default: `'-c -Ilib'` + + This variable can be changed to alter the command-line arguments to the + perl6 invocation. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-php.txt b/pack/acp/start/ale/doc/ale-php.txt new file mode 100644 index 0000000..d41fb50 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-php.txt @@ -0,0 +1,227 @@ +=============================================================================== +ALE PHP Integration *ale-php-options* + +=============================================================================== +langserver *ale-php-langserver* + +g:ale_php_langserver_executable *g:ale_php_langserver_executable* + *b:ale_php_langserver_executable* + Type: |String| + Default: `'php-language-server.php'` + + The variable can be set to configure the executable that will be used for + running the PHP language server. `vendor` directory executables will be + preferred instead of this setting if |g:ale_php_langserver_use_global| is `0`. + + See: |ale-integrations-local-executables| + + +g:ale_php_langserver_use_global *g:ale_php_langserver_use_global* + *b:ale_php_langserver_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable can be set to `1` to force the language server to be run with + the executable set for |g:ale_php_langserver_executable|. + + See: |ale-integrations-local-executables| + + +=============================================================================== +phan *ale-php-phan* + +WARNING: please use the phan_client linter if you have an configuration file +for your project because the phan will look into your entirely project and +ale will display in the current buffer warnings that may belong to other file. + +g:ale_php_phan_minimum_severity *g:ale_php_phan_minimum_severity* + *b:ale_php_phan_minimum_severity* + Type: |Number| + Default: `0` + + This variable defines the minimum severity level. + +g:ale_php_phan_executable *g:ale_php_phan_executable* + *b:ale_php_phan_executable* + Type: |String| + Default: `'phan'` + + This variable sets executable used for phan or phan_client. + +g:ale_php_phan_use_client *g:ale_php_phan_use_client* + *b:ale_php_phan_use_client* + Type: |Number| + Default: `get(g:, 'ale_php_phan_use_client', 0)` + + This variable can be set to 1 to use the phan_client with phan daemon mode + instead of the phan standalone. + +=============================================================================== +phpcbf *ale-php-phpcbf* + +g:ale_php_phpcbf_executable *g:ale_php_phpcbf_executable* + *b:ale_php_phpcbf_executable* + Type: |String| + Default: `'phpcbf'` + + See |ale-integrations-local-executables| + + +g:ale_php_phpcbf_standard *g:ale_php_phpcbf_standard* + *b:ale_php_phpcbf_standard* + Type: |String| + Default: `''` + + This variable can be set to specify the coding standard used by phpcbf. If no + coding standard is specified, phpcbf will default to fixing against the + PEAR coding standard, or the standard you have set as the default. + + +g:ale_php_phpcbf_use_global *g:ale_php_phpcbf_use_global* + *b:ale_php_phpcbf_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +phpcs *ale-php-phpcs* + +g:ale_php_phpcs_executable *g:ale_php_phpcs_executable* + *b:ale_php_phpcs_executable* + Type: |String| + Default: `'phpcs'` + + See |ale-integrations-local-executables| + + +g:ale_php_phpcs_standard *g:ale_php_phpcs_standard* + *b:ale_php_phpcs_standard* + Type: |String| + Default: `''` + + This variable can be set to specify the coding standard used by phpcs. If no + coding standard is specified, phpcs will default to checking against the + PEAR coding standard, or the standard you have set as the default. + + +g:ale_php_phpcs_use_global *g:ale_php_phpcs_use_global* + *b:ale_php_phpcs_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_php_phpcs_options *g:ale_php_phpcs_options* + *b:ale_php_phpcs_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to php-cs + +=============================================================================== +phpmd *ale-php-phpmd* + +g:ale_php_phpmd_executable *g:ale_php_phpmd_executable* + *b:ale_php_phpmd_executable* + Type: |String| + Default: `'phpmd'` + + This variable sets executable used for phpmd. + + +g:ale_php_phpmd_ruleset *g:ale_php_phpmd_ruleset* + *b:ale_php_phpmd_ruleset* + Type: |String| + Default: `'cleancode,codesize,controversial,design,naming,unusedcode'` + + This variable controls the ruleset used by phpmd. Default is to use all of + the available phpmd rulesets + + +=============================================================================== +phpstan *ale-php-phpstan* + +g:ale_php_phpstan_executable *g:ale_php_phpstan_executable* + *b:ale_php_phpstan_executable* + Type: |String| + Default: `'phpstan'` + + This variable sets executable used for phpstan. + + +g:ale_php_phpstan_level *g:ale_php_phpstan_level* + *b:ale_php_phpstan_level* + Type: |String| + Default: `''` + + This variable controls the rule levels. 0 is the loosest and 4 is the + strictest. If this option isn't set, the rule level will be controlled by + the configuration file. If no configuration file can be detected, `'4'` will + be used instead. + + +g:ale_php_phpstan_configuration *g:ale_php_phpstan_configuration* + *b:ale_php_phpstan_configuration* + Type: |String| + Default: `''` + + This variable sets path to phpstan configuration file. + + +g:ale_php_phpstan_autoload *g:ale_php_phpstan_autoload* + *b:ale_php_phpstan_autoload* + Type: |String| + Default: `''` + + This variable sets path to phpstan autoload file. + + +=============================================================================== +psalm *ale-php-psalm* + +g:ale_php_psalm_executable *g:ale_php_psalm_executable* + *b:ale_php_psalm_executable* + Type: |String| + Default: `'psalm'` + + This variable sets the executable used for psalm. + +=============================================================================== +php-cs-fixer *ale-php-php-cs-fixer* + +g:ale_php_cs_fixer_executable *g:ale_php_cs_fixer_executable* + *b:ale_php_cs_fixer_executable* + Type: |String| + Default: `'php-cs-fixer'` + + This variable sets executable used for php-cs-fixer. + +g:ale_php_cs_fixer_use_global *g:ale_php_cs_fixer_use_global* + *b:ale_php_cs_fixer_use_global* + Type: |Boolean| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable force globally installed fixer. + +g:ale_php_cs_fixer_options *g:ale_php_cs_fixer_options* + *b:ale_php_cs_fixer_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to php-cs-fixer. + +=============================================================================== +php *ale-php-php* + +g:ale_php_php_executable *g:ale_php_php_executable* + *b:ale_php_php_executable* + Type: |String| + Default: `'php'` + + This variable sets the executable used for php. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-po.txt b/pack/acp/start/ale/doc/ale-po.txt new file mode 100644 index 0000000..1e03b7b --- /dev/null +++ b/pack/acp/start/ale/doc/ale-po.txt @@ -0,0 +1,12 @@ +=============================================================================== +ALE PO Integration *ale-po-options* + + +=============================================================================== +write-good *ale-po-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-pod.txt b/pack/acp/start/ale/doc/ale-pod.txt new file mode 100644 index 0000000..c7cc0bb --- /dev/null +++ b/pack/acp/start/ale/doc/ale-pod.txt @@ -0,0 +1,12 @@ +=============================================================================== +ALE Pod Integration *ale-pod-options* + + +=============================================================================== +write-good *ale-pod-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-pony.txt b/pack/acp/start/ale/doc/ale-pony.txt new file mode 100644 index 0000000..3b32168 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-pony.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE Pony Integration *ale-pony-options* + + +=============================================================================== +ponyc *ale-pony-ponyc* + +g:ale_pony_ponyc_executable *g:ale_pony_ponyc_executable* + *b:ale_pony_ponyc_executable* + Type: |String| + Default: `'ponyc'` + + See |ale-integrations-local-executables| + + +g:ale_pony_ponyc_options *g:ale_pony_ponyc_options* + *b:ale_pony_ponyc_options* + Type: |String| + Default: `'--pass paint'` + + This variable can be set to pass options to ponyc. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-powershell.txt b/pack/acp/start/ale/doc/ale-powershell.txt new file mode 100644 index 0000000..c28ef9e --- /dev/null +++ b/pack/acp/start/ale/doc/ale-powershell.txt @@ -0,0 +1,77 @@ +=============================================================================== +ALE PowerShell Integration *ale-powershell-options* + + +=============================================================================== +powershell *ale-powershell-powershell* + +g:ale_powershell_powershell_executable *g:ale_powershell_powershell_executable* + *b:ale_powershell_powershell_executable* + Type: String + Default: `'pwsh'` + + This variable can be changed to use a different executable for powershell. + +> + " Use powershell.exe rather than the default pwsh + let g:ale_powershell_powershell_executable = 'powershell.exe' +> + +=============================================================================== +psscriptanalyzer *ale-powershell-psscriptanalyzer* + +Installation +------------------------------------------------------------------------------- + +Install PSScriptAnalyzer by any means, so long as it can be automatically +imported in PowerShell. +Some PowerShell plugins set the filetype of files to `ps1`. To continue using +these plugins, use the ale_linter_aliases global to alias `ps1` to `powershell` + +> + " Allow ps1 filetype to work with powershell linters + let g:ale_linter_aliases = {'ps1': 'powershell'} +< + +g:ale_powershell_psscriptanalyzer_executable +*g:ale_powershell_psscriptanalyzer_executable* + *b:ale_powershell_psscriptanalyzer_executable* + Type: |String| + Default: `'pwsh'` + + This variable sets executable used for powershell. + + For example, on Windows you could set powershell to be Windows Powershell: +> + let g:ale_powershell_psscriptanalyzer_executable = 'powershell.exe' +< + +g:ale_powershell_psscriptanalyzer_module +*g:ale_powershell_psscriptanalyzer_module* + *b:ale_powershell_psscriptanalyzer_module* + Type: |String + Default: `'psscriptanalyzer'` + + This variable sets the name of the psscriptanalyzer module. + for psscriptanalyzer invocation. + + +g:ale_powershell_psscriptanalyzer_exclusions +*g:ale_powershell_psscriptanalyzer_exclusions* + *b:ale_powershell_psscriptanalyzer_exclusions* + Type: |String| + Default: `''` + + Set this variable to exclude test(s) for psscriptanalyzer + (-ExcludeRule option). To exclude more than one option, separate them with + commas. + +> + " Suppress Write-Host and Global vars warnings + let g:ale_powershell_psscriptanalyzer_exclusions = + \ 'PSAvoidUsingWriteHost,PSAvoidGlobalVars' +< + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-prolog.txt b/pack/acp/start/ale/doc/ale-prolog.txt new file mode 100644 index 0000000..14062a5 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-prolog.txt @@ -0,0 +1,56 @@ +=============================================================================== +ALE Prolog Integration *ale-prolog-options* + + +=============================================================================== +swipl *ale-prolog-swipl* + +g:ale_prolog_swipl_executable *g:ale_prolog_swipl_executable* + *b:ale_prolog_swipl_executable* + Type: |String| + Default: `'swipl'` + + The executable that will be run for the `swipl` linter. + +g:ale_prolog_swipl_load *g:ale_prolog_swipl_load* + *b:ale_prolog_swipl_load* + Type: |String| + Default: `'current_prolog_flag(argv, [File]), load_files(File, [sandboxed(true)]), halt.'` + + The prolog goals that will be passed to |g:ale_prolog_swipl_executable| with `-g` option. + + It does: + 1. Takes the first command argument (current file path) + 2. Checks (syntactic / semantic) problems and output to stderr + + NOTE: `sandboxed(true)` prohibits executing some directives such as 'initialization main'. + +g:ale_prolog_swipl_timeout *g:ale_prolog_swipl_timeout* + *b:ale_prolog_swipl_timeout* + Type: |Number| + Default: `3` + + Timeout seconds to detect long-running linter. + It is done by setting SIGALRM. + See |g:ale_prolog_swipl_alarm| and |g:ale_prolog_swipl_alarm_handler|. + +g:ale_prolog_swipl_alarm *g:ale_prolog_swipl_alarm* + *b:ale_prolog_swipl_alarm* + Type: |String| + Default: `'alarm(%t, (%h), _, [])'` + + The prolog goals to be expected to set SIGALRM. + `%t` is replaced by |g:ale_prolog_swipl_timeout|. + `%h` is replaced by |g:ale_prolog_swipl_alarm_handler|. + +g:ale_prolog_swipl_alarm_handler *g:ale_prolog_swipl_alarm_handler* + *b:ale_prolog_swipl_alarm_handler* + Type: |String| + Default: `'writeln(user_error, "ERROR: Exceeded %t seconds, Please change g:prolog_swipl_timeout to modify the limit."), halt(1)'` + + The prolog goals to be expected that will be run on SIGALRM. + `%t` is replaced by |g:ale_prolog_swipl_timeout|. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-proto.txt b/pack/acp/start/ale/doc/ale-proto.txt new file mode 100644 index 0000000..734e23d --- /dev/null +++ b/pack/acp/start/ale/doc/ale-proto.txt @@ -0,0 +1,33 @@ +=============================================================================== +ALE Proto Integration *ale-proto-options* + + +=============================================================================== +Integration Information + +Linting of `.proto` files requires that the `protoc` binary is installed in the +system path and that the `protoc-gen-lint` plugin for the `protoc` binary is also +installed. + +To enable `.proto` file linting, update |g:ale_linters| as appropriate: +> + " Enable linter for .proto files + let g:ale_linters = {'proto': ['protoc-gen-lint']} +< +=============================================================================== +protoc-gen-lint *ale-proto-protoc-gen-lint* + + The linter is a plugin for the `protoc` binary. As long as the binary resides + in the system path, `protoc` will find it. + +g:ale_proto_protoc_gen_lint_options *g:ale_proto_protoc_gen_lint_options* + + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to protoc. Note that the + directory of the linted file is always passed as an include path with '-I' + before any user-supplied options. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-pug.txt b/pack/acp/start/ale/doc/ale-pug.txt new file mode 100644 index 0000000..e2836f8 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-pug.txt @@ -0,0 +1,44 @@ +=============================================================================== +ALE Pug Integration *ale-pug-options* + + +=============================================================================== +puglint *ale-pug-puglint* + +The puglint linter will detect configuration files based on the path to the +filename automatically. Configuration files will be loaded in this order: + +1. `.pug-lintrc` +2. `.pug-lintrc.js` +3. `.pug-lintrc.json` +4. `package.json` + +You might need to create a configuration file for your project to get +meaningful results. + +g:ale_pug_puglint_executable *g:ale_pug_puglint_executable* + *b:ale_pug_puglint_executable* + Type: |String| + Default: `'pug-lint'` + + See |ale-integrations-local-executables| + + +g:ale_pug_puglint_options *g:ale_pug_puglint_options* + *b:ale_pug_puglint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to pug-lint. + + +g:ale_pug_puglint_use_global *g:ale_pug_puglint_use_global* + *b:ale_pug_puglint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-puppet.txt b/pack/acp/start/ale/doc/ale-puppet.txt new file mode 100644 index 0000000..daa8c10 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-puppet.txt @@ -0,0 +1,57 @@ +=============================================================================== +ALE Puppet Integration *ale-puppet-options* + + +=============================================================================== +puppet *ale-puppet-puppet* + +g:ale_puppet_puppet_executable *g:ale_puppet_puppet_executable* + *b:ale_puppet_puppet_executable* + Type: |String| + Default: `'puppet'` + + This variable can be changed to specify the executable used for puppet. + + +g:ale_puppet_puppet_options *g:ale_puppet_puppet_options* + *b:ale_puppet_puppet_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the + puppet parser validate invocation. + + +=============================================================================== +puppetlint *ale-puppet-puppetlint* + +g:ale_puppet_puppetlint_executable *g:ale_puppet_puppetlint_executable* + *b:ale_puppet_puppetlint_executable* + Type: |String| + Default: `'puppet-lint'` + + This variable can be changed to specify the executable used for puppet-lint. + + +g:ale_puppet_puppetlint_options *g:ale_puppet_puppetlint_options* + *b:ale_puppet_puppetlint_options* + Type: |String| + Default: `'--no-autoloader_layout-check'` + + This variable can be changed to add command-line arguments to the + puppet-lint invocation. + + +=============================================================================== +puppet-languageserver *ale-puppet-languageserver* + +g:ale_puppet_languageserver_executable *g:ale_puppet_languageserver_executable* + *b:ale_puppet_languageserver_executable* + type: |String| + Default: `'puppet-languageserver'` + + This variable can be used to specify the executable used for + puppet-languageserver. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-pyrex.txt b/pack/acp/start/ale/doc/ale-pyrex.txt new file mode 100644 index 0000000..245e611 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-pyrex.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE Pyrex (Cython) Integration *ale-pyrex-options* + + +=============================================================================== +cython *ale-pyrex-cython* + +g:ale_pyrex_cython_executable *g:ale_pyrex_cython_executable* + *b:ale_pyrex_cython_executable* + Type: |String| + Default: `'cython'` + + This variable can be changed to use a different executable for cython. + + +g:ale_pyrex_cython_options *g:ale_pyrex_cython_options* + *b:ale_pyrex_cython_options* + Type: |String| + Default: `'--warning-extra --warning-errors'` + + This variable can be changed to modify flags given to cython. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-python.txt b/pack/acp/start/ale/doc/ale-python.txt new file mode 100644 index 0000000..9d5846d --- /dev/null +++ b/pack/acp/start/ale/doc/ale-python.txt @@ -0,0 +1,764 @@ +=============================================================================== +ALE Python Integration *ale-python-options* + + +g:ale_python_auto_pipenv *g:ale_python_auto_pipenv* + *b:ale_python_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + +=============================================================================== +ALE Python Project Root Behavior *ale-python-root* + +For some linters, ALE will search for a Python project root by looking at the +files in directories on or above where a file being checked is. ALE applies +the following methods, in order: + +1. Find the first directory containing a common Python configuration file. +2. If no configuration file can be found, use the first directory which does + not contain a readable file named `__init__.py`. + +ALE will look for configuration files with the following filenames. > + + MANIFEST.in + setup.cfg + pytest.ini + tox.ini + mypy.ini + pycodestyle.cfg + .flake8 + .flake8rc + pylama.ini + pylintrc + .pylintrc + Pipfile + Pipfile.lock +< + +The first directory containing any of the files named above will be used. + + +=============================================================================== +autopep8 *ale-python-autopep8* + +g:ale_python_autopep8_executable *g:ale_python_autopep8_executable* + *b:ale_python_autopep8_executable* + Type: |String| + Default: `'autopep8'` + + See |ale-integrations-local-executables| + + +g:ale_python_autopep8_options *g:ale_python_autopep8_options* + *b:ale_python_autopep8_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to autopep8. + + +g:ale_python_autopep8_use_global *g:ale_python_autopep8_use_global* + *b:ale_python_autopep8_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +bandit *ale-python-bandit* + +g:ale_python_bandit_executable *g:ale_python_bandit_executable* + *b:ale_python_bandit_executable* + Type: |String| + Default: `'bandit'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `bandit'`. + + +g:ale_python_bandit_options *g:ale_python_bandit_options* + *b:ale_python_bandit_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the + bandit invocation. + + +g:ale_python_bandit_use_config *g:ale_python_bandit_use_config* + *b:ale_python_bandit_use_config* + Type: |Number| + Default: `1` + + If this variable is true and a `.bandit` file exists in the directory of the + file being checked or a parent directory, an `--ini` option is added to the + `bandit` command for the nearest `.bandit` file. Set this variable false to + disable adding the `--ini` option automatically. + + +g:ale_python_bandit_use_global *g:ale_python_bandit_use_global* + *b:ale_python_bandit_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_bandit_auto_pipenv *g:ale_python_bandit_auto_pipenv* + *b:ale_python_bandit_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +black *ale-python-black* + +g:ale_python_black_executable *g:ale_python_black_executable* + *b:ale_python_black_executable* + Type: |String| + Default: `'black'` + + See |ale-integrations-local-executables| + + +g:ale_python_black_options *g:ale_python_black_options* + *b:ale_python_black_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to black. + + +g:ale_python_black_use_global *g:ale_python_black_use_global* + *b:ale_python_black_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_black_auto_pipenv *g:ale_python_black_auto_pipenv* + *b:ale_python_black_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + +g:ale_python_black_change_directory *g:ale_python_black_change_directory* + *b:ale_python_black_change_directory* + Type: |Number| + Default: `1` + + If set to `1`, ALE will switch to the directory the Python file being + checked with `black` is in before checking it. This helps `black` find + configuration files more easily. This option can be turned off if you want + to control the directory Python is executed from yourself. + + +=============================================================================== +flake8 *ale-python-flake8* + +g:ale_python_flake8_change_directory *g:ale_python_flake8_change_directory* + *b:ale_python_flake8_change_directory* + Type: |Number| + Default: `1` + + If set to `1`, ALE will switch to the directory the Python file being + checked with `flake8` is in before checking it. This helps `flake8` find + configuration files more easily. This option can be turned off if you want + to control the directory Python is executed from yourself. + + +g:ale_python_flake8_executable *g:ale_python_flake8_executable* + *b:ale_python_flake8_executable* + Type: |String| + Default: `'flake8'` + + This variable can be changed to modify the executable used for flake8. Set + this to `'pipenv'` to invoke `'pipenv` `run` `flake8'`. + + +g:ale_python_flake8_options *g:ale_python_flake8_options* + *b:ale_python_flake8_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the flake8 + invocation. + + For example, to dynamically switch between programs targeting Python 2 and + Python 3, you may want to set > + + let g:ale_python_flake8_executable = 'python3' " or 'python' for Python 2 + let g:ale_python_flake8_options = '-m flake8' +< + after making sure it's installed for the appropriate Python versions (e.g. + `python3 -m pip install --user flake8`). + + +g:ale_python_flake8_use_global *g:ale_python_flake8_use_global* + *b:ale_python_flake8_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable controls whether or not ALE will search for flake8 in a + virtualenv directory first. If this variable is set to `1`, then ALE will + always use |g:ale_python_flake8_executable| for the executable path. + + Both variables can be set with `b:` buffer variables instead. + + +g:ale_python_flake8_auto_pipenv *g:ale_python_flake8_auto_pipenv* + *b:ale_python_flake8_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +isort *ale-python-isort* + +g:ale_python_isort_executable *g:ale_python_isort_executable* + *b:ale_python_isort_executable* + Type: |String| + Default: `'isort'` + + See |ale-integrations-local-executables| + + +g:ale_python_isort_options *g:ale_python_isort_options* + *b:ale_python_isort_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to isort. + + +g:ale_python_isort_use_global *g:ale_python_isort_use_global* + *b:ale_python_isort_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +mypy *ale-python-mypy* + +The minimum supported version of mypy that ALE supports is v0.4.4. This is +the first version containing the `--shadow-file` option ALE needs to be able +to check for errors while you type. + +`mypy` will be run from a detected project root, per |ale-python-root|. + + +g:ale_python_mypy_executable *g:ale_python_mypy_executable* + *b:ale_python_mypy_executable* + Type: |String| + Default: `'mypy'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `mypy'`. + +g:ale_python_mypy_ignore_invalid_syntax + *g:ale_python_mypy_ignore_invalid_syntax* + *b:ale_python_mypy_ignore_invalid_syntax* + Type: |Number| + Default: `0` + + When set to `1`, syntax error messages for mypy will be ignored. This option + can be used when running other Python linters which check for syntax errors, + as mypy can take a while to finish executing. + + +g:ale_python_mypy_options *g:ale_python_mypy_options* + *b:ale_python_mypy_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the mypy + invocation. + + +g:ale_python_mypy_use_global *g:ale_python_mypy_use_global* + *b:ale_python_mypy_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_mypy_auto_pipenv *g:ale_python_mypy_auto_pipenv* + *b:ale_python_mypy_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +prospector *ale-python-prospector* + +g:ale_python_prospector_executable *g:ale_python_prospector_executable* + *b:ale_python_prospector_executable* + Type: |String| + Default: `'prospector'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `prospector'`. + + +g:ale_python_prospector_options *g:ale_python_prospector_options* + *b:ale_python_prospector_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the prospector + invocation. + + For example, to dynamically switch between programs targeting Python 2 and + Python 3, you may want to set > + + let g:ale_python_prospector_executable = 'python3' + " or 'python' for Python 2 + let g:ale_python_prospector_options = '--rcfile /path/to/.prospector.yaml' + " The virtualenv detection needs to be disabled. + let g:ale_python_prospector_use_global = 0 + + after making sure it's installed for the appropriate Python versions (e.g. + `python3 -m pip install --user prospector`). + + +g:ale_python_prospector_use_global *g:ale_python_prospector_use_global* + *b:ale_python_prospector_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_prospector_auto_pipenv *g:ale_python_prospector_auto_pipenv* + *b:ale_python_prospector_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +pycodestyle *ale-python-pycodestyle* + + +g:ale_python_pycodestyle_executable *g:ale_python_pycodestyle_executable* + *b:ale_python_pycodestyle_executable* + Type: |String| + Default: `'pycodestyle'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `pycodestyle'`. + + +g:ale_python_pycodestyle_options *g:ale_python_pycodestyle_options* + *b:ale_python_pycodestyle_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the + pycodestyle invocation. + + +g:ale_python_pycodestyle_use_global *g:ale_python_pycodestyle_use_global* + *b:ale_python_pycodestyle_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_pycodestyle_auto_pipenv *g:ale_python_pycodestyle_auto_pipenv* + *b:ale_python_pycodestyle_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +pydocstyle *ale-python-pydocstyle* + + +g:ale_python_pydocstyle_executable *g:ale_python_pydocstyle_executable* + *b:ale_python_pydocstyle_executable* + Type: |String| + Default: `'pydocstyle'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `pydocstyle'`. + + +g:ale_python_pydocstyle_options *g:ale_python_pydocstyle_options* + *b:ale_python_pydocstyle_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the + pydocstyle invocation. + + +g:ale_python_pydocstyle_use_global *g:ale_python_pydocstyle_use_global* + *b:ale_python_pydocstyle_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_pydocstyle_auto_pipenv *g:ale_python_pydocstyle_auto_pipenv* + *b:ale_python_pydocstyle_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +pyflakes *ale-python-pyflakes* + + +g:ale_python_pyflakes_executable *g:ale_python_pyflakes_executable* + *b:ale_python_pyflakes_executable* + Type: |String| + Default: `'pyflakes'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `pyflakes'`. + + +g:ale_python_pyflakes_auto_pipenv *g:ale_python_pyflakes_auto_pipenv* + *b:ale_python_pyflakes_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +pylama *ale-python-pylama* + +g:ale_python_pylama_change_directory *g:ale_python_pylama_change_directory* + *b:ale_python_pylama_change_directory* + Type: |Number| + Default: `1` + + If set to `1`, `pylama` will be run from a detected project root, per + |ale-python-root|. This is useful because `pylama` only searches for + configuration files in its current directory and applies file masks using + paths relative to its current directory. This option can be turned off if + you want to control the directory in which `pylama` is executed. + + +g:ale_python_pylama_executable *g:ale_python_pylama_executable* + *b:ale_python_pylama_executable* + Type: |String| + Default: `'pylama'` + + This variable can be changed to modify the executable used for pylama. Set + this to `'pipenv'` to invoke `'pipenv` `run` `pylama'`. + + +g:ale_python_pylama_options *g:ale_python_pylama_options* + *b:ale_python_pylama_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the pylama + invocation. + + +g:ale_python_pylama_use_global *g:ale_python_pylama_use_global* + *b:ale_python_pylama_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable controls whether or not ALE will search for pylama in a + virtualenv directory first. If this variable is set to `1`, then ALE will + always use |g:ale_python_pylama_executable| for the executable path. + + Both variables can be set with `b:` buffer variables instead. + + +g:ale_python_pylama_auto_pipenv *g:ale_python_pylama_auto_pipenv* + *b:ale_python_pylama_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +pylint *ale-python-pylint* + +g:ale_python_pylint_change_directory *g:ale_python_pylint_change_directory* + *b:ale_python_pylint_change_directory* + Type: |Number| + Default: `1` + + If set to `1`, `pylint` will be run from a detected project root, per + |ale-python-root|. Since `pylint` only checks for `pylintrc` in the packages + above its current directory before falling back to user and global `pylintrc` + files, this is necessary for `pylint` to use a project `pylintrc` file, if + present. This option can be turned off if you want to control the directory + Python is executed from yourself. + + +g:ale_python_pylint_executable *g:ale_python_pylint_executable* + *b:ale_python_pylint_executable* + Type: |String| + Default: `'pylint'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `pylint'`. + + +g:ale_python_pylint_options *g:ale_python_pylint_options* + *b:ale_python_pylint_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the pylint + invocation. + + For example, to dynamically switch between programs targeting Python 2 and + Python 3, you may want to set > + + let g:ale_python_pylint_executable = 'python3' " or 'python' for Python 2 + let g:ale_python_pylint_options = '--rcfile /path/to/pylint.rc' + " The virtualenv detection needs to be disabled. + let g:ale_python_pylint_use_global = 0 + + after making sure it's installed for the appropriate Python versions (e.g. + `python3 -m pip install --user pylint`). + + +g:ale_python_pylint_use_global *g:ale_python_pylint_use_global* + *b:ale_python_pylint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_pylint_auto_pipenv *g:ale_python_pylint_auto_pipenv* + *b:ale_python_pylint_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_pylint_use_msg_id *g:ale_python_pylint_use_msg_id* + *b:ale_python_pylint_use_msg_id* + Type: |Number| + Default: `0` + + Use message for output (e.g. I0011) instead of symbolic name of the message + (e.g. locally-disabled). + +=============================================================================== +pyls *ale-python-pyls* + +`pyls` will be run from a detected project root, per |ale-python-root|. + + +g:ale_python_pyls_executable *g:ale_python_pyls_executable* + *b:ale_python_pyls_executable* + Type: |String| + Default: `'pyls'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `pyls'`. + + +g:ale_python_pyls_use_global *g:ale_python_pyls_use_global* + *b:ale_python_pyls_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_pyls_auto_pipenv *g:ale_python_pyls_auto_pipenv* + *b:ale_python_pyls_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_pyls_config *g:ale_python_pyls_config* + *b:ale_python_pyls_config* + Type: |Dictionary| + Default: `{}` + + Dictionary with configuration settings for pyls. For example, to disable + the pycodestyle linter: > + { + \ 'pyls': { + \ 'plugins': { + \ 'pycodestyle': { + \ 'enabled': v:false + \ } + \ } + \ }, + \ } +< + +=============================================================================== +pyre *ale-python-pyre* + +`pyre` will be run from a detected project root, per |ale-python-root|. + + +g:ale_python_pyre_executable *g:ale_python_pyre_executable* + *b:ale_python_pyre_executable* + Type: |String| + Default: `'pyre'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `pyre'`. + + +g:ale_python_pyre_use_global *g:ale_python_pyre_use_global* + *b:ale_python_pyre_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_pyre_auto_pipenv *g:ale_python_pyre_auto_pipenv* + *b:ale_python_pyre_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +=============================================================================== +reorder-python-imports *ale-python-reorder_python_imports* + +g:ale_python_reorder_python_imports_executable + *g:ale_python_reorder_python_imports_executable* + *b:ale_python_reorder_python_imports_executable* + Type: |String| + Default: `'reorder-python-imports'` + + See |ale-integrations-local-executables| + + +g:ale_python_reorder_python_imports_options + *g:ale_python_reorder_python_imports_options* + *b:ale_python_reorder_python_imports_options* + Type: |String| + Default: `''` + + This variable can be set to pass extra options to reorder-python-imports. + + +g:ale_python_reorder_python_imports_use_global + *g:ale_python_reorder_python_imports_use_global* + *b:ale_python_reorder_python_imports_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +vulture *ale-python-vulture* + +g:ale_python_vulture_change_directory *g:ale_python_vulture_change_directory* + *b:ale_python_vulture_change_directory* + Type: |Number| + Default: `1` + + If set to `1`, ALE will switch to the directory the Python file being + checked with `vulture` is in before checking it and check the whole project + directory instead of checking only the file opened in the current buffer. + This helps `vulture` to know the context and avoid false-negative results. + + +g:ale_python_vulture_executable *g:ale_python_vulture_executable* + *b:ale_python_vulture_executable* + Type: |String| + Default: `'vulture'` + + See |ale-integrations-local-executables| + + +g:ale_python_vulture_options *g:ale_python_vulture_options* + *b:ale_python_vulture_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the vulture + invocation. + + +g:ale_python_vulture_use_global *g:ale_python_vulture_use_global* + *b:ale_python_vulture_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +yapf *ale-python-yapf* + +g:ale_python_yapf_executable *g:ale_python_yapf_executable* + *b:ale_python_yapf_executable* + Type: |String| + Default: `'yapf'` + + See |ale-integrations-local-executables| + + +g:ale_python_yapf_use_global *g:ale_python_yapf_use_global* + *b:ale_python_yapf_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-qml.txt b/pack/acp/start/ale/doc/ale-qml.txt new file mode 100644 index 0000000..f6d715a --- /dev/null +++ b/pack/acp/start/ale/doc/ale-qml.txt @@ -0,0 +1,18 @@ +=============================================================================== +ALE QML Integration *ale-qml-options* + + +=============================================================================== +qmlfmt *ale-qml-qmlfmt* + +g:ale_qml_qmlfmt_executable *g:ale_qml_qmlfmt_executable* + *b:ale_qml_qmlfmt_executable* + Type: |String| + Default: `'qmlfmt'` + + This variable can be set to change the path to qmlfmt. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/pack/acp/start/ale/doc/ale-r.txt b/pack/acp/start/ale/doc/ale-r.txt new file mode 100644 index 0000000..b5ccebe --- /dev/null +++ b/pack/acp/start/ale/doc/ale-r.txt @@ -0,0 +1,45 @@ +=============================================================================== +ALE R Integration *ale-r-options* + + +=============================================================================== +lintr *ale-r-lintr* + +g:ale_r_lintr_options *g:ale_r_lintr_options* + *b:ale_r_lintr_options* + Type: |String| + Default: `'lintr::with_defaults()'` + + This option can be configured to change the options for lintr. + + The value of this option will be run with `eval` for the `lintr::lint` + options. Consult the lintr documentation for more information. + + +g:ale_r_lintr_lint_package *g:ale_r_lintr_lint_package* + *b:ale_r_lintr_lint_package* + Type: |Number| + Default: `0` + + When set to `1`, the file will be checked with `lintr::lint_package` instead + of `lintr::lint`. This prevents erroneous namespace warnings when linting + package files. + + +=============================================================================== +styler *ale-r-styler* + +g:ale_r_styler_options *g:ale_r_styler_options* + *b:ale_r_styler_options* + Type: |String| + Default: `'styler::tidyverse_style'` + + This option can be configured to change the options for styler. + + The value of this option will be used as the `style` argument for the + `styler::style_file` options. Consult the styler documentation + for more information. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-reasonml.txt b/pack/acp/start/ale/doc/ale-reasonml.txt new file mode 100644 index 0000000..b8729a5 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-reasonml.txt @@ -0,0 +1,76 @@ +=============================================================================== +ALE ReasonML Integration *ale-reasonml-options* + + +=============================================================================== +merlin *ale-reasonml-merlin* + +To use merlin linter for ReasonML source code you need to make sure Merlin for +Vim is correctly configured. See the corresponding Merlin wiki page for +detailed instructions: +https://github.com/the-lambda-church/merlin/wiki/vim-from-scratch + +=============================================================================== +ols *ale-reasonml-ols* + +The `ocaml-language-server` is the engine that powers OCaml and ReasonML +editor support using the Language Server Protocol. See the installation +instructions: +https://github.com/freebroccolo/ocaml-language-server#installation + + +g:ale_reason_ols_executable *g:ale_reason_ols_executable* + *b:ale_reason_ols_executable* + Type: |String| + Default: `'ocaml-language-server'` + + This variable can be set to change the executable path for `ols`. + + +g:ale_reason_ols_use_global *g:ale_reason_ols_use_global* + *b:ale_reason_ols_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable can be set to `1` to always use the globally installed + executable. See also |ale-integrations-local-executables|. + + +=============================================================================== +reason-language-server *ale-reasonml-language-server* + +Note: You must set an executable - there is no 'default' install location. +Go to https://github.com/jaredly/reason-language-server and download the +latest release. You can place it anywhere, but ensure you set the executable +path. + + +g:ale_reason_ls_executable *g:ale_reason_ls_executable* + *b:ale_reason_ls_executable* + Type: |String| + + This variable defines the standard location of the language server + executable. This must be set. + + +=============================================================================== +refmt *ale-reasonml-refmt* + +g:ale_reasonml_refmt_executable *g:ale_reasonml_refmt_executable* + *b:ale_reasonml_refmt_executable* + Type: |String| + Default: `'refmt'` + + This variable can be set to pass the path of the refmt fixer. + + +g:ale_reasonml_refmt_options *g:ale_reasonml_refmt_options* + *b:ale_reasonml_refmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the refmt fixer. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-restructuredtext.txt b/pack/acp/start/ale/doc/ale-restructuredtext.txt new file mode 100644 index 0000000..e308b07 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-restructuredtext.txt @@ -0,0 +1,26 @@ +=============================================================================== +ALE reStructuredText Integration *ale-restructuredtext-options* + + +=============================================================================== +textlint *ale-restructuredtext-textlint* + +To use textlint at reStructuredText, please install `textlint-plugin-rst`. +https://github.com/jimo1001/textlint-plugin-rst +> + $ npm install textlint-plugin-rst + +To install `textlint-plugin-rst`, `docutils-ast-writer` python package +must be installed. +See: https://github.com/jimo1001/docutils-ast-writer + +See |ale-text-textlint| + +=============================================================================== +write-good *ale-restructuredtext-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-ruby.txt b/pack/acp/start/ale/doc/ale-ruby.txt new file mode 100644 index 0000000..bf971e7 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-ruby.txt @@ -0,0 +1,155 @@ +=============================================================================== +ALE Ruby Integration *ale-ruby-options* + + +=============================================================================== +brakeman *ale-ruby-brakeman* + +g:ale_ruby_brakeman_executable *g:ale_ruby_brakeman_executable* + *b:ale_ruby_brakeman_executable* + Type: String + Default: `'brakeman'` + + Override the invoked brakeman binary. Set this to `'bundle'` to invoke + `'bundle` `exec` brakeman'. + + +g:ale_ruby_brakeman_options *g:ale_ruby_brakeman_options* + *b:ale_ruby_brakeman_options* + Type: |String| + Default: `''` + + The contents of this variable will be passed through to brakeman. + + +=============================================================================== +rails_best_practices *ale-ruby-rails_best_practices* + +g:ale_ruby_rails_best_practices_executable + *g:ale_ruby_rails_best_practices_executable* + *b:ale_ruby_rails_best_practices_executable* + Type: String + Default: `'rails_best_practices'` + + Override the invoked rails_best_practices binary. Set this to `'bundle'` to + invoke `'bundle` `exec` rails_best_practices'. + + +g:ale_ruby_rails_best_practices_options + *g:ale_ruby_rails_best_practices_options* + *b:ale_ruby_rails_best_practices_options* + Type: |String| + Default: `''` + + The contents of this variable will be passed through to rails_best_practices. + + +=============================================================================== +reek *ale-ruby-reek* + +g:ale_ruby_reek_executable *g:ale_ruby_reek_executable* + *b:ale_ruby_reek_executable* + Type: String + Default: `'reek'` + + Override the invoked reek binary. Set this to `'bundle'` to invoke + `'bundle` `exec` reek'. + + +g:ale_ruby_reek_show_context *g:ale_ruby_reek_show_context* + *b:ale_ruby_reek_show_context* + Type: |Number| + Default: 0 + + Controls whether context is included in the linter message. Defaults to off + because context is usually obvious while viewing a file. + + +g:ale_ruby_reek_show_wiki_link *g:ale_ruby_reek_show_wiki_link* + *b:ale_ruby_reek_show_wiki_link* + Type: |Number| + Default: 0 + + Controls whether linter messages contain a link to an explanatory wiki page + for the type of code smell. Defaults to off to improve readability. + + +=============================================================================== +rubocop *ale-ruby-rubocop* + +g:ale_ruby_rubocop_executable *g:ale_ruby_rubocop_executable* + *b:ale_ruby_rubocop_executable* + Type: String + Default: `'rubocop'` + + Override the invoked rubocop binary. Set this to `'bundle'` to invoke + `'bundle` `exec` rubocop'. + + +g:ale_ruby_rubocop_options *g:ale_ruby_rubocop_options* + *b:ale_ruby_rubocop_options* + Type: |String| + Default: `''` + + This variable can be change to modify flags given to rubocop. + + +=============================================================================== +ruby *ale-ruby-ruby* + +g:ale_ruby_ruby_executable *g:ale_ruby_ruby_executable* + *b:ale_ruby_ruby_executable* + Type: String + Default: `'ruby'` + + This variable can be changed to use a different executable for ruby. + + +=============================================================================== +rufo *ale-ruby-rufo* + +g:ale_ruby_rufo_executable *g:ale_ruby_rufo_executable* + *b:ale_ruby_rufo_executable* + Type: String + Default: `'rufo'` + + Override the invoked rufo binary. This is useful for running rufo from + binstubs or a bundle. + + +=============================================================================== +solargraph *ale-ruby-solargraph* + +g:ale_ruby_solargraph_executable *g:ale_ruby_solargraph_executable* + *b:ale_ruby_solargraph_executable* + Type: String + Default: `'solargraph'` + + Override the invoked solargraph binary. This is useful for running solargraph + from binstubs or a bundle. + + +=============================================================================== +standardrb *ale-ruby-standardrb* + +g:ale_ruby_standardrb_executable *g:ale_ruby_standardrb_executable* + *b:ale_ruby_standardrb_executable* + Type: String + Default: `'standardrb'` + + Override the invoked standardrb binary. Set this to `'bundle'` to invoke + `'bundle` `exec` standardrb'. + + +g:ale_ruby_standardrb_options *g:ale_ruby_standardrb_options* + *b:ale_ruby_standardrb_options* + Type: |String| + Default: `''` + + This variable can be change to modify flags given to standardrb. + + +=============================================================================== + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-rust.txt b/pack/acp/start/ale/doc/ale-rust.txt new file mode 100644 index 0000000..44a79b1 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-rust.txt @@ -0,0 +1,248 @@ +=============================================================================== +ALE Rust Integration *ale-rust-options* + *ale-integration-rust* + +=============================================================================== +Integration Information + + If Vim does not detect the Rust file type out-of-the-box, you need the runtime + files for Rust distributed in Vim >=8.0.0501 or upstream: + https://github.com/rust-lang/rust.vim + + Note that there are three possible linters for Rust files: + + 1. rustc -- The Rust compiler is used to check the currently edited file. + So, if your project consists of multiple files, you will get some errors + when you use e.g. a struct which is defined in another file. You can use + |g:ale_rust_ignore_error_codes| to ignore some of these errors. + 2. cargo -- If your project is managed by Cargo, the whole project is + checked. That means that all errors are properly shown, but cargo can + only operate on the files written on disk, so errors will not be reported + while you type. + 3. rls -- If you have `rls` installed, you might prefer using this linter + over cargo. rls implements the Language Server Protocol for incremental + compilation of Rust code, and can check Rust files while you type. `rls` + requires Rust files to contained in Cargo projects. + 4. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to + consistently reformat your Rust code. + + Only cargo is enabled by default. To switch to using rustc instead of cargo, + configure |g:ale_linters| appropriately: > + + " See the help text for the option for more information. + let g:ale_linters = {'rust': ['rustc']} +< + + Also note that rustc 1.12. or later is needed. + + +=============================================================================== +cargo *ale-rust-cargo* + +g:ale_rust_cargo_use_check *g:ale_rust_cargo_use_check* + *b:ale_rust_cargo_use_check* + Type: |Number| + Default: `1` + + When set to `1`, this option will cause ALE to use `cargo check` instead of + `cargo build` . `cargo check` is supported since version 1.16.0 of Rust. + + ALE will never use `cargo check` when the version of `cargo` is less than + 0.17.0. + + +g:ale_rust_cargo_check_all_targets *g:ale_rust_cargo_check_all_targets* + *b:ale_rust_cargo_check_all_targets* + Type: |Number| + Default: `0` + + When set to `1`, ALE will set the `--all-targets` option when `cargo check` + is used. See |g:ale_rust_cargo_use_check|, + + +g:ale_rust_cargo_check_tests *g:ale_rust_cargo_check_tests* + *b:ale_rust_cargo_check_tests* + Type: |Number| + Default: `0` + + When set to `1`, ALE will set the `--tests` option when `cargo check` + is used. This allows for linting of tests which are normally excluded. + See |g:ale_rust_cargo_use_check|, + + +g:ale_rust_cargo_check_examples *g:ale_rust_cargo_check_examples* + *b:ale_rust_cargo_check_examples* + Type: |Number| + Default: `0` + + When set to `1`, ALE will set the `--examples` option when `cargo check` + is used. This allows for linting of examples which are normally excluded. + See |g:ale_rust_cargo_use_check|, + + +g:ale_rust_cargo_default_feature_behavior + *g:ale_rust_cargo_default_feature_behavior* + *b:ale_rust_cargo_default_feature_behavior* + Type: |String| + Default: `default` + + When set to `none`, ALE will set the `--no-default-features` option when + invoking `cargo`. Only the features specified in + |g:ale_rust_cargo_include_features| will be included when performing the + lint check. + + When set to `default`, ALE will instruct `cargo` to build all default + features specified in the project's `Cargo.toml` file, in addition to + including any additional features defined in + |g:ale_rust_cargo_include_features|. + + When set to `all`, ALE will set the `--all-features` option when + invoking `cargo`, which will include all features defined in the project's + `Cargo.toml` file when performing the lint check. + + +g:ale_rust_cargo_include_features *g:ale_rust_cargo_include_features* + *b:ale_rust_cargo_include_features* + Type: |String| + Default: `''` + + When defined, ALE will set the `--features` option when invoking `cargo` to + perform the lint check. See |g:ale_rust_cargo_default_feature_behavior|. + + +g:ale_rust_cargo_avoid_whole_workspace *g:ale_rust_cargo_avoid_whole_workspace* + *b:ale_rust_cargo_avoid_whole_workspace* + Type: |Number| + Default: `1` + + When set to 1, and ALE is used to edit a crate that is part of a Cargo + workspace, avoid building the entire workspace by invoking `cargo` directly + in the crate's directory. Otherwise, behave as usual. + + +g:ale_rust_cargo_use_clippy + *g:ale_rust_cargo_use_clippy* + *b:ale_rust_cargo_use_clippy* + Type: |Number| + Default: `0` + + When set to 1, `cargo clippy` will be used instead of `cargo check` or + `cargo build` as linter. + For details of `cargo clippy`, please visit the following link: + + https://github.com/rust-lang-nursery/rust-clippy + + Since `cargo clippy` is optional toolchain, it's safer to check whether + `cargo-clippy` is executable as follows: +> + let g:ale_rust_cargo_use_clippy = executable('cargo-clippy') +< + +g:ale_rust_cargo_clippy_options + *g:ale_rust_cargo_clippy_options* + *b:ale_rust_cargo_clippy_options* + + Type: |String| + Default: `''` + + When `cargo clippy` is used, this value will be added to a command line to run + it. This variable is useful when you want to add some extra options which + only `cargo clippy` supports (e.g. `--deny`). + + +=============================================================================== +rls *ale-rust-rls* + +g:ale_rust_rls_executable *g:ale_rust_rls_executable* + *b:ale_rust_rls_executable* + Type: |String| + Default: `'rls'` + + This variable can be modified to change the executable path for `rls`. + + +g:ale_rust_rls_toolchain *g:ale_rust_rls_toolchain* + *b:ale_rust_rls_toolchain* + Type: |String| + Default: `''` + + This option can be set to change the toolchain used for `rls`. Possible + values include `'nightly'`, `'beta'`, `'stable'`, and `''`. When using + option `''`, rls will automatically find the default toolchain set by + rustup. If you want to use `rls` from a specific toolchain version, you may + also use values like `'channel-yyyy-mm-dd-arch-target'` as long as + `'rls +{toolchain_name} -V'` runs correctly in your command line. + + The `rls` server will only be started once per executable. + + +g:ale_rust_rls_config *g:ale_rust_rls_config* + *b:ale_rust_rls_config* + Type: |Dictionary| + Default: `{}` + + Dictionary with configuration settings for rls. For example, to force + using clippy as linter: > + { + \ 'rust': { + \ 'clippy_preference': 'on' + \ } + \ } + + +=============================================================================== +rustc *ale-rust-rustc* + + +g:ale_rust_rustc_options *g:ale_rust_rustc_options* + *b:ale_rust_rustc_options* + Type: |String| + Default: `'-Z no-codegen'` + + The variable can be used to change the options passed to `rustc`. + + `-Z no-codegen` should only work with nightly builds of Rust. Be careful when + setting the options, as running `rustc` could execute code or generate + binary files. + + +g:ale_rust_ignore_error_codes *g:ale_rust_ignore_error_codes* + *b:ale_rust_ignore_error_codes* + Type: |List| of |String|s + Default: `[]` + + This variable can contain error codes which will be ignored. For example, to + ignore most errors regarding failed imports, put this in your .vimrc + > + let g:ale_rust_ignore_error_codes = ['E0432', 'E0433'] + +g:ale_rust_ignore_secondary_spans *g:ale_rust_ignore_secondary_spans* + *b:ale_rust_ignore_secondary_spans* + Type: Number + Default: 0 + + When set to 1, instructs the Rust error repporting to ignore secondary + spans. The problem with secondary spans is that they sometimes appear in + error messages before the main cause of the error, for example: > + + 1 src/main.rs|98 col 5 error| this function takes 4 parameters but 5 + parameters were supplied: defined here + 2 src/main.rs|430 col 32 error| this function takes 4 parameters but 5 + parameters were supplied: expected 4 parameters +< + This is due to the sorting by line numbers. With this option set to 1, + the 'defined here' span will not be presented. + +=============================================================================== +rustfmt *ale-rust-rustfmt* + +g:ale_rust_rustfmt_options *g:ale_rust_rustfmt_options* + *b:ale_rust_rustfmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the rustfmt fixer. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-sass.txt b/pack/acp/start/ale/doc/ale-sass.txt new file mode 100644 index 0000000..22d7c47 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-sass.txt @@ -0,0 +1,31 @@ +=============================================================================== +ALE Sass Integration *ale-sass-options* + + +=============================================================================== +sasslint *ale-sass-sasslint* + +See |ale-scss-sasslint| for information about the available options. + + +=============================================================================== +stylelint *ale-sass-stylelint* + +g:ale_sass_stylelint_executable *g:ale_sass_stylelint_executable* + *b:ale_sass_stylelint_executable* + Type: |String| + Default: `'stylelint'` + + See |ale-integrations-local-executables| + + +g:ale_sass_stylelint_use_global *g:ale_sass_stylelint_use_global* + *b:ale_sass_stylelint_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-scala.txt b/pack/acp/start/ale/doc/ale-scala.txt new file mode 100644 index 0000000..ff43cd6 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-scala.txt @@ -0,0 +1,98 @@ +=============================================================================== +ALE Scala Integration *ale-scala-options* + + +=============================================================================== +sbtserver *ale-scala-sbtserver* + +`sbtserver` requires a running ^1.1.x sbt shell to connect to. It will attempt +to connect via TCP to the address defined in `g:ale_scala_sbtserver_address`. +As `sbt` defaults to listening via unix sockets, place these settings into +your `~/.sbt/1.0/global.sbt` to ensure that ale will always attempt to connect +to the right socket: + +`serverConnectionType := ConnectionType.Tcp` and `serverPort := 4273` + + +g:ale_scala_sbtserver_address *g:ale_scala_sbtserver_address* + *b:ale_scala_sbtserver_address* + Type: |String| + Default: `'127.0.0.1:4273'` + + By default the address is found by parsing `active.json`, however, reading a + file is a blocking operation which should be avoided in ale. The easy way + around this is to configure sbt to always connect to the same port, which + the instructions above describe. + + +g:ale_scala_sbtserver_project_root *g:ale_scala_sbtserver_project_root* + *b:ale_scala_sbtserver_project_root* + Type: |String| + Default: `''` + + By default the project root is found by searching upwards for `build.sbt`. + If the project root is elsewhere, you can override the project root + directory. + + +=============================================================================== +scalafmt *ale-scala-scalafmt* + +If Nailgun is used, override `g:ale_scala_scalafmt_executable` like so: > + let g:ale_scala_scalafmt_executable = 'ng' + + +g:ale_scala_scalafmt_executable *g:ale_scala_scalafmt_executable* + *b:ale_scala_scalafmt_executable* + Type: |String| + Default: `'scalafmt'` + + Override the invoked `scalafmt` binary. This is useful for running `scalafmt` + with Nailgun. + + +g:ale_scala_scalafmt_options *g:ale_scala_scalafmt_options* + *b:ale_scala_scalafmt_options* + Type: |String| + Default: `''` + + A string containing additional options to pass to `'scalafmt'`, or + `'ng scalafmt'` if Nailgun is used. + + +=============================================================================== +scalastyle *ale-scala-scalastyle* + +`scalastyle` requires a configuration file for a project to run. When no +configuration file can be found, ALE will report a problem saying that a +configuration file is required at line 1. + +To disable `scalastyle` globally, use |g:ale_linters| like so: > + let g:ale_linters = {'scala': ['scalac']} " Enable only scalac instead +< + +See |g:ale_linters| for more information on disabling linters. + + +g:ale_scala_scalastyle_config *g:ale_scala_scalastyle_config* + *b:ale_scala_scalastyle_config* + Type: |String| + Default: `''` + + A string containing the location of a global fallback configuration file. + + By default, ALE will look for a configuration file named + `scalastyle_config.xml` or `scalastyle-config.xml` in the current file's + directory or parent directories. + + +g:ale_scala_scalastyle_options *g:ale_scala_scalastyle_options* + *b:ale_scala_scalastyle_options* + Type: |String| + Default: `''` + + A string containing additional options to pass to scalastyle. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-scss.txt b/pack/acp/start/ale/doc/ale-scss.txt new file mode 100644 index 0000000..07a94fe --- /dev/null +++ b/pack/acp/start/ale/doc/ale-scss.txt @@ -0,0 +1,64 @@ +=============================================================================== +ALE SCSS Integration *ale-scss-options* + + +=============================================================================== +prettier *ale-scss-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +sasslint *ale-scss-sasslint* + +g:ale_scss_sasslint_executable *g:ale_scss_sasslint_executable* + *b:ale_scss_sasslint_executable* + Type: |String| + Default: `'sass-lint'` + + See |ale-integrations-local-executables| + + +g:ale_scss_sasslint_options *g:ale_scss_sasslint_options* + *b:ale_scss_sasslint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to sass-lint. + + +g:ale_scss_sasslint_use_global *g:ale_scss_sasslint_use_global* + *b:ale_scss_sasslint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +stylelint *ale-scss-stylelint* + +g:ale_scss_stylelint_executable *g:ale_scss_stylelint_executable* + *b:ale_scss_stylelint_executable* + Type: |String| + Default: `'stylelint'` + + See |ale-integrations-local-executables| + +g:ale_scss_stylelint_options *g:ale_scss_stylelint_options* + *b:ale_scss_stylelint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to stylelint. + +g:ale_scss_stylelint_use_global *g:ale_scss_stylelint_use_global* + *b:ale_scss_stylelint_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-sh.txt b/pack/acp/start/ale/doc/ale-sh.txt new file mode 100644 index 0000000..3eac903 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-sh.txt @@ -0,0 +1,115 @@ +=============================================================================== +ALE Shell Integration *ale-sh-options* + + +=============================================================================== +sh-language-server *ale-sh-language-server* + +g:ale_sh_language_server_executable *g:ale_sh_language_server_executable* + *b:ale_sh_language_server_executable* + Type: |String| + Default: `'bash-language-server'` + + See |ale-integrations-local-executables| + + +g:ale_sh_language_server_use_global *g:ale_sh_language_server_use_global* + *b:ale_sh_language_server_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +shell *ale-sh-shell* + +g:ale_sh_shell_default_shell *g:ale_sh_shell_default_shell* + *b:ale_sh_shell_default_shell* + Type: |String| + Default: The current shell (`$SHELL`). Falls back to `'bash'` if that cannot be + read or if the current shell is `'fish'`. + + When ALE runs the linter for shells with the `-n` flag, it will attempt to + read the shell from the shebang (`#!`) line from the shell script to + determine the shell program to run. When this detection fails, this variable + will be used instead. + + +=============================================================================== +shellcheck *ale-sh-shellcheck* + +g:ale_sh_shellcheck_executable *g:ale_sh_shellcheck_executable* + *b:ale_sh_shellcheck_executable* + Type: |String| + Default: `'shellcheck'` + + This variable sets executable used for shellcheck. + + +g:ale_sh_shellcheck_options *g:ale_sh_shellcheck_options* + *b:ale_sh_shellcheck_options* + Type: |String| + Default: `''` + + With this variable we are able to pass extra arguments for shellcheck + for shellcheck invocation. + + For example, if we want shellcheck to follow external sources (`see SC1091`) + we can set the variable as such: +> + let g:ale_sh_shellcheck_options = '-x' +< + + +g:ale_sh_shellcheck_change_directory *g:ale_sh_shellcheck_change_directory* + *b:ale_sh_shellcheck_change_directory* + Type: |Number| + Default: `1` + + If set to `1`, ALE will switch to the directory the shell file being + checked with `shellcheck` is in before checking it. This helps `shellcheck` + determine the path to sourced files more easily. This option can be turned + off if you want to control the directory `shellcheck` is executed from + yourself. + + +g:ale_sh_shellcheck_dialect *g:ale_sh_shellcheck_dialect* + *b:ale_sh_shellcheck_dialect* + Type: |String| + Default: `'auto'` + + This variable specifies the shellcheck dialect (`-s` option). The value + `'auto'` causes ALE to detect the dialect automatically, based on the shebang + line (if present) or the value of `b:is_bash`, `b:is_sh`, or `b:is_kornshell` + (set and used by |sh.vim|). + + +g:ale_sh_shellcheck_exclusions *g:ale_sh_shellcheck_exclusions* + *b:ale_sh_shellcheck_exclusions* + Type: |String| + Default: `''` + + Set this variable to exclude test(s) for shellcheck (-e/--exclude option). + To exclude more than one option, separate them with commas. + + For example, to ignore some warnings that aren't applicable to files that + will be sourced by other scripts, use the buffer-local variant: +> + autocmd BufEnter PKGBUILD,.env + \ let b:ale_sh_shellcheck_exclusions = 'SC2034,SC2154,SC2164' +< + +=============================================================================== +shfmt *ale-sh-shfmt* + +g:ale_sh_shfmt_options *g:ale_sh_shfmt_options* + *b:ale_sh_shfmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the shfmt fixer. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-sml.txt b/pack/acp/start/ale/doc/ale-sml.txt new file mode 100644 index 0000000..cc8d679 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-sml.txt @@ -0,0 +1,36 @@ +=============================================================================== +ALE SML Integration *ale-sml-options* + +=============================================================================== +smlnj *ale-sml-smlnj* + *ale-sml-smlnj-cm* + +There are two SML/NJ powered checkers: + +- one using Compilation Manager that works on whole projects, but requires you + to save before errors show up +- one using the SML/NJ REPL that works as you change the text, but might fail + if your project can only be built with CM. + +We dynamically select which one to use based whether we find a `*.cm` file at +or above the directory of the file being checked. Only one checker (`smlnj`, +`smlnj-cm`) will be enabled at a time. + +------------------------------------------------------------------------------- + +g:ale_sml_smlnj_cm_file *g:ale_sml_smlnj_cm_file* + *b:ale_sml_smlnj_cm_file* + Type: |String| + Default: `'*.cm'` + + By default, ALE will look for a `*.cm` file in your current directory, + searching upwards. It stops when it finds at least one `*.cm` file (taking + the first file if there are more than one). + + Change this option (in the buffer or global scope) to control how ALE finds + CM files. For example, to always search for a CM file named `sandbox.cm`: +> + let g:ale_sml_smlnj_cm_file = 'sandbox.cm' + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-solidity.txt b/pack/acp/start/ale/doc/ale-solidity.txt new file mode 100644 index 0000000..4b74a27 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-solidity.txt @@ -0,0 +1,24 @@ +=============================================================================== +ALE Solidity Integration *ale-solidity-options* + + +=============================================================================== +solhint *ale-solidity-solhint* + + Solhint should work out-of-the-box. You can further configure it using a + `.solihint.json` file. See https://github.com/protofire/solhint for more + information. + + +=============================================================================== +solium *ale-solidity-solium* + + Use of Solium linter for Solidity source code requires a .soliumrc.json + file in project root. This file can be generated by running `solium --init`. + See the corresponding solium usage for detailed instructions + (https://github.com/duaraghav8/Solium#usage). + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/pack/acp/start/ale/doc/ale-spec.txt b/pack/acp/start/ale/doc/ale-spec.txt new file mode 100644 index 0000000..3da950c --- /dev/null +++ b/pack/acp/start/ale/doc/ale-spec.txt @@ -0,0 +1,43 @@ +=============================================================================== +ALE Spec Integration *ale-spec-options* + *ale-integration-spec* + +=============================================================================== +Integration Information + + The rpmlint linter is disabled by default, because running rpmlint can + result in the execution of code embedded in the spec file and rpmlint makes + no distinction between checks which are safe to run on untrusted files and + those which are not. + + Currently linters must be enabled globally. The rpmlint linter can be + enabled with: +> + let g:ale_linters = {'spec': ['rpmlint']} +< + +=============================================================================== +rpmlint *ale-spec-rpmlint* + +g:ale_spec_rpmlint_executable *g:ale_spec_rpmlint_executable* + *b:ale_spec_rpmlint_executable* + Type: |String| + Default: `'rpmlint'` + + This variable sets executable used for rpmlint. + + +g:ale_spec_rpmlint_options *g:ale_spec_rpmlint_options* + *b:ale_spec_rpmlint_options* + Type: |String| + Default: `''` + + Set this to pass extra arguments to rpmlint. + + For example, to instruct rpmlint to use a specific configuration file: +> + let g:ale_spec_rpmlint_options = '-f custom.cf' +< + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-sql.txt b/pack/acp/start/ale/doc/ale-sql.txt new file mode 100644 index 0000000..f9bc6ac --- /dev/null +++ b/pack/acp/start/ale/doc/ale-sql.txt @@ -0,0 +1,43 @@ +=============================================================================== +ALE SQL Integration *ale-sql-options* + + +=============================================================================== +pgformatter *ale-sql-pgformatter* + +g:ale_sql_pgformatter_executable *g:ale_sql_pgformatter_executable* + *b:ale_sql_pgformatter_executable* + Type: |String| + Default: `'pg_format'` + + This variable sets executable used for pgformatter. + +g:ale_sql_pgformatter_options *g:ale_sql_pgformatter_options* + *b:ale_sql_pgformatter_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the pgformatter fixer. + + +=============================================================================== +sqlfmt *ale-sql-sqlfmt* + +g:ale_sql_sqlfmt_executable *g:ale_sql_sqlfmt_executable* + *b:ale_sql_sqlfmt_executable* + Type: |String| + Default: `'sqlfmt'` + + This variable sets executable used for sqlfmt. + +g:ale_sql_sqlfmt_options *g:ale_sql_sqlfmt_options* + *b:ale_sql_sqlfmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the sqlfmt fixer. + At this time only the -u flag is available to format with upper-case. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-stylus.txt b/pack/acp/start/ale/doc/ale-stylus.txt new file mode 100644 index 0000000..3e6ba90 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-stylus.txt @@ -0,0 +1,33 @@ +=============================================================================== +ALE Stylus Integration *ale-stylus-options* + + +=============================================================================== +stylelint *ale-stylus-stylelint* + +g:ale_stylus_stylelint_executable *g:ale_stylus_stylelint_executable* + *b:ale_stylus_stylelint_executable* + Type: |String| + Default: `'stylelint'` + + See |ale-integrations-local-executables| + + +g:ale_stylus_stylelint_options *g:ale_stylus_stylelint_options* + *b:ale_stylus_stylelint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to stylelint. + + +g:ale_stylus_stylelint_use_global *g:ale_stylus_stylelint_use_global* + *b:ale_stylus_stylelint_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-sugarss.txt b/pack/acp/start/ale/doc/ale-sugarss.txt new file mode 100644 index 0000000..8e991e5 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-sugarss.txt @@ -0,0 +1,31 @@ +=============================================================================== +ALE SugarSS Integration *ale-sugarss-options* + + +=============================================================================== +stylelint *ale-sugarss-stylelint* + +g:ale_sugarss_stylelint_executable *g:ale_sugarss_stylelint_executable* + *b:ale_sugarss_stylelint_executable* + Type: |String| + Default: `'stylelint'` + + See |ale-integrations-local-executables| + +g:ale_sugarss_stylelint_options *g:ale_sugarss_stylelint_options* + *b:ale_sugarss_stylelint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to stylelint. + +g:ale_sugarss_stylelint_use_global *g:ale_sugarss_stylelint_use_global* + *b:ale_sugarss_stylelint_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-supported-languages-and-tools.txt b/pack/acp/start/ale/doc/ale-supported-languages-and-tools.txt new file mode 100644 index 0000000..f1087c2 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-supported-languages-and-tools.txt @@ -0,0 +1,488 @@ +*ale-supported-languages-and-tools.txt* For Vim version 8.0. +*ale-supported-list* + +ALE Supported Languages and Tools + +=============================================================================== + +The following languages and tools are supported by ALE. + +Notes: + +`^` No linters for text or Vim help filetypes are enabled by default. +`!!` These linters check only files on disk. See |ale-lint-file-linters| + +* Ada + * `gcc` +* Ansible + * `ansible-lint` +* API Blueprint + * `drafter` +* AsciiDoc + * `alex`!! + * `proselint` + * `redpen` + * `textlint` + * `vale` + * `write-good` +* ASM + * `gcc` +* Awk + * `gawk` +* Bash + * `language-server` + * `shell` (-n flag) + * `shellcheck` + * `shfmt` +* BibTeX + * `bibclean` +* Bourne Shell + * `shell` (-n flag) + * `shellcheck` + * `shfmt` +* C + * `ccls` + * `clang` + * `clangd` + * `clang-format` + * `clangtidy`!! + * `cppcheck` + * `cpplint`!! + * `cquery` + * `flawfinder` + * `gcc` + * `uncrustify` +* C# + * `mcs` + * `mcsc`!! + * `uncrustify` +* C++ (filetype cpp) + * `ccls` + * `clang` + * `clangcheck`!! + * `clangd` + * `clang-format` + * `clangtidy`!! + * `clazy`!! + * `cppcheck` + * `cpplint`!! + * `cquery` + * `flawfinder` + * `gcc` + * `uncrustify` +* Chef + * `cookstyle` + * `foodcritic` +* Clojure + * `clj-kondo` + * `joker` +* CloudFormation + * `cfn-python-lint` +* CMake + * `cmake-format` + * `cmakelint` +* CoffeeScript + * `coffee` + * `coffeelint` +* Crystal + * `ameba`!! + * `crystal`!! +* CSS + * `csslint` + * `fecs` + * `prettier` + * `stylelint` +* Cucumber + * `cucumber` +* CUDA + * `nvcc`!! +* Cypher + * `cypher-lint` +* Cython (pyrex filetype) + * `cython` +* D + * `dls` + * `dmd` + * `uncrustify` +* Dafny + * `dafny`!! +* Dart + * `dartanalyzer`!! + * `dartfmt`!! + * `language_server` +* Dockerfile + * `dockerfile_lint` + * `hadolint` +* Elixir + * `credo` + * `dialyxir` + * `dogma` + * `elixir-ls` + * `mix`!! +* Elm + * `elm-format` + * `elm-lsp` + * `elm-make` +* Erb + * `erb` + * `erubi` + * `erubis` + * `ruumba` +* Erlang + * `erlc` + * `SyntaxErl` +* Fish + * `fish` (-n flag) +* Fortran + * `gcc` + * `language_server` +* Fountain + * `proselint` +* FusionScript + * `fusion-lint` +* Git Commit Messages + * `gitlint` +* GLSL + * glslang + * `glslls` +* Go + * `bingo` + * `go build`!! + * `gofmt` + * `goimports` + * `golangci-lint`!! + * `golangserver` + * `golint` + * `gometalinter`!! + * `go mod`!! + * `gopls` + * `gosimple`!! + * `gotype`!! + * `go vet`!! + * `staticcheck`!! +* GraphQL + * `eslint` + * `gqlint` + * `prettier` +* Hack + * `hack` + * `hackfmt` + * `hhast` +* Haml + * `haml-lint` +* Handlebars + * `ember-template-lint` +* Haskell + * `brittany` + * `cabal-ghc` + * `floskell` + * `ghc` + * `ghc-mod` + * `hdevtools` + * `hfmt` + * `hie` + * `hlint` + * `stack-build`!! + * `stack-ghc` + * `stylish-haskell` +* HCL + * `terraform-fmt` +* HTML + * `alex`!! + * `fecs` + * `HTMLHint` + * `prettier` + * `proselint` + * `tidy` + * `write-good` +* Idris + * `idris` +* ISPC + * `ispc`!! +* Java + * `checkstyle` + * `eclipselsp` + * `google-java-format` + * `javac` + * `javalsp` + * `PMD` + * `uncrustify` +* JavaScript + * `eslint` + * `fecs` + * `flow` + * `jscs` + * `jshint` + * `prettier` + * `prettier-eslint` + * `prettier-standard` + * `standard` + * `tsserver` + * `xo` +* JSON + * `fixjson` + * `jq` + * `jsonlint` + * `prettier` +* Julia + * `languageserver` +* Kotlin + * `kotlinc`!! + * `ktlint`!! + * `languageserver` +* LaTeX (tex) + * `alex`!! + * `chktex` + * `lacheck` + * `proselint` + * `redpen` + * `texlab` + * `textlint` + * `vale` + * `write-good` +* Less + * `lessc` + * `prettier` + * `stylelint` +* LLVM + * `llc` +* Lua + * `luac` + * `luacheck` +* Mail + * `alex`!! + * `languagetool`!! + * `proselint` + * `vale` +* Make + * `checkmake` +* Markdown + * `alex`!! + * `languagetool`!! + * `markdownlint`!! + * `mdl` + * `prettier` + * `proselint` + * `redpen` + * `remark-lint` + * `textlint` + * `vale` + * `write-good` +* MATLAB + * `mlint` +* Mercury + * `mmc`!! +* NASM + * `nasm`!! +* Nim + * `nim check`!! +* nix + * `nix-instantiate` +* nroff + * `alex`!! + * `proselint` + * `write-good` +* Objective-C + * `ccls` + * `clang` + * `clangd` + * `uncrustify` +* Objective-C++ + * `clang` + * `clangd` + * `uncrustify` +* OCaml + * `merlin` (see |ale-ocaml-merlin|) + * `ocamlformat` + * `ocp-indent` + * `ols` +* Pawn + * `uncrustify` +* Perl + * `perl -c` + * `perl-critic` + * `perltidy` +* Perl6 + * `perl6 -c` +* PHP + * `langserver` + * `phan` + * `phpcbf` + * `phpcs` + * `php-cs-fixer` + * `php -l` + * `phpmd` + * `phpstan` + * `psalm`!! +* PO + * `alex`!! + * `msgfmt` + * `proselint` + * `write-good` +* Pod + * `alex`!! + * `proselint` + * `write-good` +* Pony + * `ponyc` +* PowerShell + * `powershell` + * `psscriptanalyzer` +* Prolog + * `swipl` +* proto + * `protoc-gen-lint` +* Pug + * `pug-lint` +* Puppet + * `languageserver` + * `puppet` + * `puppet-lint` +* Python + * `autopep8` + * `bandit` + * `black` + * `flake8` + * `isort` + * `mypy` + * `prospector` + * `pycodestyle` + * `pydocstyle` + * `pyflakes` + * `pylama`!! + * `pylint`!! + * `pyls` + * `pyre` + * `reorder-python-imports` + * `vulture`!! + * `yapf` +* QML + * `qmlfmt` + * `qmllint` +* R + * `lintr` + * `styler` +* Racket + * `raco` +* ReasonML + * `merlin` + * `ols` + * `reason-language-server` + * `refmt` +* reStructuredText + * `alex`!! + * `proselint` + * `redpen` + * `rstcheck` + * `textlint` + * `vale` + * `write-good` +* Re:VIEW + * `redpen` +* RPM spec + * `rpmlint` +* Ruby + * `brakeman` + * `rails_best_practices`!! + * `reek` + * `rubocop` + * `ruby` + * `rufo` + * `solargraph` + * `standardrb` +* Rust + * `cargo`!! + * `rls` + * `rustc` (see |ale-integration-rust|) + * `rustfmt` +* Sass + * `sass-lint` + * `stylelint` +* Scala + * `fsc` + * `sbtserver` + * `scalac` + * `scalafmt` + * `scalastyle` +* SCSS + * `prettier` + * `sass-lint` + * `scss-lint` + * `stylelint` +* Slim + * `slim-lint` +* SML + * `smlnj` +* Solidity + * `solhint` + * `solium` +* SQL + * `pgformatter` + * `sqlfmt` + * `sqlint` +* Stylus + * `stylelint` +* SugarSS + * `stylelint` +* Swift + * `sourcekit-lsp` + * `swiftformat` + * `swiftlint` +* Tcl + * `nagelfar`!! +* Terraform + * `fmt` + * `tflint` +* Texinfo + * `alex`!! + * `proselint` + * `write-good` +* Text^ + * `alex`!! + * `languagetool`!! + * `proselint` + * `redpen` + * `textlint` + * `vale` + * `write-good` +* Thrift + * `thrift` +* TypeScript + * `eslint` + * `fecs` + * `prettier` + * `tslint` + * `tsserver` + * `typecheck` +* VALA + * `uncrustify` +* Verilog + * `iverilog` + * `verilator` + * `vlog` + * `xvlog` +* VHDL + * `ghdl` + * `vcom` + * `xvhdl` +* Vim + * `vint` +* Vim help^ + * `alex`!! + * `proselint` + * `write-good` +* Vue + * `prettier` + * `vls` +* XHTML + * `alex`!! + * `proselint` + * `write-good` +* XML + * `xmllint` +* YAML + * `prettier` + * `swaglint` + * `yamllint` +* YANG + * `yang-lsp` diff --git a/pack/acp/start/ale/doc/ale-swift.txt b/pack/acp/start/ale/doc/ale-swift.txt new file mode 100644 index 0000000..8fa0c06 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-swift.txt @@ -0,0 +1,21 @@ +=============================================================================== +ALE Swift Integration *ale-swift-options* + + +=============================================================================== +sourcekitlsp *ale-swift-sourcekitlsp* + +To enable the SourceKit-LSP you need to install and build the executable as +described here: https://github.com/apple/sourcekit-lsp#building-sourcekit-lsp + + +g:ale_sourcekit_lsp_executable *g:ale_sourcekit_lsp_executable* + *b:ale_sourcekit_lsp_executable* + Type: |String| + Default: `'sourcekit-lsp'` + + See |ale-integrations-local-executables| + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/pack/acp/start/ale/doc/ale-tcl.txt b/pack/acp/start/ale/doc/ale-tcl.txt new file mode 100644 index 0000000..497c9fd --- /dev/null +++ b/pack/acp/start/ale/doc/ale-tcl.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE Tcl Integration *ale-tcl-options* + + +=============================================================================== +nagelfar *ale-tcl-nagelfar* + +g:ale_tcl_nagelfar_executable *g:ale_tcl_nagelfar_executable* + *b:ale_tcl_nagelfar_executable* + Type: |String| + Default: `'nagelfar.tcl'` + + This variable can be changed to change the path to nagelfar. + + +g:ale_tcl_nagelfar_options *g:ale_tcl_nagelfar_options* + *b:ale_tcl_nagelfar_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to nagelfar. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-terraform.txt b/pack/acp/start/ale/doc/ale-terraform.txt new file mode 100644 index 0000000..387fd73 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-terraform.txt @@ -0,0 +1,59 @@ +=============================================================================== +ALE Terraform Integration *ale-terraform-options* + + +=============================================================================== +terraform-fmt-fixer *ale-terraform-fmt-fixer* + +g:ale_terraform_fmt_executable *g:ale_terraform_fmt_executable* + *b:ale_terraform_fmt_executable* + + Type: |String| + Default: `'terraform'` + + This variable can be changed to use a different executable for terraform. + + +g:ale_terraform_fmt_options *g:ale_terraform_fmt_options* + *b:ale_terraform_fmt_options* + Type: |String| + Default: `''` + + +=============================================================================== +terraform *ale-terraform-terraform* + +g:ale_terraform_terraform_executable *g:ale_terraform_terraform_executable* + *b:ale_terraform_terraform_executable* + + Type: |String| + Default: `'terraform'` + + This variable can be changed to use a different executable for terraform. + + +=============================================================================== +tflint *ale-terraform-tflint* + +g:ale_terraform_tflint_executable *g:ale_terraform_tflint_executable* + *b:ale_terraform_tflint_executable* + + Type: |String| + Default: `'tflint'` + + This variable can be changed to use a different executable for tflint. + + +g:ale_terraform_tflint_options *g:ale_terraform_tflint_options* + *b:ale_terraform_tflint_options* + Type: |String| + Default: `'-f json'` + + This variable can be changed to pass different options to tflint. Ale does + expect json output from tflint, so if you change this, you'll probably want + to include '-f json' in your new value. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/pack/acp/start/ale/doc/ale-tex.txt b/pack/acp/start/ale/doc/ale-tex.txt new file mode 100644 index 0000000..ceb9fa8 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-tex.txt @@ -0,0 +1,77 @@ +=============================================================================== +ALE TeX Integration *ale-tex-options* + + +=============================================================================== +chktex *ale-tex-chktex* + +g:ale_tex_chktex_executable *g:ale_tex_chktex_executable* + *b:ale_tex_chktex_executable* + Type: |String| + Default: `'chktex'` + + This variable can be changed to change the path to chktex. + + +g:ale_tex_chktex_options *g:ale_tex_chktex_options* + *b:ale_tex_chktex_options* + Type: |String| + Default: `'-I'` + + This variable can be changed to modify flags given to chktex. + + +------------------------------------------------------------------------------ +lacheck *ale-tex-lacheck* + +g:ale_lacheck_executable *g:ale_lacheck_executable* + *b:ale_lacheck_executable* + Type: |String| + Default: '`lacheck`' + + This variable can be changed to change the path to lacheck. + + + +=============================================================================== +latexindent *ale-tex-latexindent* + +g:ale_tex_latexindent_executable *g:ale_tex_latexindent_executable* + *b:ale_tex_latexindent_executable* + Type: |String| + Default: `'latexindent'` + + This variable can be changed to change the path to latexindent. + + +g:ale_tex_latexindent_options *g:ale_tex_latexindent_options* + *b:ale_tex_latexindent_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to latexindent. + + + +=============================================================================== +texlab *ale-tex-texlab* + +g:ale_tex_texlab_executable *g:ale_tex_texlab_executable* + *b:ale_tex_texlab_executable* + Type: |String| + Default: `'texlab'` + + This variable can be changed to change the path to texlab. + + +g:ale_tex_texlab_options *g:ale_tex_texlab_options* + *b:ale_tex_texlab_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to texlab. + + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-texinfo.txt b/pack/acp/start/ale/doc/ale-texinfo.txt new file mode 100644 index 0000000..f8ed342 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-texinfo.txt @@ -0,0 +1,12 @@ +=============================================================================== +ALE Texinfo Integration *ale-texinfo-options* + + +=============================================================================== +write-good *ale-texinfo-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-text.txt b/pack/acp/start/ale/doc/ale-text.txt new file mode 100644 index 0000000..913d7e6 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-text.txt @@ -0,0 +1,42 @@ +=============================================================================== +ALE Text Integration *ale-text-options* + + +=============================================================================== +textlint *ale-text-textlint* + +The options for the textlint linter are global because it does not make +sense to have them specified on a per-language basis. + +g:ale_textlint_executable *g:ale_textlint_executable* + *b:ale_textlint_executable* + Type: |String| + Default: `'textlint'` + + See |ale-integrations-local-executables| + + +g:ale_textlint_options *g:ale_textlint_options* + *b:ale_textlint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to textlint. + + +g:ale_textlint_use_global *g:ale_textlint_use_global* + *b:ale_textlint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +write-good *ale-text-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-thrift.txt b/pack/acp/start/ale/doc/ale-thrift.txt new file mode 100644 index 0000000..bb2ec05 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-thrift.txt @@ -0,0 +1,46 @@ +=============================================================================== +ALE Thrift Integration *ale-thrift-options* + + +=============================================================================== +thrift *ale-thrift-thrift* + +The `thrift` linter works by compiling the buffer's contents and reporting any +errors reported by the parser and the configured code generator(s). + +g:ale_thrift_thrift_executable *g:ale_thrift_thrift_executable* + *b:ale_thrift_thrift_executable* + Type: |String| + Default: `'thrift'` + + See |ale-integrations-local-executables| + + +g:ale_thrift_thrift_generators *g:ale_thrift_thrift_generators* + *b:ale_thrift_thrift_generators* + Type: |List| of |String|s + Default: `['cpp']` + + This list must contain one or more named code generators. Generator options + can be included as part of each string, e.g. `['py:dynamic']`. + + +g:ale_thrift_thrift_includes *g:ale_thrift_thrift_includes* + *b:ale_thrift_thrift_includes* + Type: |List| of |String|s + Default: `['.']` + + This list contains paths that will be searched for thrift `include` + directives. + + +g:ale_thrift_thrift_options *g:ale_thrift_thrift_options* + *b:ale_thrift_thrift_options* + Type: |String| + Default: `'-strict'` + + This variable can be changed to customize the additional command-line + arguments that are passed to the thrift compiler. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-typescript.txt b/pack/acp/start/ale/doc/ale-typescript.txt new file mode 100644 index 0000000..7dc5982 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-typescript.txt @@ -0,0 +1,115 @@ +=============================================================================== +ALE TypeScript Integration *ale-typescript-options* + + +=============================================================================== +eslint *ale-typescript-eslint* + +Because of how TypeScript compiles code to JavaScript and how interrelated +the two languages are, the `eslint` linter for TypeScript uses the JavaScript +options for `eslint` too. See: |ale-javascript-eslint|. + + +=============================================================================== +prettier *ale-typescript-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +tslint *ale-typescript-tslint* + +This linter isn't recommended, because TSLint can't be used for checking for +problems while you type. You should probably use the tsserver plugin instead. +tsserver plugins are described here: +https://github.com/Microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin + +Follow the instructions on the plugin website for installing it: +https://github.com/Microsoft/typescript-tslint-plugin + +Then disable TSLint in vimrc or any other Vim configuration file. > + let g:ale_linters_ignore = {'typescript': ['tslint']} +< + +g:ale_typescript_tslint_executable *g:ale_typescript_tslint_executable* + *b:ale_typescript_tslint_executable* + Type: |String| + Default: `'tslint'` + + See |ale-integrations-local-executables| + + +g:ale_typescript_tslint_config_path *g:ale_typescript_tslint_config_path* + *b:ale_typescript_tslint_config_path* + Type: |String| + Default: `''` + + ALE will first discover the tslint.json path in an ancestor directory. If no + such path exists, this variable will be used instead. + + +g:ale_typescript_tslint_ignore_empty_files + *g:ale_typescript_tslint_ignore_empty_files* + *b:ale_typescript_tslint_ignore_empty_files* + Type: |Number| + Default: `0` + + When set to `1`, ALE will not report any problems for empty files with + TSLint. ALE will still execute TSLint for the files, but ignore any problems + reported. This stops ALE from complaining about newly created files, + and files where lines have been added and then removed. + + +g:ale_typescript_tslint_rules_dir *g:ale_typescript_tslint_rules_dir* + *b:ale_typescript_tslint_rules_dir* + Type: |String| + Default: `''` + + If this variable is set, ALE will use it as the rules directory for tslint. + + +g:ale_typescript_tslint_use_global *g:ale_typescript_tslint_use_global* + *b:ale_typescript_tslint_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +tsserver *ale-typescript-tsserver* + +g:ale_typescript_tsserver_executable *g:ale_typescript_tsserver_executable* + *b:ale_typescript_tsserver_executable* + Type: |String| + Default: `'tsserver'` + + ALE will first discover the tsserver path in an ancestor node_modules + directory. If no such path exists, this variable will be used instead. + + If you wish to use only a globally installed version of tsserver, set + |g:ale_typescript_tsserver_use_global| to `1`. + + +g:ale_typescript_tsserver_config_path *g:ale_typescript_tsserver_config_path* + *b:ale_typescript_tsserver_config_path* + Type: |String| + Default: `''` + + ALE will first discover the tsserver.json path in an ancestor directory. If + no such path exists, this variable will be used instead. + + +g:ale_typescript_tsserver_use_global *g:ale_typescript_tsserver_use_global* + *b:ale_typescript_tsserver_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + This variable controls whether or not ALE will search for a local path for + tsserver first. If this variable is set to `1`, then ALE will always use the + global version of tsserver, in preference to locally installed versions of + tsserver in node_modules. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-vala.txt b/pack/acp/start/ale/doc/ale-vala.txt new file mode 100644 index 0000000..ca24bcf --- /dev/null +++ b/pack/acp/start/ale/doc/ale-vala.txt @@ -0,0 +1,12 @@ +=============================================================================== +ALE VALA Integration *ale-vala-options* + + +=============================================================================== +uncrustify *ale-vala-uncrustify* + +See |ale-c-uncrustify| for information about the available options. + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-verilog.txt b/pack/acp/start/ale/doc/ale-verilog.txt new file mode 100644 index 0000000..94b820b --- /dev/null +++ b/pack/acp/start/ale/doc/ale-verilog.txt @@ -0,0 +1,102 @@ +=============================================================================== +ALE Verilog/SystemVerilog Integration *ale-verilog-options* + + +=============================================================================== +ALE can use four different linters for Verilog HDL: + + iverilog: + Using `iverilog -t null -Wall` + + verilator + Using `verilator --lint-only -Wall` + + ModelSim/Questa + Using `vlog -quiet -lint` + + Vivado + Using `xvlog` + +By default, both 'verilog' and 'systemverilog' filetypes are checked. + +You can limit 'systemverilog' files to be checked using only 'verilator' by +defining 'g:ale_linters' variable: +> + au FileType systemverilog + \ let g:ale_linters = {'systemverilog' : ['verilator'],} +< + +Linters/compilers that utilize a "work" directory for analyzing designs- such +as ModelSim and Vivado- can be passed the location of these directories as +part of their respective option strings listed below. This is useful for +holistic analysis of a file (e.g. a design with components, packages, or other +code defined external to the current file as part of a larger project) or +when wanting to simply pass an alternative location for the auto-generated +work directories (such as '/tmp') so as to not muddle the current directory. +Since these type of linters often use this work directory for holding compiled +design data as part of a single build process, they sometimes cannot handle +the frequent, asynchronous application launches when linting while text is +changing. This can happen in the form of hangs or crashes. To help prevent +this when using these linters, it may help to run linting less frequently; for +example, only when a file is saved. + +=============================================================================== +iverilog *ale-verilog-iverilog* + + No additional options + + +=============================================================================== +verilator *ale-verilog-verilator* + +g:ale_verilog_verilator_options *g:ale_verilog_verilator_options* + *b:ale_verilog_verilator_options* + Type: |String| + Default: `''` + + This variable can be changed to modify 'verilator' command arguments + + For example `'-sv --default-language "1800-2012"'` if you want to enable + SystemVerilog parsing and select the 2012 version of the language. + + +=============================================================================== +vlog *ale-verilog-vlog* + +g:ale_verilog_vlog_executable *g:ale_verilog_vlog_executable* + *b:ale_verilog_vlog_executable* + Type: |String| + Default: `'vlog'` + + This variable can be changed to the path to the 'vlog' executable. + + +g:ale_verilog_vlog_options *g:ale_verilog_vlog_options* + *b:ale_verilog_vlog_options* + Type: |String| + Default: `'-quiet -lint'` + + This variable can be changed to modify the flags/options passed to 'vlog'. + + +=============================================================================== +xvlog *ale-verilog-xvlog* + +g:ale_verilog_xvlog_executable *g:ale_verilog_xvlog_executable* + *b:ale_verilog_xvlog_executable* + Type: |String| + Default: `'xvlog'` + + This variable can be changed to the path to the 'xvlog' executable. + + +g:ale_verilog_xvlog_options *g:ale_verilog_xvlog_options* + *b:ale_verilog_xvlog_options* + Type: |String| + Default: `''` + + This variable can be changed to modify the flags/options passed to 'xvlog'. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-vhdl.txt b/pack/acp/start/ale/doc/ale-vhdl.txt new file mode 100644 index 0000000..3fea947 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-vhdl.txt @@ -0,0 +1,92 @@ +=============================================================================== +ALE VHDL Integration *ale-vhdl-options* + + +=============================================================================== +ALE can use three different linters for VHDL: + + iverilog: + Using `iverilog -t null -Wall` + + ModelSim/Questa + Using `vcom -2008 -quiet -lint` + + Vivado + Using `xvhdl --2008` + +Note all linters default to VHDL-2008 support. This, and other options, can be +changed with each linter's respective option variable. + +Linters/compilers that utilize a "work" directory for analyzing designs- such +as ModelSim and Vivado- can be passed the location of these directories as +part of their respective option strings listed below. This is useful for +holistic analysis of a file (e.g. a design with components, packages, or other +code defined external to the current file as part of a larger project) or +when wanting to simply pass an alternative location for the auto-generated +work directories (such as '/tmp') so as to not muddle the current directory. +Since these type of linters often use this work directory for holding compiled +design data as part of a single build process, they sometimes cannot handle +the frequent, asynchronous application launches when linting while text is +changing. This can happen in the form of hangs or crashes. To help prevent +this when using these linters, it may help to run linting less frequently; for +example, only when a file is saved. + +=============================================================================== +ghdl *ale-vhdl-ghdl* + +g:ale_vhdl_ghdl_executable *g:ale_vhdl_ghdl_executable* + *b:ale_vhdl_ghdl_executable* + Type: |String| + Default: `'ghdl'` + + This variable can be changed to the path to the 'ghdl' executable. + + +g:ale_vhdl_ghdl_options *g:ale_vhdl_ghdl_options* + *b:ale_vhdl_ghdl_options* + Type: |String| + Default: `'--std=08'` + + This variable can be changed to modify the flags/options passed to 'ghdl'. + + +=============================================================================== +vcom *ale-vhdl-vcom* + +g:ale_vhdl_vcom_executable *g:ale_vhdl_vcom_executable* + *b:ale_vhdl_vcom_executable* + Type: |String| + Default: `'vcom'` + + This variable can be changed to the path to the 'vcom' executable. + + +g:ale_vhdl_vcom_options *g:ale_vhdl_vcom_options* + *b:ale_vhdl_vcom_options* + Type: |String| + Default: `'-2008 -quiet -lint'` + + This variable can be changed to modify the flags/options passed to 'vcom'. + + +=============================================================================== +xvhdl *ale-vhdl-xvhdl* + +g:ale_vhdl_xvhdl_executable *g:ale_vhdl_xvhdl_executable* + *b:ale_vhdl_xvhdl_executable* + Type: |String| + Default: `'xvhdl'` + + This variable can be changed to the path to the 'xvhdl' executable. + + +g:ale_vhdl_xvhdl_options *g:ale_vhdl_xvhdl_options* + *b:ale_vhdl_xvhdl_options* + Type: |String| + Default: `'--2008'` + + This variable can be changed to modify the flags/options passed to 'xvhdl'. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-vim-help.txt b/pack/acp/start/ale/doc/ale-vim-help.txt new file mode 100644 index 0000000..3cbe20d --- /dev/null +++ b/pack/acp/start/ale/doc/ale-vim-help.txt @@ -0,0 +1,12 @@ +=============================================================================== +ALE Vim help Integration *ale-vim-help-options* + + +=============================================================================== +write-good *ale-vim-help-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-vim.txt b/pack/acp/start/ale/doc/ale-vim.txt new file mode 100644 index 0000000..772bad2 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-vim.txt @@ -0,0 +1,27 @@ +=============================================================================== +ALE Vim Integration *ale-vim-options* + + +=============================================================================== +vint *ale-vim-vint* + +g:ale_vim_vint_executable *g:ale_vim_vint_executable* + *b:ale_vim_vint_executable* + Type: |String| + Default: `'vint'` + + This option can be set to change the executable path for Vint. + + +g:ale_vim_vint_show_style_issues *g:ale_vim_vint_show_style_issues* + *b:ale_vim_vint_show_style_issues* + Type: |Number| + Default: `1` + + This variable will enable/disable style issues for Vint. When this option + is disabled, only warnings and errors which are not purely style issues + will be reported. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-vue.txt b/pack/acp/start/ale/doc/ale-vue.txt new file mode 100644 index 0000000..a2c2786 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-vue.txt @@ -0,0 +1,31 @@ +=============================================================================== +ALE Vue Integration *ale-vue-options* + + +=============================================================================== +prettier *ale-vue-prettier* + +See |ale-javascript-prettier| for information about the available options. + + +=============================================================================== +vls *ale-vue-vls* + +g:ale_vue_vls_executable *g:ale_vue_vls_executable* + *b:ale_vue_vls_executable* + Type: |String| + Default: `'vls'` + + See |ale-integrations-local-executables| + + +g:ale_vue_vls_use_global *g:ale_vue_vls_use_global* + *b:ale_vue_vls_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-xhtml.txt b/pack/acp/start/ale/doc/ale-xhtml.txt new file mode 100644 index 0000000..3cc639e --- /dev/null +++ b/pack/acp/start/ale/doc/ale-xhtml.txt @@ -0,0 +1,12 @@ +=============================================================================== +ALE XHTML Integration *ale-xhtml-options* + + +=============================================================================== +write-good *ale-xhtml-write-good* + +See |ale-write-good-options| + + +=============================================================================== +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-xml.txt b/pack/acp/start/ale/doc/ale-xml.txt new file mode 100644 index 0000000..e43fdef --- /dev/null +++ b/pack/acp/start/ale/doc/ale-xml.txt @@ -0,0 +1,34 @@ +=============================================================================== +ALE XML Integration *ale-xml-options* + + +=============================================================================== +xmllint *ale-xml-xmllint* + +g:ale_xml_xmllint_executable *g:ale_xml_xmllint_executable* + *b:ale_xml_xmllint_executable* + Type: |String| + Default: `'xmllint'` + + This variable can be set to change the path to xmllint. + + +g:ale_xml_xmllint_options *g:ale_xml_xmllint_options* + *b:ale_xml_xmllint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to xmllint. + + +g:ale_xml_xmllint_indentsize *g:ale_xml_xmllint_indentsize* + *b:ale_xml_xmllint_indentsize* + Type: |Number| + Default: 2 + + This variable can be sent to specify the amount of spaces used for + indentation. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/pack/acp/start/ale/doc/ale-yaml.txt b/pack/acp/start/ale/doc/ale-yaml.txt new file mode 100644 index 0000000..c9a12ea --- /dev/null +++ b/pack/acp/start/ale/doc/ale-yaml.txt @@ -0,0 +1,92 @@ +=============================================================================== +ALE YAML Integration *ale-yaml-options* + +=============================================================================== +prettier *ale-yaml-prettier* + +Website: https://github.com/prettier/prettier + + +Installation +------------------------------------------------------------------------------- + +Install prettier either globally or locally: > + + npm install prettier -g # global + npm install prettier # local +< + +=============================================================================== +swaglint *ale-yaml-swaglint* + +Website: https://github.com/byCedric/swaglint + + +Installation +------------------------------------------------------------------------------- + +Install swaglint either globally or locally: > + + npm install swaglint -g # global + npm install swaglint # local +< + +Options +------------------------------------------------------------------------------- + +g:ale_yaml_swaglint_executable *g:ale_yaml_swaglint_executable* + *b:ale_yaml_swaglint_executable* + Type: |String| + Default: `'swaglint'` + + This variable can be set to change the path to swaglint. + + +g:ale_yaml_swaglint_use_global *g:ale_yaml_swaglint_use_global* + *b:ale_yaml_swaglint_use_global* + Type: |String| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +=============================================================================== +yamllint *ale-yaml-yamllint* + +Website: https://github.com/adrienverge/yamllint + + +Installation +------------------------------------------------------------------------------- + +Install yamllint in your a virtualenv directory, locally, or globally: > + + pip install yamllint # After activating virtualenv + pip install --user yamllint # Install to ~/.local/bin + sudo pip install yamllint # Install globally + +See |g:ale_virtualenv_dir_names| for configuring how ALE searches for +virtualenv directories. + + +Options +------------------------------------------------------------------------------- + +g:ale_yaml_yamllint_executable *g:ale_yaml_yamllint_executable* + *b:ale_yaml_yamllint_executable* + Type: |String| + Default: `'yamllint'` + + This variable can be set to change the path to yamllint. + + +g:ale_yaml_yamllint_options *g:ale_yaml_yamllint_options* + *b:ale_yaml_yamllint_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to yamllint. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale-yang.txt b/pack/acp/start/ale/doc/ale-yang.txt new file mode 100644 index 0000000..ad61973 --- /dev/null +++ b/pack/acp/start/ale/doc/ale-yang.txt @@ -0,0 +1,17 @@ +=============================================================================== +ALE YANG Integration *ale-yang-options* + + +=============================================================================== +yang-lsp *ale-yang-lsp* + +g:ale_yang_lsp_executable *g:ale_yang_lsp_executable* + *b:ale_yang_lsp_executable* + Type: |String| + Default: `'yang-language-server'` + + This variable can be changed to use a different executable for yang-lsp. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/doc/ale.txt b/pack/acp/start/ale/doc/ale.txt new file mode 100644 index 0000000..6aa03a1 --- /dev/null +++ b/pack/acp/start/ale/doc/ale.txt @@ -0,0 +1,3378 @@ +*ale.txt* Plugin to lint and fix files asynchronously +*ale* + +ALE - Asynchronous Lint Engine + +=============================================================================== +CONTENTS *ale-contents* + + 1. Introduction.........................|ale-introduction| + 2. Supported Languages & Tools..........|ale-support| + 3. Linting..............................|ale-lint| + 3.1 Other Sources.....................|ale-lint-other-sources| + 4. Fixing Problems......................|ale-fix| + 5. Language Server Protocol Support.....|ale-lsp| + 5.1 Completion........................|ale-completion| + 5.2 Go To Definition..................|ale-go-to-definition| + 5.3 Go To Type Definition.............|ale-go-to-type-definition| + 5.4 Find References...................|ale-find-references| + 5.5 Hovering..........................|ale-hover| + 5.6 Symbol Search.....................|ale-symbol-search| + 6. Global Options.......................|ale-options| + 6.1 Highlights........................|ale-highlights| + 7. Linter/Fixer Options.................|ale-integration-options| + 7.1 Options for alex..................|ale-alex-options| + 7.2 Options for languagetool..........|ale-languagetool-options| + 7.3 Options for write-good............|ale-write-good-options| + 7.4 Other Linter/Fixer Options........|ale-other-integration-options| + 8. Commands/Keybinds....................|ale-commands| + 9. API..................................|ale-api| + 10. Special Thanks......................|ale-special-thanks| + 11. Contact.............................|ale-contact| + +=============================================================================== +1. Introduction *ale-introduction* + +ALE provides the means to run linters asynchronously in Vim in a variety of +languages and tools. ALE sends the contents of buffers to linter programs +using the |job-control| features available in Vim 8 and NeoVim. For Vim 8, +Vim must be compiled with the |job| and |channel| and |timers| features +as a minimum. + +ALE supports the following key features for linting: + +1. Running linters when text is changed. +2. Running linters when files are opened. +3. Running linters when files are saved. (When a global flag is set.) +4. Populating the |loclist| with warning and errors. +5. Setting |signs| with warnings and errors for error markers. +6. Using |echo| to show error messages when the cursor moves. +7. Setting syntax highlights for errors. + +ALE can fix problems with files with the |ALEFix| command, using the same job +control functionality used for checking for problems. Try using the +|ALEFixSuggest| command for browsing tools that can be used to fix problems +for the current buffer. + +If you are interested in contributing to the development of ALE, read the +developer documentation. See |ale-development| + +=============================================================================== +2. Supported Languages & Tools *ale-support* + +ALE supports a wide variety of languages and tools. See |ale-supported-list| +for the full list. + +=============================================================================== +3. Linting *ale-lint* + +ALE's primary focus is on checking for problems with your code with various +programs via some Vim code for integrating with those programs, referred to +as 'linters.' ALE supports a wide array of programs for linting by default, +but additional programs can be added easily by defining files in |runtimepath| +with the filename pattern `ale_linters//.vim`. For more +information on defining new linters, see the extensive documentation +for |ale#linter#Define()|. + +Without any configuration, ALE will attempt to check all of the code for every +file you open in Vim with all available tools by default. To see what ALE +is doing, and what options have been set, try using the |:ALEInfo| command. + +Most of the linters ALE runs will check the Vim buffer you are editing instead +of the file on disk. This allows you to check your code for errors before you +have even saved your changes. ALE will check your code in the following +circumstances, which can be configured with the associated options. + +* When you modify a buffer. - |g:ale_lint_on_text_changed| +* On leaving insert mode. - |g:ale_lint_on_insert_leave| +* When you open a new or modified buffer. - |g:ale_lint_on_enter| +* When you save a buffer. - |g:ale_lint_on_save| +* When the filetype changes for a buffer. - |g:ale_lint_on_filetype_changed| +* If ALE is used to check code manually. - |:ALELint| + + *ale-lint-settings-on-startup* + +It is worth reading the documentation for every option. You should configure +which events ALE will use before ALE is loaded, so it can optimize which +autocmd commands to run. You can force autocmd commands to be reloaded with +`:ALEDisable | ALEEnable` + +This also applies to the autocmd commands used for |g:ale_echo_cursor|. + + *ale-lint-file-linters* + +Some programs must be run against files which have been saved to disk, and +simply do not support reading temporary files or stdin, either of which are +required for ALE to be able to check for errors as you type. The programs +which behave this way are documented in the lists and tables of supported +programs. ALE will only lint files with these programs in the following +circumstances. + +* When you open a new or modified buffer. - |g:ale_lint_on_enter| +* When you save a buffer. - |g:ale_lint_on_save| +* When the filetype changes for a buffer. - |g:ale_lint_on_filetype_changed| +* If ALE is used to check code manually. - |:ALELint| + +ALE will report problems with your code in the following ways, listed with +their relevant options. + +* By updating loclist. (On by default) - |g:ale_set_loclist| +* By updating quickfix. (Off by default) - |g:ale_set_quickfix| +* By setting error highlights. - |g:ale_set_highlights| +* By creating signs in the sign column. - |g:ale_set_signs| +* By echoing messages based on your cursor. - |g:ale_echo_cursor| +* By inline text based on your cursor. - |g:ale_virtualtext_cursor| +* By displaying the preview based on your cursor. - |g:ale_cursor_detail| +* By showing balloons for your mouse cursor - |g:ale_set_balloons| + +Please consult the documentation for each option, which can reveal some other +ways of tweaking the behaviour of each way of displaying problems. You can +disable or enable whichever options you prefer. + +Most settings can be configured for each buffer. (|b:| instead of |g:|), +including disabling ALE for certain buffers with |b:ale_enabled|. The +|g:ale_pattern_options| setting can be used to configure files differently +based on regular expressions for filenames. For configuring entire projects, +the buffer-local options can be used with external plugins for reading Vim +project configuration files. Buffer-local settings can also be used in +ftplugin files for different filetypes. + +ALE offers several options for controlling which linters are run. + +* Selecting linters to run. - |g:ale_linters| +* Aliasing filetypes for linters - |g:ale_linter_aliases| +* Only running linters you asked for. - |g:ale_linters_explicit| +* Disabling only a subset of linters. - |g:ale_linters_ignore| +* Disabling LSP linters and `tsserver`. - |g:ale_disable_lsp| + + +------------------------------------------------------------------------------- +3.1 Other Sources *ale-lint-other-sources* + +Problems for a buffer can be taken from other sources and rendered by ALE. +This allows ALE to be used in combination with other plugins which also want +to display any problems they might find with a buffer. ALE's API includes the +following components for making this possible. + +* |ale#other_source#StartChecking()| - Tell ALE that a buffer is being checked. +* |ale#other_source#ShowResults()| - Show results from another source. +* |ALEWantResults| - A signal for when ALE wants results. + +Other resources can provide results for ALE to display at any time, following +ALE's loclist format. (See |ale-loclist-format|) For example: > + + " Tell ALE to show some results. + " This function can be called at any time. + call ale#other_source#ShowResults(bufnr(''), 'some-linter-name', [ + \ {'text': 'Something went wrong', 'lnum': 13}, + \]) +< + +Other sources should use a unique name for identifying themselves. A single +linter name can be used for all problems from another source, or a series of +unique linter names can be used. Results can be cleared for that source by +providing an empty List. + +|ale#other_source#StartChecking()| should be called whenever another source +starts checking a buffer, so other tools can know that a buffer is being +checked by some plugin. The |ALEWantResults| autocmd event can be used to +start checking a buffer for problems every time that ALE does. When +|ALEWantResults| is signaled, |g:ale_want_results_buffer| will be set to the +number of the buffer that ALE wants to check. +|ale#other_source#StartChecking()| should be called synchronously, and other +sources should perform their checks on a buffer in the background +asynchronously, so they don't interrupt editing. + +A plugin might integrate its own checks with ALE like so: > + + augroup SomeGroupName + autocmd! + autocmd User ALEWantResults call Hook(g:ale_want_results_buffer) + augroup END + + function! DoBackgroundWork(buffer) abort + " Start some work in the background here. + " ... + " Then call WorkDone(a:buffer, results) + endfunction + + function! Hook(buffer) abort + " Tell ALE we're going to check this buffer. + call ale#other_source#StartChecking(a:buffer, 'some-name') + call DoBackgroundWork(a:buffer) + endfunction + + function! WorkDone(buffer, results) abort + " Send results to ALE after they have been collected. + call ale#other_source#ShowResults(buffer, 'some-name', a:results) + endfunction +< + +=============================================================================== +4. Fixing Problems *ale-fix* + +ALE can fix problems with files with the |ALEFix| command. |ALEFix| +accepts names of fixers to be applied as arguments. Alternatively, +when no arguments are provided, the variable |g:ale_fixers| will be +read for getting a |List| of commands for filetypes, split on `.`, and +the functions named in |g:ale_fixers| will be executed for fixing the +errors. + +The |ALEFixSuggest| command can be used to suggest tools that be used to +fix problems for the current buffer. + +The values for `g:ale_fixers` can be a list of |String|, |Funcref|, or +|lambda| values. String values must either name a function, or a short name +for a function set in the ALE fixer registry. + +Each function for fixing errors must accept either one argument `(buffer)` or +two arguments `(buffer, lines)`, representing the buffer being fixed and the +lines to fix. The functions must return either `0`, for changing nothing, a +|List| for new lines to set, a |Dictionary| for describing a command to be +run in the background, or the result of |ale#command#Run()|. + +Functions receiving a variable number of arguments will not receive the second +argument `lines`. Functions should name two arguments if the `lines` argument +is desired. This is required to avoid unnecessary copying of the lines of +the buffers being checked. + +When a |Dictionary| is returned for an |ALEFix| callback, the following keys +are supported for running the commands. + + `command` A |String| for the command to run. This key is required. + + When `%t` is included in a command string, a temporary + file will be created, containing the lines from the file + after previous adjustment have been done. + + `read_temporary_file` When set to `1`, ALE will read the contents of the + temporary file created for `%t`. This option can be used + for commands which need to modify some file on disk in + order to fix files. + + `process_with` An optional callback for post-processing. + + The callback must accept two arguments, + `(buffer, output)`, which can be used for converting + the output from a command into lines to replace the + buffer's contents with. + + A |List| of |String|s must be returned. + + `read_buffer` An optional key for disabling reading the buffer. + + When set to `0`, ALE will not pipe the buffer's data + into the command via stdin. This option is ignored and + the buffer is not read when `read_temporary_file` is + `1`. + + This option defaults to `1`. + + *ale-fix-configuration* + +Synchronous functions and asynchronous jobs will be run in a sequence for +fixing files, and can be combined. For example: +> + let g:ale_fixers = { + \ 'javascript': [ + \ 'DoSomething', + \ 'eslint', + \ {buffer, lines -> filter(lines, 'v:val !=~ ''^\s*//''')}, + \ ], + \} + + ALEFix +< +The above example will call a function called `DoSomething` which could act +upon some lines immediately, then run `eslint` from the ALE registry, and +then call a lambda function which will remove every single line comment +from the file. + +For buffer-local settings, such as in |g:ale_pattern_options| or in ftplugin +files, a |List| may be used for configuring the fixers instead. +> + " Same as the above, only a List can be used instead of a Dictionary. + let b:ale_fixers = [ + \ 'DoSomething', + \ 'eslint', + \ {buffer, lines -> filter(lines, 'v:val !=~ ''^\s*//''')}, + \] + + ALEFix +< +For convenience, a plug mapping is defined for |ALEFix|, so you can set up a +keybind easily for fixing files. > + + " Bind F8 to fixing problems with ALE + nmap (ale_fix) +< +Files can be fixed automatically with the following options, which are all off +by default. + +|g:ale_fix_on_save| - Fix files when they are saved. + +Fixers can be disabled on save with |g:ale_fix_on_save_ignore|. They will +still be run when you manually run |ALEFix|. + + +=============================================================================== +5. Language Server Protocol Support *ale-lsp* + +ALE offers some support for integrating with Language Server Protocol (LSP) +servers. LSP linters can be used in combination with any other linter, and +will automatically connect to LSP servers when needed. ALE also supports +`tsserver` for TypeScript, which uses a different but very similar protocol. + +If you want to use another plugin for LSP features and tsserver, you can use +the |g:ale_disable_lsp| setting to disable ALE's own LSP integrations, or +ignore particular linters with |g:ale_linters_ignore|. + +------------------------------------------------------------------------------- +5.1 Completion *ale-completion* + +ALE offers support for automatic completion of code while you type. +Completion is only supported while at least one LSP linter is enabled. ALE +will only suggest symbols provided by the LSP servers. + + *ale-deoplete-integration* + +ALE integrates with Deoplete for offering automatic completion data. ALE's +completion source for Deoplete is named `'ale'`, and should enabled +automatically if Deoplete is enabled and configured correctly. Deoplete +integration should not be combined with ALE's own implementation. + +ALE also offers its own completion implementation, which does not require any +other plugins. Suggestions will be made while you type after completion is +enabled. ALE's own completion implementation can be enabled by setting +|g:ale_completion_enabled| to `1`. This setting must be set to `1` before ALE +is loaded. The delay for completion can be configured with +|g:ale_completion_delay|. This setting should not be enabled if you wish to +use ALE as a completion source for other plugins. + +ALE provides an 'omnifunc' function |ale#completion#OmniFunc| for triggering +completion manually with CTRL-X CTRL-O. |i_CTRL-X_CTRL-O| > + + " Use ALE's function for omnicompletion. + set omnifunc=ale#completion#OmniFunc +< +ALE will only suggest so many possible matches for completion. The maximum +number of items can be controlled with |g:ale_completion_max_suggestions|. + +If you don't like some of the suggestions you see, you can filter them out +with |g:ale_completion_excluded_words| or |b:ale_completion_excluded_words|. + +The |ALEComplete| command can be used to show completion suggestions manually, +even when |g:ale_completion_enabled| is set to `0`. For manually requesting +completion information with Deoplete, consult Deoplete's documentation. + + *ale-completion-completeopt-bug* + +ALE Automatic completion implementation replaces |completeopt| before opening +the omnicomplete menu with . In some versions of Vim, the value set +for the option will not be respected. If you experience issues with Vim +automatically inserting text while you type, set the following option in +vimrc, and your issues should go away. > + + set completeopt=menu,menuone,preview,noselect,noinsert +< + +------------------------------------------------------------------------------- +5.2 Go To Definition *ale-go-to-definition* + +ALE supports jumping to the files and locations where symbols are defined +through any enabled LSP linters. The locations ALE will jump to depend on the +information returned by LSP servers. The following commands are supported: + +|ALEGoToDefinition| - Open the definition of the symbol under the cursor. +|ALEGoToDefinitionInTab| - The same, but for opening the file in a new tab. +|ALEGoToDefinitionInSplit| - The same, but in a new split. +|ALEGoToDefinitionInVSplit| - The same, but in a new vertical split. + +ALE will update Vim's |tagstack| automatically unless |g:ale_update_tagstack| is +set to `0`. + +------------------------------------------------------------------------------- +5.3 Go To Type Definition *ale-go-to-type-definition* + +ALE supports jumping to the files and locations where symbols' types are +defined through any enabled LSP linters. The locations ALE will jump to depend +on the information returned by LSP servers. The following commands are +supported: + +|ALEGoToTypeDefinition| - Open the definition of the symbol's type under + the cursor. +|ALEGoToTypeDefinitionInTab| - The same, but for opening the file in a new tab. +|ALEGoToTypeDefinitionInSplit| - The same, but in a new split. +|ALEGoToTypeDefinitionInVSplit| - The same, but in a new vertical split. + + +------------------------------------------------------------------------------- +5.4 Find References *ale-find-references* + +ALE supports finding references for symbols though any enabled LSP linters. +ALE will display a preview window showing the places where a symbol is +referenced in a codebase when a command is run. The following commands are +supported: + +|ALEFindReferences| - Find references for the word under the cursor. + +Options: + `-relative` Show file paths in the results relative to the working dir + +------------------------------------------------------------------------------- +5.5 Hovering *ale-hover* + +ALE supports "hover" information for printing brief information about symbols +at the cursor taken from LSP linters. The following commands are supported: + +|ALEHover| - Print information about the symbol at the cursor. + +If |g:ale_set_balloons| is set to `1` and your version of Vim supports the +|balloon_show()| function, then "hover" information also show up when you move +the mouse over a symbol in a buffer. Diagnostic information will take priority +over hover information for balloons. If a line contains a problem, that +problem will be displayed in a balloon instead of hover information. + +For Vim 8.1+ terminals, mouse hovering is disabled by default. Enabling +|balloonexpr| commands in terminals can cause scrolling issues in terminals, +so ALE will not attempt to show balloons unless |g:ale_set_balloons| is set to +`1` before ALE is loaded. + +For enabling mouse support in terminals, you may have to change your mouse +settings. For example: > + + " Example mouse settings. + " You will need to try different settings, depending on your terminal. + set mouse=a + set ttymouse=xterm +< + +Documentation for symbols at the cursor can be retrieved using the +|ALEDocumentation| command. This command is only available for `tsserver`. + +------------------------------------------------------------------------------- +5.6 Symbol Search *ale-symbol-search* + +ALE supports searching for workspace symbols via LSP linters. The following +commands are supported: + +|ALESymbolSearch| - Search for symbols in the workspace. + +Options: + `-relative` Show file paths in the results relative to the working dir + +=============================================================================== +6. Global Options *ale-options* + +g:airline#extensions#ale#enabled *g:airline#extensions#ale#enabled* + + Type: |Number| + Default: `1` + + Enables or disables the |airline|'s native extension for ale, which displays + warnings and errors in the status line, prefixed by + |airline#extensions#ale#error_symbol| and + |airline#extensions#ale#warning_symbol|. + + +g:ale_cache_executable_check_failures *g:ale_cache_executable_check_failures* + + Type: |Number| + Default: undefined + + When set to `1`, ALE will cache failing executable checks for linters. By + default, only executable checks which succeed will be cached. + + When this option is set to `1`, Vim will have to be restarted after new + executables are installed for ALE to be able to run linters for those + executables. + + +g:ale_change_sign_column_color *g:ale_change_sign_column_color* + + Type: |Number| + Default: `0` + + When set to `1`, this option will set different highlights for the sign + column itself when ALE reports problems with a file. This option can be + combined with |g:ale_sign_column_always|. + + ALE uses the following highlight groups for highlighting the sign column: + + `ALESignColumnWithErrors` - Links to `error` by default. + `ALESignColumnWithoutErrors` - Uses the value for `SignColumn` by default. + + The sign column color can only be changed globally in Vim. The sign column + might produce unexpected results if editing different files in split + windows. + + +g:ale_close_preview_on_insert *g:ale_close_preview_on_insert* + + Type: |Number| + Default: `0` + + When this option is set to `1`, ALE's |preview-window| will be automatically + closed upon entering Insert Mode. This option can be used in combination + with |g:ale_cursor_detail| for automatically displaying the preview window + on problem lines, and automatically closing it again when editing text. + + This setting must be set to `1` before ALE is loaded for this behavior + to be enabled. See |ale-lint-settings-on-startup|. + + +g:ale_command_wrapper *g:ale_command_wrapper* + *b:ale_command_wrapper* + Type: |String| + Default: `''` + + An option for wrapping all commands that ALE runs, for linters, fixers, + and LSP commands. This option can be set globally, or for specific buffers. + + This option can be used to apply nice to all commands. For example: > + + " Prefix all commands with nice. + let g:ale_command_wrapper = 'nice -n5' +< + Use the |ALEInfo| command to view the commands that are run. All of the + arguments for commands will be put on the end of the wrapped command by + default. A `%*` marker can be used to spread the arguments in the wrapped + command. > + + " Has the same effect as the above. + let g:ale_command_wrapper = 'nice -n5 %*' +< + + For passing all of the arguments for a command as one argument to a wrapper, + `%@` can be used instead. > + + " Will result in say: /bin/bash -c 'other-wrapper -c "some command" -x' + let g:ale_command_wrapper = 'other-wrapper -c %@ -x' +< + For commands including `&&` or `;`, only the last command in the list will + be passed to the wrapper. `&&` is most commonly used in ALE to change the + working directory before running a command. + + +g:ale_completion_delay *g:ale_completion_delay* + + Type: |Number| + Default: `100` + + The number of milliseconds before ALE will send a request to a language + server for completions after you have finished typing. + + See |ale-completion| + + +g:ale_completion_enabled *g:ale_completion_enabled* +b:ale_completion_enabled *b:ale_completion_enabled* + + Type: |Number| + Default: `0` + + When this option is set to `1`, completion support will be enabled. + + This setting must be set to `1` before ALE is loaded for this behavior + to be enabled. + + This setting should not be enabled if you wish to use ALE as a completion + source for other completion plugins. + + A buffer-local version of this setting `b:ale_completion_enabled` can be set + to `0` to disable ALE's automatic completion support for a single buffer. + ALE's completion support must be enabled globally to be enabled locally. + + See |ale-completion| + + +g:ale_completion_excluded_words *g:ale_completion_excluded_words* + *b:ale_completion_excluded_words* + Type: |List| + Default: `[]` + + This option can be set to a list of |String| values for "words" to exclude + from completion results, as in the words for |complete-items|. The strings + will be matched exactly in a case-sensitive manner. (|==#|) + + This setting can be configured in ftplugin files with buffer variables, so + that different lists can be used for different filetypes. For example: > + + " In ~/.vim/ftplugin/typescript.vim + + " Don't suggest `it` or `describe` so we can use snippets for those words. + let b:ale_completion_excluded_words = ['it', 'describe'] +< + +g:ale_completion_max_suggestions *g:ale_completion_max_suggestions* + + Type: |Number| + Default: `50` + + The maximum number of items ALE will suggest in completion menus for + automatic completion. + + Setting this number higher will require more processing time, and may + suggest too much noise. Setting this number lower will require less + processing time, but some suggestions will not be included, so you might not + be able to see the suggestions you want. + + Adjust this option as needed, depending on the complexity of your codebase + and your available processing power. + +g:ale_cursor_detail *g:ale_cursor_detail* + + Type: |Number| + Default: `0` + + When this option is set to `1`, ALE's |preview-window| will be automatically + opened when the cursor moves onto lines with problems. ALE will search for + problems using the same logic that |g:ale_echo_cursor| uses. The preview + window will be closed automatically when you move away from the line. + + Messages are only displayed after a short delay. See |g:ale_echo_delay|. + + The preview window is opened without stealing focus, which means your cursor + will stay in the same buffer as it currently is. + + The preview window can be closed automatically upon entering Insert mode + by setting |g:ale_close_preview_on_insert| to `1`. + + Either this setting or |g:ale_echo_cursor| must be set to `1` before ALE is + loaded for messages to be displayed. See |ale-lint-settings-on-startup|. + + +g:ale_disable_lsp *g:ale_disable_lsp* + *b:ale_disable_lsp* + + Type: |Number| + Default: `0` + + When this option is set to `1`, ALE ignores all linters powered by LSP, + and also `tsserver`. + + Please see also |ale-lsp|. + + +g:ale_echo_cursor *g:ale_echo_cursor* + + Type: |Number| + Default: `1` + + When this option is set to `1`, a truncated message will be echoed when a + cursor is near a warning or error. ALE will attempt to find the warning or + error at a column nearest to the cursor when the cursor is resting on a line + which contains a warning or error. This option can be set to `0` to disable + this behavior. + + Messages are only displayed after a short delay. See |g:ale_echo_delay|. + + The format of the message can be customized with |g:ale_echo_msg_format|. + + Either this setting or |g:ale_cursor_detail| must be set to `1` before ALE + is loaded for messages to be displayed. See |ale-lint-settings-on-startup|. + + +g:ale_echo_delay *g:ale_echo_delay* + *b:ale_echo_delay* + Type: |Number| + Default: `10` + + Given any integer, this option controls the number of milliseconds before + ALE will echo or preview a message for a problem near the cursor. + + The value can be increased to decrease the amount of processing ALE will do + for files displaying a large number of problems. + + +g:ale_echo_msg_error_str *g:ale_echo_msg_error_str* + + Type: |String| + Default: `'Error'` + + The string used for `%severity%` for errors. See |g:ale_echo_msg_format| + + +g:ale_echo_msg_format *g:ale_echo_msg_format* +b:ale_echo_msg_format *b:ale_echo_msg_format* + + Type: |String| + Default: `'%code: %%s'` + + This variable defines a message format for echoed messages. The following + sequences of characters will be replaced. + + `%s` - replaced with the text for the problem + `%...code...% `- replaced with the error code + `%linter%` - replaced with the name of the linter + `%severity%` - replaced with the severity of the problem + + The strings for `%severity%` can be configured with the following options. + + |g:ale_echo_msg_error_str| - Defaults to `'Error'` + |g:ale_echo_msg_info_str| - Defaults to `'Info'` + |g:ale_echo_msg_warning_str| - Defaults to `'Warning'` + + `%code%` is replaced with the error code, and replaced with an empty string + when there is no error code. Any extra characters between the percent signs + will be printed when an error code is present. For example, a message like + `(error code): message` will be printed for `'%(code): %%s'` and simply the + message will be printed when there is no code. + + |g:ale_echo_cursor| needs to be set to 1 for messages to be displayed. + + The echo message format can also be configured separately for each buffer, + so different formats can be used for different languages. (Say in ftplugin + files.) + + +g:ale_echo_msg_info_str *g:ale_echo_msg_info_str* + + Type: |String| + Default: `'Info'` + + The string used for `%severity%` for info. See |g:ale_echo_msg_format| + + +g:ale_echo_msg_warning_str *g:ale_echo_msg_warning_str* + + Type: |String| + Default: `'Warning'` + + The string used for `%severity%` for warnings. See |g:ale_echo_msg_format| + + +g:ale_enabled *g:ale_enabled* + *b:ale_enabled* + + Type: |Number| + Default: `1` + + When set to `0`, this option will completely disable ALE, such that no + error checking will be performed, etc. ALE can be toggled on and off with + the |ALEToggle| command, which changes this option. + + ALE can be disabled in each buffer by setting `let b:ale_enabled = 0` + Disabling ALE based on filename patterns can be accomplished by setting + a regular expression for |g:ale_pattern_options|. For example: > + + " Disable linting for all minified JS files. + let g:ale_pattern_options = {'\.min.js$': {'ale_enabled': 0}} +< + + See |g:ale_pattern_options| for more information on that option. + + +g:ale_fixers *g:ale_fixers* + *b:ale_fixers* + + Type: |Dictionary| + Default: `{}` + + A mapping from filetypes to |List| values for functions for fixing errors. + See |ale-fix| for more information. + + This variable can be overridden with variables in each buffer. + `b:ale_fixers` can be set to a |List| of callbacks instead, which can be + more convenient. + + A special `'*'` key be used as a wildcard filetype for configuring fixers + for every other type of file. For example: > + + " Fix Python files with 'bar'. + " Don't fix 'html' files. + " Fix everything else with 'foo'. + let g:ale_fixers = {'python': ['bar'], 'html': [], '*': ['foo']} +< + +g:ale_fix_on_save *g:ale_fix_on_save* +b:ale_fix_on_save *b:ale_fix_on_save* + + Type: |Number| + Default: `0` + + When set to 1, ALE will fix files when they are saved. + + If |g:ale_lint_on_save| is set to 1, files will be checked with linters + after files are fixed, only when the buffer is open, or re-opened. Changes + to the file will be saved to the file on disk. + + Files will not be fixed on `:wq`, so you should check your code before + closing a buffer. + + Fixing files can be disabled or enabled for individual buffers by setting + `b:ale_fix_on_save` to `0` or `1`. + + Some fixers can be excluded from being run automatically when you save files + with the |g:ale_fix_on_save_ignore| setting. + + +g:ale_fix_on_save_ignore *g:ale_fix_on_save_ignore* +b:ale_fix_on_save_ignore *b:ale_fix_on_save_ignore* + + Type: |Dictionary| or |List| + Default: `{}` + + Given a |Dictionary| mapping filetypes to |Lists| of fixers to ignore, or + just a |List| of fixers to ignore, exclude those fixers from being run + automatically when files are saved. + + You can disable some fixers in your ftplugin file: > + + " Disable fixers 'b' and 'c' when fixing on safe for this buffer. + let b:ale_fix_on_save_ignore = ['b', 'c'] + " Alternatively, define ignore lists for different filetypes. + let b:ale_fix_on_save_ignore = {'foo': ['b'], 'bar': ['c']} +< + You can disable some fixers globally per filetype like so: > + + let g:ale_fixers = {'foo': ['a', 'b'], 'bar': ['c', 'd']} + let g:ale_fix_on_save = 1 + " For filetype `foo.bar`, only fixers 'b' and 'd' will be run on save. + let g:ale_fix_on_save_ignore = {'foo': ['a'], 'bar': ['c']} + " Alternatively, disable these fixers on save for all filetypes. + let g:ale_fix_on_save_ignore = ['a', 'c'] +< + You can ignore fixers based on matching |Funcref| values too: > + + let g:AddBar = {buffer, lines -> lines + ['bar']} + let g:ale_fixers = {'foo': g:AddBar} + " The lambda fixer will be ignored, as it will be found in the ignore list. + let g:ale_fix_on_save_ignore = [g:AddBar] +< + +g:ale_history_enabled *g:ale_history_enabled* + + Type: |Number| + Default: `1` + + When set to `1`, ALE will remember the last few commands which were run + for every buffer which is open. This information can be viewed with the + |ALEInfo| command. The size of the buffer can be controlled with the + |g:ale_max_buffer_history_size| option. + + This option can be disabled if storing a command history is not desired. + + +g:ale_history_log_output *g:ale_history_log_output* + + Type: |Number| + Default: `1` + + When set to `1`, ALE will store the output of commands which have completed + successfully in the command history, and the output will be displayed when + using |ALEInfo|. + + |g:ale_history_enabled| must be set to `1` for this output to be stored or + printed. + + Some memory will be consumed by this option. It is very useful for figuring + out what went wrong with linters, and for bug reports. Turn this option off + if you want to save on some memory usage. + + +g:ale_keep_list_window_open *g:ale_keep_list_window_open* + *b:ale_keep_list_window_open* + Type: |Number| + Default: `0` + + When set to `1`, this option will keep the loclist or quickfix windows event + after all warnings/errors have been removed for files. By default the + loclist or quickfix windows will be closed automatically when there are no + warnings or errors. + + See |g:ale_open_list| + + +g:ale_list_window_size *g:ale_list_window_size* + *b:ale_list_window_size* + Type: |Number| + Default: `10` + + This number configures the number of lines to set for the height of windows + opened automatically for ALE problems. The default of `10` matches the Vim + default height. + + See |g:ale_open_list| for information on automatically opening windows + for quickfix or the loclist. + + +g:ale_lint_delay *g:ale_lint_delay* + + Type: |Number| + Default: `200` + + This variable controls the milliseconds delay after which the linters will + be run after text is changed. This option is only meaningful with the + |g:ale_lint_on_text_changed| variable set to `always`, `insert`, or `normal`. + + +g:ale_lint_on_enter *g:ale_lint_on_enter* + + Type: |Number| + Default: `1` + + When this option is set to `1`, the |BufWinEnter| event will be used to + apply linters when buffers are first opened. If this is not desired, this + variable can be set to `0` in your vimrc file to disable this behavior. + + The |FileChangedShellPost| and |BufEnter| events will be used to check if + files have been changed outside of Vim. If a file is changed outside of + Vim, it will be checked when it is next opened. + + You should set this setting once before ALE is loaded, and restart Vim if + you want to change your preferences. See |ale-lint-settings-on-startup|. + + +g:ale_lint_on_filetype_changed *g:ale_lint_on_filetype_changed* + + Type: |Number| + Default: `1` + + This option will cause ALE to run when the filetype for a file is changed + after a buffer has first been loaded. A short delay will be used before + linting will be done, so the filetype can be changed quickly several times + in a row, but resulting in only one lint cycle. + + You should set this setting once before ALE is loaded, and restart Vim if + you want to change your preferences. See |ale-lint-settings-on-startup|. + + +g:ale_lint_on_save *g:ale_lint_on_save* + + Type: |Number| + Default: `1` + + This option will make ALE run the linters whenever a file is saved when it + it set to `1` in your vimrc file. This option can be used in combination + with the |g:ale_lint_on_enter| and |g:ale_lint_on_text_changed| options to + make ALE only check files after that have been saved, if that is what is + desired. + + +g:ale_lint_on_text_changed *g:ale_lint_on_text_changed* + + Type: |String| + Default: `'normal'` + + This option controls how ALE will check your files as you make changes. + The following values can be used. + + `'always'`, `'1'`, or `1` - Check buffers on |TextChanged| or |TextChangedI|. + `'normal'` - Check buffers only on |TextChanged|. + `'insert'` - Check buffers only on |TextChangedI|. + `'never'`, `'0'`, or `0` - Never check buffers on changes. + + ALE will check buffers after a short delay, with a timer which resets on + each change. The delay can be configured by adjusting the |g:ale_lint_delay| + variable. + *ale-linting-interrupts-mapping* + + Due to a bug in Vim, ALE can interrupt mappings with pending key presses, + per |timeoutlen|. If this happens, follow the advice for enabling + |g:ale_lint_on_insert_leave| below, and set this option to `'normal'`, or + disable it entirely. + + You should set this setting once before ALE is loaded, and restart Vim if + you want to change your preferences. See |ale-lint-settings-on-startup|. + + +g:ale_lint_on_insert_leave *g:ale_lint_on_insert_leave* + *b:ale_lint_on_insert_leave* + + Type: |Number| + Default: `0` + + When set to `1` in your vimrc file, this option will cause ALE to run + linters when you leave insert mode. + + ALE will not lint files when you escape insert mode with |CTRL-C| by + default. You can make ALE lint files with this option when you use |CTRL-C| + with the following mapping. > + + " Make using Ctrl+C do the same as Escape, to trigger autocmd commands + inoremap +< + A buffer-local version of this setting `b:ale_lint_on_insert_leave` can be + set to `0` to disable linting when leaving insert mode. The setting must + be enabled globally to be enabled locally. + + You should set this setting once before ALE is loaded, and restart Vim if + you want to change your preferences. See |ale-lint-settings-on-startup|. + + +g:ale_linter_aliases *g:ale_linter_aliases* + *b:ale_linter_aliases* + Type: |Dictionary| + Default: `{}` + + The |g:ale_linter_aliases| option can be used to set aliases from one + filetype to another. A given filetype can be mapped to use the linters + run for another given filetype. + + This |Dictionary| will be merged with a default dictionary containing the + following values: > + + { + \ 'Dockerfile': 'dockerfile', + \ 'csh': 'sh', + \ 'plaintex': 'tex', + \ 'rmarkdown': 'r', + \ 'systemverilog': 'verilog', + \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], + \ 'vimwiki': 'markdown', + \ 'vue': ['vue', 'javascript'], + \ 'xsd': ['xsd', 'xml'], + \ 'xslt': ['xslt', 'xml'], + \ 'zsh': 'sh', + \} +< + For example, if you wish to map a new filetype `'foobar'` to run the `'php'` + linters, you could set the following: > + + let g:ale_linter_aliases = {'foobar': 'php'} +< + When combined with the |g:ale_linters| option, the original filetype + (`'foobar'`) will be used for determining which linters to run, + not the aliased type (`'php'`). This allows an aliased type to run a + different set of linters from the type it is being mapped to. + + Passing a list of filetypes is also supported. Say you want to lint + javascript and css embedded in HTML (using linters that support that). + You could alias `html` like so: + + `let g:ale_linter_aliases = {'html': ['html', 'javascript', 'css']}` + + Note that `html` itself was included as an alias. That is because aliases + will override the original linters for the aliased filetype. + + Linter aliases can be configured in each buffer with buffer-local variables. + ALE will first look for aliases for filetypes in the `b:ale_linter_aliases` + variable, then `g:ale_linter_aliases`, and then a default Dictionary. + + `b:ale_linter_aliases` can be set to a |List| or a |String|, to tell ALE to + load the linters for specific filetypes for a given buffer. > + + let b:ale_linter_aliases = ['html', 'javascript', 'css'] + " OR, Alias a filetype to only a single filetype with a String. + let b:ale_linter_aliases = 'javascript' +< + No linters will be loaded when the buffer's filetype is empty. + +g:ale_linters *g:ale_linters* + *b:ale_linters* + Type: |Dictionary| + Default: `{}` + + The |g:ale_linters| option sets a |Dictionary| mapping a filetype to a + |List| of linter programs to be run when checking particular filetypes. + + This |Dictionary| will be merged with a default dictionary containing the + following values: > + + { + \ 'csh': ['shell'], + \ 'elixir': ['credo', 'dialyxir', 'dogma'], + \ 'go': ['gofmt', 'golint', 'go vet'], + \ 'hack': ['hack'], + \ 'help': [], + \ 'perl': ['perlcritic'], + \ 'perl6': [], + \ 'python': ['flake8', 'mypy', 'pylint'], + \ 'rust': ['cargo'], + \ 'spec': [], + \ 'text': [], + \ 'vue': ['eslint', 'vls'], + \ 'zsh': ['shell'], + \} +< + This option can be used to enable only a particular set of linters for a + file. For example, you can enable only `eslint` for JavaScript files: > + + let g:ale_linters = {'javascript': ['eslint']} +< + If you want to disable all linters for a particular filetype, you can pass + an empty list of linters as the value: > + + let g:ale_linters = {'javascript': []} +< + All linters will be run for unspecified filetypes. All available linters can + be enabled explicitly for a given filetype by passing the string `'all'`, + instead of a List. > + + let g:ale_linters = {'c': 'all'} +< + Linters can be configured in each buffer with buffer-local variables. ALE + will first look for linters for filetypes in the `b:ale_linters` variable, + then `g:ale_linters`, and then the default Dictionary mentioned above. + + `b:ale_linters` can be set to a List, or the string `'all'`. When linters + for two different filetypes share the same name, the first linter loaded + will be used. Any ambiguity can be resolved by using a Dictionary specifying + which linter to run for which filetype instead. > + + " Use ESLint for the buffer if the filetype includes 'javascript'. + let b:ale_linters = {'javascript': ['eslint'], 'html': ['tidy']} + " Use a List for the same setting. This will work in most cases. + let b:ale_linters = ['eslint', 'tidy'] + " Disable all linters for the buffer. + let b:ale_linters = [] + " Explicitly enable all available linters for the filetype. + let b:ale_linters = 'all' +< + ALE can be configured to disable all linters unless otherwise specified with + `g:ale_enabled` or `b:ale_enabled` with the option |g:ale_linters_explicit|. + + +g:ale_linters_explicit *g:ale_linters_explicit* + + Type: |Number| + Default: `0` + + When set to `1`, only the linters from |g:ale_linters| and |b:ale_linters| + will be enabled. The default behavior for ALE is to enable as many linters + as possible, unless otherwise specified. + + +g:ale_linters_ignore *g:ale_linters_ignore* + *b:ale_linters_ignore* + + Type: |Dictionary| or |List| + Default: `{}` + + Linters to ignore. Commands for ignored linters will not be run, and + diagnostics for LSP linters will be ignored. (See |ale-lsp|) + + This setting can be set to a |Dictionary| mapping filetypes to linter names, + just like |g:ale_linters|, to list linters to ignore. Ignore lists will be + applied after everything else. > + + " Select flake8 and pylint, and ignore pylint, so only flake8 is run. + let g:ale_linters = {'python': ['flake8', 'pylint']} + let g:ale_linters_ignore = {'python': ['pylint']} +< + This setting can be set to simply a |List| of linter names, which is + especially more convenient when using the setting in ftplugin files for + particular buffers. > + + " The same as above, in a ftplugin/python.vim. + let b:ale_linters = ['flake8', 'pylint'] + let b:ale_linters_ignore = ['pylint'] +< + +g:ale_list_vertical *g:ale_list_vertical* + *b:ale_list_vertical* + Type: |Number| + Default: `0` + + When set to `1`, this will cause ALE to open any windows (loclist or + quickfix) vertically instead of horizontally (|vert| |lopen|) or (|vert| + |copen|) + + +g:ale_loclist_msg_format *g:ale_loclist_msg_format* +b:ale_loclist_msg_format *b:ale_loclist_msg_format* + + Type: |String| + Default: `g:ale_echo_msg_format` + + This option is the same as |g:ale_echo_msg_format|, but for formatting the + message used for the loclist and the quickfix list. + + The strings for configuring `%severity%` are also used for this option. + +g:ale_lsp_root *g:ale_lsp_root* +b:ale_lsp_root *b:ale_lsp_root* + + Type: |Dictionary| or |String| + Default: {} + + This option is used to determine the project root for the LSP linter. If the + value is a |Dictionary|, it maps a linter to either a string containing the + project root or a |Funcref| to call to look up the root. The funcref is + provided the buffer number as its argument. + + The buffer-specific variable may additionally be a string containing the + project root itself. + + If neither variable yields a result, a linter-specific function is invoked to + detect a project root. If this, too, yields no result, the linter is disabled. + +g:ale_max_buffer_history_size *g:ale_max_buffer_history_size* + + Type: |Number| + Default: `20` + + This setting controls the maximum number of commands which will be stored in + the command history used for |ALEInfo|. Command history will be rotated in + a FIFO manner. If set to a number <= 0, then the history will be + continuously set to an empty |List|. + + History can be disabled completely with |g:ale_history_enabled|. + + +g:ale_max_signs *g:ale_max_signs* + *b:ale_max_signs* + Type: |Number| + Default: `-1` + + When set to any positive integer, ALE will not render any more than the + given number of signs for any one buffer. + + When set to `0`, no signs will be set, but sign processing will still be + done, so existing signs can be removed. + + When set to any other value, no limit will be imposed on the number of signs + set. + + For disabling sign processing, see |g:ale_set_signs|. + + +g:ale_maximum_file_size *g:ale_maximum_file_size* + *b:ale_maximum_file_size* + Type: |Number| + Default: undefined + + A maximum file size in bytes for ALE to check. If set to any positive + number, ALE will skip checking files larger than the given size. + + +g:ale_open_list *g:ale_open_list* + *b:ale_open_list* + Type: |Number| or |String| + Default: `0` + + When set to `1`, this will cause ALE to automatically open a window for the + loclist (|lopen|) or for the quickfix list instead if |g:ale_set_quickfix| + is `1`. (|copen|) + + When set to `'on_save'`, ALE will only open the loclist after buffers have + been saved. The list will be opened some time after buffers are saved and + any linter for a buffer returns results. + + The window will be kept open until all warnings or errors are cleared, + including those not set by ALE, unless |g:ale_keep_list_window_open| is set + to `1`, in which case the window will be kept open when no problems are + found. + + The window size can be configured with |g:ale_list_window_size|. + + Windows can be opened vertically with |g:ale_list_vertical|. + + If you want to close the loclist window automatically when the buffer is + closed, you can set up the following |autocmd| command: > + + augroup CloseLoclistWindowGroup + autocmd! + autocmd QuitPre * if empty(&buftype) | lclose | endif + augroup END +< + +g:ale_pattern_options *g:ale_pattern_options* + + Type: |Dictionary| + Default: undefined + + This option maps regular expression patterns to |Dictionary| values for + buffer variables. This option can be set to automatically configure + different settings for different files. For example: > + + " Use just ESLint for linting and fixing files which end in '.foo.js' + let g:ale_pattern_options = { + \ '\.foo\.js$': { + \ 'ale_linters': ['eslint'], + \ 'ale_fixers': ['eslint'], + \ }, + \} +< + See |b:ale_linters| and |b:ale_fixers| for information for those options. + + Filenames are matched with |match()|, and patterns depend on the |magic| + setting, unless prefixed with the special escape sequences like `'\v'`, etc. + The patterns can match any part of a filename. The absolute path of the + filename will be used for matching, taken from `expand('%:p')`. + + The options for every match for the filename will be applied, with the + pattern keys sorted in alphabetical order. Options for `'zebra'` will + override the options for `'alpha'` for a filename `alpha-zebra`. + + +g:ale_pattern_options_enabled *g:ale_pattern_options_enabled* + + Type: |Number| + Default: undefined + + This option can be used for disabling pattern options. If set to `0`, ALE + will not set buffer variables per |g:ale_pattern_options|. + + +g:ale_set_balloons *g:ale_set_balloons* + *b:ale_set_balloons* + + Type: |Number| + Default: `has('balloon_eval') && has('gui_running')` + + When this option is set to `1`, balloon messages will be displayed for + problems or hover information if available. + + Problems nearest to the line the mouse cursor is over will be displayed. If + there are no problems to show, and one of the linters is an LSP linter + supporting "Hover" information, per |ale-hover|, then brief information + about the symbol under the cursor will be displayed in a balloon. + + Balloons can be enabled for terminal versions of Vim that support balloons, + but some versions of Vim will produce strange mouse behavior when balloons + are enabled. To configure balloons for your terminal, you should first + configure your |ttymouse| setting, and then consider setting + `g:ale_set_balloons` to `1` before ALE is loaded. + + `b:ale_set_balloons` can be set to `0` to disable balloons for a buffer. + Balloons cannot be enabled for a specific buffer when not initially enabled + globally. + + Balloons will not be shown when |g:ale_enabled| or |b:ale_enabled| is `0`. + + +g:ale_set_balloons_legacy_echo *g:ale_set_balloons_legacy_echo* + *b:ale_set_balloons_legacy_echo* + Type: |Number| + Default: undefined + + If set to `1`, moving your mouse over documents in Vim will make ALE ask + `tsserver` or `LSP` servers for information about the symbol where the mouse + cursor is, and print that information into Vim's echo line. This is an + option for supporting older versions of Vim which do not properly support + balloons in an asynchronous manner. + + If your version of Vim supports the |balloon_show| function, then this + option does nothing meaningful. + + +g:ale_set_highlights *g:ale_set_highlights* + + Type: |Number| + Default: `has('syntax')` + + When this option is set to `1`, highlights will be set for problems. + + ALE will use the following highlight groups for problems: + + |ALEError| - Items with `'type': 'E'` + |ALEWarning| - Items with `'type': 'W'` + |ALEInfo.| - Items with `'type': 'I'` + |ALEStyleError| - Items with `'type': 'E'` and `'sub_type': 'style'` + |ALEStyleWarning| - Items with `'type': 'W'` and `'sub_type': 'style'` + + When |g:ale_set_signs| is set to `0`, the following highlights for entire + lines will be set. + + |ALEErrorLine| - All items with `'type': 'E'` + |ALEWarningLine| - All items with `'type': 'W'` + |ALEInfoLine| - All items with `'type': 'I'` + + Vim can only highlight the characters up to the last column in a buffer for + match highlights, whereas the line highlights when signs are enabled will + run to the edge of the screen. + + +g:ale_set_loclist *g:ale_set_loclist* + + Type: |Number| + Default: `1` + + When this option is set to `1`, the |loclist| will be populated with any + warnings and errors which are found by ALE. This feature can be used to + implement jumping between errors through typical use of |lnext| and |lprev|. + + +g:ale_set_quickfix *g:ale_set_quickfix* + + Type: |Number| + Default: `0` + + When this option is set to `1`, the |quickfix| list will be populated with + any problems which are found by ALE, instead of the |loclist|. The loclist + will never be populated when this option is on. + + Problems from every buffer ALE has checked will be included in the quickfix + list, which can be checked with |:copen|. Problems will be de-duplicated. + + This feature should not be used in combination with tools for searching for + matches and commands like |:cfdo|, as ALE will replace the quickfix list + pretty frequently. If you wish to use such tools, you should populate the + loclist instead. + + +g:ale_set_signs *g:ale_set_signs* + + Type: |Number| + Default: `has('signs')` + + When this option is set to `1`, the |sign| column will be populated with + signs marking where problems appear in the file. + + ALE will use the following highlight groups for problems: + + |ALEErrorSign| - Items with `'type': 'E'` + |ALEWarningSign| - Items with `'type': 'W'` + |ALEInfoSign| - Items with `'type': 'I'` + |ALEStyleErrorSign| - Items with `'type': 'E'` and `'sub_type': 'style'` + |ALEStyleWarningSign| - Items with `'type': 'W'` and `'sub_type': 'style'` + + In addition to the style of the signs, the style of lines where signs appear + can be configured with the following highlights: + + |ALEErrorLine| - All items with `'type': 'E'` + |ALEWarningLine| - All items with `'type': 'W'` + |ALEInfoLine| - All items with `'type': 'I'` + + The markers for the highlights can be customized with the following options: + + |g:ale_sign_error| + |g:ale_sign_warning| + |g:ale_sign_info| + |g:ale_sign_style_error| + |g:ale_sign_style_warning| + + When multiple problems exist on the same line, the signs will take + precedence in the order above, from highest to lowest. + + To limit the number of signs ALE will set, see |g:ale_max_signs|. + + +g:ale_shell *g:ale_shell* + + Type: |String| + Default: not set + + Override the shell used by ALE for executing commands. ALE uses 'shell' by + default, but falls back in `/bin/sh` if the default shell looks like `fish` + or `pwsh`, which are not compatible with all of the commands run by ALE. The + shell specified with this option will be used even if it might not work in + all cases. + + For Windows, ALE uses `cmd` when this option isn't set. Setting this option + will apply shell escaping to the command string, even on Windows. + + NOTE: Consider setting |g:ale_shell_arguments| if this option is defined. + + +g:ale_shell_arguments *g:ale_shell_arguments* + + Type: |String| + Default: not set + + This option specifies the arguments to use for executing a command with a + custom shell, per |g:ale_shell|. If this option is not set, 'shellcmdflag' + will be used instead. + + +g:ale_sign_column_always *g:ale_sign_column_always* + + Type: |Number| + Default: `0` + + By default, the sign gutter will disappear when all warnings and errors have + been fixed for a file. When this option is set to `1`, the sign column will + remain open. This can be preferable if you don't want the text in your file + to move around as you edit a file. + + +g:ale_sign_error *g:ale_sign_error* + + Type: |String| + Default: `'>>'` + + The sign for errors in the sign gutter. + + +g:ale_sign_info *g:ale_sign_info* + + Type: |String| + Default: `g:ale_sign_warning` + + The sign for "info" markers in the sign gutter. + + +g:ale_sign_style_error *g:ale_sign_style_error* + + Type: |String| + Default: `g:ale_sign_error` + + The sign for style errors in the sign gutter. + + +g:ale_sign_style_warning *g:ale_sign_style_warning* + + Type: |String| + Default: `g:ale_sign_warning` + + The sign for style warnings in the sign gutter. + + +g:ale_sign_offset *g:ale_sign_offset* + + Type: |Number| + Default: `1000000` + + This variable controls offset from which numeric IDs will be generated for + new signs. Signs cannot share the same ID values, so when two Vim plugins + set signs at the same time, the IDs have to be configured such that they do + not conflict with one another. If the IDs used by ALE are found to conflict + with some other plugin, this offset value can be changed, and hopefully both + plugins will work together. See |sign-place| for more information on how + signs are set. + + +g:ale_sign_warning *g:ale_sign_warning* + + Type: |String| + Default: `'--'` + + The sign for warnings in the sign gutter. + + +g:ale_update_tagstack *g:ale_update_tagstack* + *b:ale_update_tagstack* + Type: |Number| + Default: `1` + + This option can be set to disable updating Vim's |tagstack| automatically. + + +g:ale_type_map *g:ale_type_map* + *b:ale_type_map* + Type: |Dictionary| + Default: `{}` + + This option can be set re-map problem types for linters. Each key in the + |Dictionary| should be the name of a linter, and each value must be a + |Dictionary| mapping problem types from one type to another. The following + types are supported: + + `'E'` - `{'type': 'E'}` + `'ES'` - `{'type': 'E', 'sub_type': 'style'}` + `'W'` - `{'type': 'W'}` + `'WS'` - `{'type': 'W', 'sub_type': 'style'}` + `'I'` - `{'type': 'I'}` + + For example, if you want to turn flake8 errors into warnings, you can write + the following: > + + let g:ale_type_map = {'flake8': {'ES': 'WS', 'E': 'W'}} +< + If you wanted to turn style errors and warnings into regular errors and + warnings, you can write the following: > + + let g:ale_type_map = {'flake8': {'ES': 'E', 'WS': 'W'}} +< + Type maps can be set per-buffer with `b:ale_type_map`. + + +g:ale_use_global_executables *g:ale_use_global_executables* + + Type: |Number| + Default: not set + + This option can be set to change the default for all `_use_global` options. + This option must be set before ALE is loaded, preferably in a vimrc file. + + See |ale-integrations-local-executables| for more information on those + options. + + +g:ale_virtualtext_cursor *g:ale_virtualtext_cursor* + + Type: |Number| + Default: `0` + + When this option is set to `1`, a message will be shown when a cursor is + near a warning or error. ALE will attempt to find the warning or error at a + column nearest to the cursor when the cursor is resting on a line which + contains a warning or error. This option can be set to `0` to disable this + behavior. + + Messages are only displayed after a short delay. See |g:ale_virtualtext_delay|. + + Messages can be prefixed prefixed with a string. See |g:ale_virtualtext_prefix|. + + ALE will use the following highlight groups for problems: + + |ALEVirtualTextError| - Items with `'type': 'E'` + |ALEVirtualTextWarning| - Items with `'type': 'W'` + |ALEVirtualTextInfo| - Items with `'type': 'I'` + |ALEVirtualTextStyleError| - Items with `'type': 'E'` and `'sub_type': 'style'` + |ALEVirtualTextStyleWarning| - Items with `'type': 'W'` and `'sub_type': 'style'` + + +g:ale_virtualtext_delay *g:ale_virtualtext_delay* +b:ale_virtualtext_delay *b:ale_virtualtext_delay* + Type: |Number| + Default: `10` + + Given any integer, this option controls the number of milliseconds before + ALE will show a message for a problem near the cursor. + + The value can be increased to decrease the amount of processing ALE will do + for files displaying a large number of problems. + + +g:ale_virtualtext_prefix *g:ale_virtualtext_prefix* + + Type: |String| + Default: `'> '` + + Prefix to be used with |g:ale_virtualtext_cursor|. + +g:ale_virtualenv_dir_names *g:ale_virtualenv_dir_names* +b:ale_virtualenv_dir_names *b:ale_virtualenv_dir_names* + + Type: |List| + Default: `['.env', '.venv', 'env', 've-py3', 've', 'virtualenv', 'venv']` + + A list of directory names to be used when searching upwards from Python + files to discover virtulenv directories with. + + For directory named `'foo'`, ALE will search for `'foo/bin/activate'` + (`foo\Scripts\activate\` on Windows) in all directories on and above the + directory containing the Python file to find virtualenv paths. + + +g:ale_warn_about_trailing_blank_lines *g:ale_warn_about_trailing_blank_lines* +b:ale_warn_about_trailing_blank_lines *b:ale_warn_about_trailing_blank_lines* + + Type: |Number| + Default: `1` + + When this option is set to `1`, warnings about trailing blank lines will be + shown. + + This option behaves similarly to |g:ale_warn_about_trailing_whitespace|. + + +g:ale_warn_about_trailing_whitespace *g:ale_warn_about_trailing_whitespace* +b:ale_warn_about_trailing_whitespace *b:ale_warn_about_trailing_whitespace* + + Type: |Number| + Default: `1` + + When this option is set to `1`, warnings relating to trailing whitespace on + lines will be shown. If warnings are too irritating while editing buffers, + and you have configured Vim to automatically remove trailing whitespace, + you can disable these warnings by setting this option to `0`. + + Not all linters may respect this option. If a linter does not, please file a + bug report, and it may be possible to add such support. + + This option may be configured on a per buffer basis. + + +g:ale_windows_node_executable_path *g:ale_windows_node_executable_path* + *b:ale_windows_node_executable_path* + + Type: |String| + Default: `'node.exe'` + + This variable is used as the path to the executable to use for executing + scripts with Node.js on Windows. + + For Windows, any file with a `.js` file extension needs to be executed with + the node executable explicitly. Otherwise, Windows could try and open the + scripts with other applications, like a text editor. Therefore, these + scripts are executed with whatever executable is configured with this + setting. + + +------------------------------------------------------------------------------- +6.1. Highlights *ale-highlights* + +ALEError *ALEError* + + Default: `highlight link ALEError SpellBad` + + The highlight for highlighted errors. See |g:ale_set_highlights|. + + +ALEErrorLine *ALEErrorLine* + + Default: Undefined + + The highlight for an entire line where errors appear. Only the first + line for a problem will be highlighted. + + See |g:ale_set_signs| and |g:ale_set_highlights|. + + +ALEErrorSign *ALEErrorSign* + + Default: `highlight link ALEErrorSign error` + + The highlight for error signs. See |g:ale_set_signs|. + + +ALEInfo *ALEInfo.* + *ALEInfo-highlight* + Default: `highlight link ALEInfo ALEWarning` + + The highlight for highlighted info messages. See |g:ale_set_highlights|. + + +ALEInfoSign *ALEInfoSign* + + Default: `highlight link ALEInfoSign ALEWarningSign` + + The highlight for info message signs. See |g:ale_set_signs|. + + +ALEInfoLine *ALEInfoLine* + + Default: Undefined + + The highlight for entire lines where info messages appear. Only the first + line for a problem will be highlighted. + + See |g:ale_set_signs| and |g:ale_set_highlights|. + + +ALEStyleError *ALEStyleError* + + Default: `highlight link ALEStyleError ALEError` + + The highlight for highlighted style errors. See |g:ale_set_highlights|. + + +ALEStyleErrorSign *ALEStyleErrorSign* + + Default: `highlight link ALEStyleErrorSign ALEErrorSign` + + The highlight for style error signs. See |g:ale_set_signs|. + + +ALEStyleWarning *ALEStyleWarning* + + Default: `highlight link ALEStyleWarning ALEError` + + The highlight for highlighted style warnings. See |g:ale_set_highlights|. + + +ALEStyleWarningSign *ALEStyleWarningSign* + + Default: `highlight link ALEStyleWarningSign ALEWarningSign` + + The highlight for style warning signs. See |g:ale_set_signs|. + + +ALEVirtualTextError *ALEVirtualTextError* + + Default: `highlight link ALEVirtualTextError ALEError` + + The highlight for virtualtext errors. See |g:ale_virtualtext_cursor|. + + +ALEVirtualTextInfo *ALEVirtualTextInfo* + + Default: `highlight link ALEVirtualTextInfo ALEVirtualTextWarning` + + The highlight for virtualtext info. See |g:ale_virtualtext_cursor|. + + +ALEVirtualTextStyleError *ALEVirtualTextStyleError* + + Default: `highlight link ALEVirtualTextStyleError ALEVirtualTextError` + + The highlight for virtualtext style errors. See |g:ale_virtualtext_cursor|. + + +ALEVirtualTextStyleWarning *ALEVirtualTextStyleWarning* + + Default: `highlight link ALEVirtualTextStyleWarning ALEVirtualTextWarning` + + The highlight for virtualtext style warnings. See |g:ale_virtualtext_cursor|. + + +ALEVirtualTextWarning *ALEVirtualTextWarning* + + Default: `highlight link ALEVirtualTextWarning ALEWarning` + + The highlight for virtualtext errors. See |g:ale_virtualtext_cursor|. + + +ALEWarning *ALEWarning* + + Default: `highlight link ALEWarning SpellCap` + + The highlight for highlighted warnings. See |g:ale_set_highlights|. + + +ALEWarningLine *ALEWarningLine* + + Default: Undefined + + The highlight for entire lines where warnings appear. Only the first line + for a problem will be highlighted. + + See |g:ale_set_signs| and |g:ale_set_highlights|. + + +ALEWarningSign *ALEWarningSign* + + Default: `highlight link ALEWarningSign todo` + + The highlight for warning signs. See |g:ale_set_signs|. + + +=============================================================================== +7. Linter/Fixer Options *ale-integration-options* + +Linter and fixer options are documented below and in individual help files. + +Every option for programs can be set globally, or individually for each +buffer. For example, `b:ale_python_flake8_executable` will override any +values set for `g:ale_python_flake8_executable`. + + *ale-integrations-local-executables* + +Some tools will prefer to search for locally-installed executables, unless +configured otherwise. For example, the `eslint` linter will search for +various executable paths in `node_modules`. The `flake8` linter will search +for virtualenv directories. + +If you prefer to use global executables for those tools, set the relevant +`_use_global` and `_executable` options for those linters. > + + " Use the global executable with a special name for eslint. + let g:ale_javascript_eslint_executable = 'special-eslint' + let g:ale_javascript_eslint_use_global = 1 + + " Use the global executable with a special name for flake8. + let g:ale_python_flake8_executable = '/foo/bar/flake8' + let g:ale_python_flake8_use_global = 1 +< +|g:ale_use_global_executables| can be set to `1` in your vimrc file to make +ALE use global executables for all linters by default. + +The option |g:ale_virtualenv_dir_names| controls the local virtualenv paths +ALE will use to search for Python executables. + + +------------------------------------------------------------------------------- +7.1. Options for alex *ale-alex-options* + +The options for `alex` are shared between all filetypes, so options can be +configured once. + +g:ale_alex_executable *g:ale_alex_executable* + *b:ale_alex_executable* + Type: |String| + Default: `'alex'` + + See |ale-integrations-local-executables| + + +g:ale_alex_use_global *g:ale_alex_use_global* + *b:ale_alex_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +------------------------------------------------------------------------------- +7.2. Options for languagetool *ale-languagetool-options* + +g:ale_languagetool_executable *g:ale_languagetool_executable* + *b:ale_languagetool_executable* + + Type: |String| + Default: `'languagetool'` + + The executable to run for languagetool. + + +------------------------------------------------------------------------------- +7.3. Options for write-good *ale-write-good-options* + +The options for `write-good` are shared between all filetypes, so options can +be configured once. + +g:ale_writegood_executable *g:ale_writegood_executable* + *b:ale_writegood_executable* + Type: |String| + Default: `'writegood'` + + See |ale-integrations-local-executables| + + +g:ale_writegood_options *g:ale_writegood_options* + *b:ale_writegood_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to writegood. + + +g:ale_writegood_use_global *g:ale_writegood_use_global* + *b:ale_writegood_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +------------------------------------------------------------------------------- +7.4. Other Linter/Fixer Options *ale-other-integration-options* + +ALE supports a very wide variety of tools. Other linter or fixer options are +documented in additional help files. + + ada.....................................|ale-ada-options| + gcc...................................|ale-ada-gcc| + ansible.................................|ale-ansible-options| + ansible-lint..........................|ale-ansible-ansible-lint| + asciidoc................................|ale-asciidoc-options| + write-good............................|ale-asciidoc-write-good| + textlint..............................|ale-asciidoc-textlint| + asm.....................................|ale-asm-options| + gcc...................................|ale-asm-gcc| + awk.....................................|ale-awk-options| + gawk..................................|ale-awk-gawk| + bib.....................................|ale-bib-options| + bibclean..............................|ale-bib-bibclean| + c.......................................|ale-c-options| + clang.................................|ale-c-clang| + clangd................................|ale-c-clangd| + clang-format..........................|ale-c-clangformat| + clangtidy.............................|ale-c-clangtidy| + cppcheck..............................|ale-c-cppcheck| + cquery................................|ale-c-cquery| + flawfinder............................|ale-c-flawfinder| + gcc...................................|ale-c-gcc| + uncrustify............................|ale-c-uncrustify| + ccls..................................|ale-c-ccls| + chef....................................|ale-chef-options| + cookstyle.............................|ale-chef-cookstyle| + foodcritic............................|ale-chef-foodcritic| + clojure.................................|ale-clojure-options| + clj-kondo.............................|ale-clojure-clj-kondo| + joker.................................|ale-clojure-joker| + cloudformation..........................|ale-cloudformation-options| + cfn-python-lint.......................|ale-cloudformation-cfn-python-lint| + cmake...................................|ale-cmake-options| + cmakelint.............................|ale-cmake-cmakelint| + cmake-format..........................|ale-cmake-cmakeformat| + cpp.....................................|ale-cpp-options| + clang.................................|ale-cpp-clang| + clangd................................|ale-cpp-clangd| + clangcheck............................|ale-cpp-clangcheck| + clang-format..........................|ale-cpp-clangformat| + clangtidy.............................|ale-cpp-clangtidy| + clazy.................................|ale-cpp-clazy| + cppcheck..............................|ale-cpp-cppcheck| + cpplint...............................|ale-cpp-cpplint| + cquery................................|ale-cpp-cquery| + flawfinder............................|ale-cpp-flawfinder| + gcc...................................|ale-cpp-gcc| + uncrustify............................|ale-cpp-uncrustify| + ccls..................................|ale-cpp-ccls| + c#......................................|ale-cs-options| + mcs...................................|ale-cs-mcs| + mcsc..................................|ale-cs-mcsc| + uncrustify............................|ale-cs-uncrustify| + css.....................................|ale-css-options| + fecs..................................|ale-css-fecs| + prettier..............................|ale-css-prettier| + stylelint.............................|ale-css-stylelint| + cuda....................................|ale-cuda-options| + nvcc..................................|ale-cuda-nvcc| + clang-format..........................|ale-cuda-clangformat| + d.......................................|ale-d-options| + dls...................................|ale-d-dls| + uncrustify............................|ale-d-uncrustify| + dart....................................|ale-dart-options| + dartanalyzer..........................|ale-dart-dartanalyzer| + dartfmt...............................|ale-dart-dartfmt| + dockerfile..............................|ale-dockerfile-options| + dockerfile_lint.......................|ale-dockerfile-dockerfile_lint| + hadolint..............................|ale-dockerfile-hadolint| + elixir..................................|ale-elixir-options| + mix...................................|ale-elixir-mix| + mix_format............................|ale-elixir-mix-format| + dialyxir..............................|ale-elixir-dialyxir| + elixir-ls.............................|ale-elixir-elixir-ls| + credo.................................|ale-elixir-credo| + elm.....................................|ale-elm-options| + elm-format............................|ale-elm-elm-format| + elm-lsp...............................|ale-elm-elm-lsp| + elm-make..............................|ale-elm-elm-make| + erlang..................................|ale-erlang-options| + dialyzer..............................|ale-erlang-dialyzer| + erlc..................................|ale-erlang-erlc| + syntaxerl.............................|ale-erlang-syntaxerl| + eruby...................................|ale-eruby-options| + ruumba................................|ale-eruby-ruumba| + fish....................................|ale-fish-options| + fortran.................................|ale-fortran-options| + gcc...................................|ale-fortran-gcc| + language_server.......................|ale-fortran-language-server| + fountain................................|ale-fountain-options| + fusionscript............................|ale-fuse-options| + fusion-lint...........................|ale-fuse-fusionlint| + git commit..............................|ale-gitcommit-options| + gitlint...............................|ale-gitcommit-gitlint| + glsl....................................|ale-glsl-options| + glslang...............................|ale-glsl-glslang| + glslls................................|ale-glsl-glslls| + go......................................|ale-go-options| + bingo.................................|ale-go-bingo| + gobuild...............................|ale-go-gobuild| + gofmt.................................|ale-go-gofmt| + golangci-lint.........................|ale-go-golangci-lint| + golangserver..........................|ale-go-golangserver| + golint................................|ale-go-golint| + gometalinter..........................|ale-go-gometalinter| + gopls.................................|ale-go-gopls| + govet.................................|ale-go-govet| + staticcheck...........................|ale-go-staticcheck| + graphql.................................|ale-graphql-options| + eslint................................|ale-graphql-eslint| + gqlint................................|ale-graphql-gqlint| + prettier..............................|ale-graphql-prettier| + hack....................................|ale-hack-options| + hack..................................|ale-hack-hack| + hackfmt...............................|ale-hack-hackfmt| + hhast.................................|ale-hack-hhast| + handlebars..............................|ale-handlebars-options| + ember-template-lint...................|ale-handlebars-embertemplatelint| + haskell.................................|ale-haskell-options| + brittany..............................|ale-haskell-brittany| + floskell..............................|ale-haskell-floskell| + ghc...................................|ale-haskell-ghc| + ghc-mod...............................|ale-haskell-ghc-mod| + cabal-ghc.............................|ale-haskell-cabal-ghc| + hdevtools.............................|ale-haskell-hdevtools| + hfmt..................................|ale-haskell-hfmt| + hlint.................................|ale-haskell-hlint| + stack-build...........................|ale-haskell-stack-build| + stack-ghc.............................|ale-haskell-stack-ghc| + stylish-haskell.......................|ale-haskell-stylish-haskell| + hie...................................|ale-haskell-hie| + hcl.....................................|ale-hcl-options| + terraform-fmt.........................|ale-hcl-terraform-fmt| + html....................................|ale-html-options| + fecs..................................|ale-html-fecs| + htmlhint..............................|ale-html-htmlhint| + tidy..................................|ale-html-tidy| + prettier..............................|ale-html-prettier| + stylelint.............................|ale-html-stylelint| + write-good............................|ale-html-write-good| + idris...................................|ale-idris-options| + idris.................................|ale-idris-idris| + ispc....................................|ale-ispc-options| + ispc..................................|ale-ispc-ispc| + java....................................|ale-java-options| + checkstyle............................|ale-java-checkstyle| + javac.................................|ale-java-javac| + google-java-format....................|ale-java-google-java-format| + pmd...................................|ale-java-pmd| + javalsp...............................|ale-java-javalsp| + eclipselsp............................|ale-java-eclipselsp| + uncrustify............................|ale-java-uncrustify| + javascript..............................|ale-javascript-options| + eslint................................|ale-javascript-eslint| + fecs..................................|ale-javascript-fecs| + flow..................................|ale-javascript-flow| + importjs..............................|ale-javascript-importjs| + jscs..................................|ale-javascript-jscs| + jshint................................|ale-javascript-jshint| + prettier..............................|ale-javascript-prettier| + prettier-eslint.......................|ale-javascript-prettier-eslint| + prettier-standard.....................|ale-javascript-prettier-standard| + standard..............................|ale-javascript-standard| + xo....................................|ale-javascript-xo| + json....................................|ale-json-options| + fixjson...............................|ale-json-fixjson| + jsonlint..............................|ale-json-jsonlint| + jq....................................|ale-json-jq| + prettier..............................|ale-json-prettier| + julia...................................|ale-julia-options| + languageserver........................|ale-julia-languageserver| + kotlin..................................|ale-kotlin-options| + kotlinc...............................|ale-kotlin-kotlinc| + ktlint................................|ale-kotlin-ktlint| + languageserver........................|ale-kotlin-languageserver| + latex...................................|ale-latex-options| + write-good............................|ale-latex-write-good| + textlint..............................|ale-latex-textlint| + less....................................|ale-less-options| + lessc.................................|ale-less-lessc| + prettier..............................|ale-less-prettier| + stylelint.............................|ale-less-stylelint| + llvm....................................|ale-llvm-options| + llc...................................|ale-llvm-llc| + lua.....................................|ale-lua-options| + luac..................................|ale-lua-luac| + luacheck..............................|ale-lua-luacheck| + markdown................................|ale-markdown-options| + mdl...................................|ale-markdown-mdl| + prettier..............................|ale-markdown-prettier| + remark-lint...........................|ale-markdown-remark-lint| + textlint..............................|ale-markdown-textlint| + write-good............................|ale-markdown-write-good| + mercury.................................|ale-mercury-options| + mmc...................................|ale-mercury-mmc| + nasm....................................|ale-nasm-options| + nasm..................................|ale-nasm-nasm| + nroff...................................|ale-nroff-options| + write-good............................|ale-nroff-write-good| + objc....................................|ale-objc-options| + clang.................................|ale-objc-clang| + clangd................................|ale-objc-clangd| + uncrustify............................|ale-objc-uncrustify| + ccls..................................|ale-objc-ccls| + objcpp..................................|ale-objcpp-options| + clang.................................|ale-objcpp-clang| + clangd................................|ale-objcpp-clangd| + uncrustify............................|ale-objcpp-uncrustify| + ocaml...................................|ale-ocaml-options| + merlin................................|ale-ocaml-merlin| + ols...................................|ale-ocaml-ols| + ocamlformat...........................|ale-ocaml-ocamlformat| + ocp-indent............................|ale-ocaml-ocp-indent| + pawn....................................|ale-pawn-options| + uncrustify............................|ale-pawn-uncrustify| + perl....................................|ale-perl-options| + perl..................................|ale-perl-perl| + perlcritic............................|ale-perl-perlcritic| + perltidy..............................|ale-perl-perltidy| + perl6...................................|ale-perl6-options| + perl6.................................|ale-perl6-perl6| + php.....................................|ale-php-options| + langserver............................|ale-php-langserver| + phan..................................|ale-php-phan| + phpcbf................................|ale-php-phpcbf| + phpcs.................................|ale-php-phpcs| + phpmd.................................|ale-php-phpmd| + phpstan...............................|ale-php-phpstan| + psalm.................................|ale-php-psalm| + php-cs-fixer..........................|ale-php-php-cs-fixer| + php...................................|ale-php-php| + po......................................|ale-po-options| + write-good............................|ale-po-write-good| + pod.....................................|ale-pod-options| + write-good............................|ale-pod-write-good| + pony....................................|ale-pony-options| + ponyc.................................|ale-pony-ponyc| + powershell............................|ale-powershell-options| + powershell..........................|ale-powershell-powershell| + psscriptanalyzer....................|ale-powershell-psscriptanalyzer| + prolog..................................|ale-prolog-options| + swipl.................................|ale-prolog-swipl| + proto...................................|ale-proto-options| + protoc-gen-lint.......................|ale-proto-protoc-gen-lint| + pug.....................................|ale-pug-options| + puglint...............................|ale-pug-puglint| + puppet..................................|ale-puppet-options| + puppet................................|ale-puppet-puppet| + puppetlint............................|ale-puppet-puppetlint| + puppet-languageserver.................|ale-puppet-languageserver| + pyrex (cython)..........................|ale-pyrex-options| + cython................................|ale-pyrex-cython| + python..................................|ale-python-options| + autopep8..............................|ale-python-autopep8| + bandit................................|ale-python-bandit| + black.................................|ale-python-black| + flake8................................|ale-python-flake8| + isort.................................|ale-python-isort| + mypy..................................|ale-python-mypy| + prospector............................|ale-python-prospector| + pycodestyle...........................|ale-python-pycodestyle| + pydocstyle............................|ale-python-pydocstyle| + pyflakes..............................|ale-python-pyflakes| + pylama................................|ale-python-pylama| + pylint................................|ale-python-pylint| + pyls..................................|ale-python-pyls| + pyre..................................|ale-python-pyre| + reorder-python-imports................|ale-python-reorder_python_imports| + vulture...............................|ale-python-vulture| + yapf..................................|ale-python-yapf| + qml.....................................|ale-qml-options| + qmlfmt................................|ale-qml-qmlfmt| + r.......................................|ale-r-options| + lintr.................................|ale-r-lintr| + styler................................|ale-r-styler| + reasonml................................|ale-reasonml-options| + merlin................................|ale-reasonml-merlin| + ols...................................|ale-reasonml-ols| + reason-language-server................|ale-reasonml-language-server| + refmt.................................|ale-reasonml-refmt| + restructuredtext........................|ale-restructuredtext-options| + textlint..............................|ale-restructuredtext-textlint| + write-good............................|ale-restructuredtext-write-good| + ruby....................................|ale-ruby-options| + brakeman..............................|ale-ruby-brakeman| + rails_best_practices..................|ale-ruby-rails_best_practices| + reek..................................|ale-ruby-reek| + rubocop...............................|ale-ruby-rubocop| + ruby..................................|ale-ruby-ruby| + rufo..................................|ale-ruby-rufo| + solargraph............................|ale-ruby-solargraph| + standardrb............................|ale-ruby-standardrb| + rust....................................|ale-rust-options| + cargo.................................|ale-rust-cargo| + rls...................................|ale-rust-rls| + rustc.................................|ale-rust-rustc| + rustfmt...............................|ale-rust-rustfmt| + sass....................................|ale-sass-options| + sasslint..............................|ale-sass-sasslint| + stylelint.............................|ale-sass-stylelint| + scala...................................|ale-scala-options| + sbtserver.............................|ale-scala-sbtserver| + scalafmt..............................|ale-scala-scalafmt| + scalastyle............................|ale-scala-scalastyle| + scss....................................|ale-scss-options| + prettier..............................|ale-scss-prettier| + sasslint..............................|ale-scss-sasslint| + stylelint.............................|ale-scss-stylelint| + sh......................................|ale-sh-options| + sh-language-server....................|ale-sh-language-server| + shell.................................|ale-sh-shell| + shellcheck............................|ale-sh-shellcheck| + shfmt.................................|ale-sh-shfmt| + sml.....................................|ale-sml-options| + smlnj.................................|ale-sml-smlnj| + solidity................................|ale-solidity-options| + solhint...............................|ale-solidity-solhint| + solium................................|ale-solidity-solium| + spec....................................|ale-spec-options| + rpmlint...............................|ale-spec-rpmlint| + sql.....................................|ale-sql-options| + pgformatter...........................|ale-sql-pgformatter| + sqlfmt................................|ale-sql-sqlfmt| + stylus..................................|ale-stylus-options| + stylelint.............................|ale-stylus-stylelint| + sugarss.................................|ale-sugarss-options| + stylelint.............................|ale-sugarss-stylelint| + swift...................................|ale-swift-options| + sourcekitlsp..........................|ale-swift-sourcekitlsp| + tcl.....................................|ale-tcl-options| + nagelfar..............................|ale-tcl-nagelfar| + terraform...............................|ale-terraform-options| + terraform-fmt-fixer...................|ale-terraform-fmt-fixer| + terraform.............................|ale-terraform-terraform| + tflint................................|ale-terraform-tflint| + tex.....................................|ale-tex-options| + chktex................................|ale-tex-chktex| + lacheck...............................|ale-tex-lacheck| + latexindent...........................|ale-tex-latexindent| + texlab................................|ale-tex-texlab| + texinfo.................................|ale-texinfo-options| + write-good............................|ale-texinfo-write-good| + text....................................|ale-text-options| + textlint..............................|ale-text-textlint| + write-good............................|ale-text-write-good| + thrift..................................|ale-thrift-options| + thrift................................|ale-thrift-thrift| + typescript..............................|ale-typescript-options| + eslint................................|ale-typescript-eslint| + prettier..............................|ale-typescript-prettier| + tslint................................|ale-typescript-tslint| + tsserver..............................|ale-typescript-tsserver| + vala....................................|ale-vala-options| + uncrustify............................|ale-vala-uncrustify| + verilog/systemverilog...................|ale-verilog-options| + iverilog..............................|ale-verilog-iverilog| + verilator.............................|ale-verilog-verilator| + vlog..................................|ale-verilog-vlog| + xvlog.................................|ale-verilog-xvlog| + vhdl....................................|ale-vhdl-options| + ghdl..................................|ale-vhdl-ghdl| + vcom..................................|ale-vhdl-vcom| + xvhdl.................................|ale-vhdl-xvhdl| + vim.....................................|ale-vim-options| + vint..................................|ale-vim-vint| + vim help................................|ale-vim-help-options| + write-good............................|ale-vim-help-write-good| + vue.....................................|ale-vue-options| + prettier..............................|ale-vue-prettier| + vls...................................|ale-vue-vls| + xhtml...................................|ale-xhtml-options| + write-good............................|ale-xhtml-write-good| + xml.....................................|ale-xml-options| + xmllint...............................|ale-xml-xmllint| + yaml....................................|ale-yaml-options| + prettier..............................|ale-yaml-prettier| + swaglint..............................|ale-yaml-swaglint| + yamllint..............................|ale-yaml-yamllint| + yang....................................|ale-yang-options| + yang-lsp..............................|ale-yang-lsp| + + +=============================================================================== +8. Commands/Keybinds *ale-commands* + +ALEComplete *ALEComplete* + + Manually trigger LSP autocomplete and show the menu. Works only when called + from insert mode. > + + inoremap :AleComplete +< + A plug mapping `(ale_complete)` is defined for this command. > + + imap (ale_complete) +< +ALEDocumentation *ALEDocumentation* + + Similar to the |ALEHover| command, retrieve documentation information for + the symbol at the cursor. Documentation data will always be shown in a + preview window, no matter how small the documentation content is. + + NOTE: This command is only available for `tsserver`. + + A plug mapping `(ale_documentation)` is defined for this command. + + +ALEFindReferences *ALEFindReferences* + + Find references in the codebase for the symbol under the cursor using the + enabled LSP linters for the buffer. ALE will display a preview window + containing the results if some references are found. + + The window can be navigated using the usual Vim navigation commands. The + Enter key (``) can be used to jump to a referencing location, or the `t` + key can be used to jump to the location in a new tab. + + You can jump back to the position you were at before going to a reference of + something with jump motions like CTRL-O. See |jump-motions|. + + A plug mapping `(ale_find_references)` is defined for this command. + +ALEFix *ALEFix* + + Fix problems with the current buffer. See |ale-fix| for more information. + + A plug mapping `(ale_fix)` is defined for this command. + + +ALEFixSuggest *ALEFixSuggest* + + Suggest tools that can be used to fix problems in the current buffer. + + See |ale-fix| for more information. + + +ALEGoToDefinition *ALEGoToDefinition* + + Jump to the definition of a symbol under the cursor using the enabled LSP + linters for the buffer. ALE will jump to a definition if an LSP server + provides a location to jump to. Otherwise, ALE will do nothing. + + You can jump back to the position you were at before going to the definition + of something with jump motions like CTRL-O. See |jump-motions|. + + A plug mapping `(ale_go_to_definition)` is defined for this command. + + +ALEGoToDefinitionInTab *ALEGoToDefinitionInTab* + + The same as |ALEGoToDefinition|, but opens results in a new tab. + + A plug mapping `(ale_go_to_definition_in_tab)` is defined for this + command. + + +ALEGoToDefinitionInSplit *ALEGoToDefinitionInSplit* + + The same as |ALEGoToDefinition|, but opens results in a new split. + + A plug mapping `(ale_go_to_definition_in_split)` is defined for this + command. + + +ALEGoToDefinitionInVSplit *ALEGoToDefinitionInVSplit* + + The same as |ALEGoToDefinition|, but opens results in a new vertical split. + + A plug mapping `(ale_go_to_definition_in_vsplit)` is defined for this + command. + + +ALEGoToTypeDefinition *ALEGoToTypeDefinition* + + This works similar to |ALEGoToDefinition| but instead jumps to the + definition of a type of a symbol under the cursor. ALE will jump to a + definition if an LSP server provides a location to jump to. Otherwise, ALE + will do nothing. + + You can jump back to the position you were at before going to the definition + of something with jump motions like CTRL-O. See |jump-motions|. + + A plug mapping `(ale_go_to_type_definition)` is defined for this + command. + + +ALEGoToTypeDefinitionInTab *ALEGoToTypeDefinitionInTab* + + The same as |ALEGoToTypeDefinition|, but opens results in a new tab. + + A plug mapping `(ale_go_to_type_definition_in_tab)` is defined for + this command. + + +ALEGoToTypeDefinitionInSplit *ALEGoToTypeDefinitionInSplit* + + The same as |ALEGoToTypeDefinition|, but opens results in a new split. + + A plug mapping `(ale_go_to_type_definition_in_split)` is defined for + this command. + + +ALEGoToTypeDefinitionInVSplit *ALEGoToTypeDefinitionInVSplit* + + The same as |ALEGoToTypeDefinition|, but opens results in a new vertical + split. + + A plug mapping `(ale_go_to_type_definition_in_vsplit)` is defined for + this command. + + +ALEHover *ALEHover* + + Print brief information about the symbol under the cursor, taken from any + available LSP linters. There may be a small non-blocking delay before + information is printed. + + NOTE: In Vim 8, long messages will be shown in a preview window, as Vim 8 + does not support showing a prompt to press enter to continue for long + messages from asynchronous callbacks. + + A plug mapping `(ale_hover)` is defined for this command. + + +ALESymbolSearch `` *ALESymbolSearch* + + Search for symbols in the workspace, taken from any available LSP linters. + + The arguments provided to this command will be used as a search query for + finding symbols in the workspace, such as functions, types, etc. + + *:ALELint* +ALELint *ALELint* + + Run ALE once for the current buffer. This command can be used to run ALE + manually, instead of automatically, if desired. + + This command will also run linters where `lint_file` is set to `1`, or in + other words linters which check the file instead of the Vim buffer. + + A plug mapping `(ale_lint)` is defined for this command. + + +ALEPrevious *ALEPrevious* +ALEPreviousWrap *ALEPreviousWrap* +ALENext *ALENext* +ALENextWrap *ALENextWrap* +ALEFirst *ALEFirst* +ALELast *ALELast* + *ale-navigation-commands* + + Move between warnings or errors in a buffer. ALE will only navigate between + the errors or warnings it generated, even if both |g:ale_set_quickfix| + and |g:ale_set_loclist| are set to `0`. + + `ALEPrevious` and `ALENext` will stop at the top and bottom of a file, while + `ALEPreviousWrap` and `ALENextWrap` will wrap around the file to find + the last or first warning or error in the file, respectively. + + `ALEPrevious` and `ALENext` take optional flags arguments to custom their + behaviour : + `-wrap` enable wrapping around the file + `-error`, `-warning` and `-info` enable jumping to errors, warnings or infos + respectively, ignoring anything else. They are mutually exclusive and if + several are provided the priority is the following: error > warning > info. + `-style` and `-nostyle` allow you to jump respectively to style error or + warning and to not style error or warning. They also are mutually + exclusive and nostyle has priority over style. + + Flags can be combined to create create custom jumping. Thus you can use + ":ALENext -wrap -error -nosyle" to jump to the next error which is not a + style error while going back to the beginning of the file if needed. + + `ALEFirst` goes to the first error or warning in the buffer, while `ALELast` + goes to the last one. + + The following || mappings are defined for the commands: > + (ale_previous) - ALEPrevious + (ale_previous_wrap) - ALEPreviousWrap + (ale_previous_error) - ALEPrevious -error + (ale_previous_wrap_error) - ALEPrevious -wrap -error + (ale_previous_warning) - ALEPrevious -warning + (ale_previous_wrap_warning) - ALEPrevious -wrap -warning + (ale_next) - ALENext + (ale_next_wrap) - ALENextWrap + (ale_next_error) - ALENext -error + (ale_next_wrap_error) - ALENext -wrap -error + (ale_next_warning) - ALENext -warning + (ale_next_wrap_warning) - ALENext -wrap -warning + (ale_first) - ALEFirst + (ale_last) - ALELast +< + For example, these commands could be bound to the keys Ctrl + j + and Ctrl + k: > + + " Map movement through errors without wrapping. + nmap (ale_previous) + nmap (ale_next) + " OR map keys to use wrapping. + nmap (ale_previous_wrap) + nmap (ale_next_wrap) +< + +ALEToggle *ALEToggle* +ALEEnable *ALEEnable* +ALEDisable *ALEDisable* +ALEToggleBuffer *ALEToggleBuffer* +ALEEnableBuffer *ALEEnableBuffer* +ALEDisableBuffer *ALEDisableBuffer* + + `ALEToggle`, `ALEEnable`, and `ALEDisable` enable or disable ALE linting, + including all of its autocmd events, loclist items, quickfix items, signs, + current jobs, etc., globally. Executing any of these commands will change + the |g:ale_enabled| variable. + + ALE can be disabled or enabled for only a single buffer with + `ALEToggleBuffer`, `ALEEnableBuffer`, and `ALEDisableBuffer`. Disabling ALE + for a buffer will not remove autocmd events, but will prevent ALE from + checking for problems and reporting problems for whatever buffer the + `ALEDisableBuffer` or `ALEToggleBuffer` command is executed from. These + commands can be used for temporarily disabling ALE for a buffer. These + commands will modify the |b:ale_enabled| variable. + + ALE linting cannot be enabled for a single buffer when it is disabled + globally, as disabling ALE globally removes the autocmd events needed to + perform linting with. + + The following plug mappings are defined, for conveniently defining keybinds: + + |ALEToggle| - `(ale_toggle)` + |ALEEnable| - `(ale_enable)` + |ALEDisable| - `(ale_disable)` + |ALEToggleBuffer| - `(ale_toggle_buffer)` + |ALEEnableBuffer| - `(ale_enable_buffer)` + |ALEDisableBuffer| - `(ale_disable_buffer)` + + For removing problems reported by ALE, but leaving ALE enabled, see + |ALEReset| and |ALEResetBuffer|. + + *:ALEDetail* +ALEDetail *ALEDetail* + + Show the full linter message for the problem nearest to the cursor on the + given line in the preview window. The preview window can be easily closed + with the `q` key. If there is no message to show, the window will not be + opened. + + If a loclist item has a `detail` key set, the message for that key will be + preferred over `text`. See |ale-loclist-format|. + + A plug mapping `(ale_detail)` is defined for this command. + + + *:ALEInfo* +ALEInfo *ALEInfo* +ALEInfoToClipboard *ALEInfoToClipboard* + + Print runtime information about ALE, including the values of global and + buffer-local settings for ALE, the linters that are enabled, the commands + that have been run, and the output of commands. + + ALE will log the commands that are run by default. If you wish to disable + this, set |g:ale_history_enabled| to `0`. Because it could be expensive, ALE + does not remember the output of recent commands by default. Set + |g:ale_history_log_output| to `1` to enable logging of output for commands. + ALE will only log the output captured for parsing problems, etc. + + The command `:ALEInfoToClipboard` can be used to output ALEInfo directly to + your clipboard. This might not work on every machine. + + `:ALEInfoToFile` will write the ALE runtime information to a given filename. + The filename works just like |:w|. + + +ALEReset *ALEReset* +ALEResetBuffer *ALEResetBuffer* + + `ALEReset` will remove all problems reported by ALE for all buffers. + `ALEResetBuffer` will remove all problems reported for a single buffer. + + Either command will leave ALE linting enabled, so ALE will report problems + when linting is performed again. See |ale-lint| for more information. + + The following plug mappings are defined, for conveniently defining keybinds: + + |ALEReset| - `(ale_reset)` + |ALEResetBuffer| - `(ale_reset_buffer)` + + ALE can be disabled globally or for a buffer with |ALEDisable| or + |ALEDisableBuffer|. + + +ALEStopAllLSPs *ALEStopAllLSPs* + + `ALEStopAllLSPs` will close and stop all channels and jobs for all LSP-like + clients, including tsserver, remove all of the data stored for them, and + delete all of the problems found for them, updating every linted buffer. + + This command can be used when LSP clients mess up and need to be restarted. + + +=============================================================================== +9. API *ale-api* + +ALE offers a number of functions for running linters or fixers, or defining +them. The following functions are part of the publicly documented part of that +API, and should be expected to continue to work. + + +ale#Env(variable_name, value) *ale#Env()* + + Given a variable name and a string value, produce a string for including in + a command for setting environment variables. This function can be used for + building a command like so. > + + :echo string(ale#Env('VAR', 'some value') . 'command') + 'VAR=''some value'' command' # On Linux or Mac OSX + 'set VAR="some value" && command' # On Windows + + +ale#Has(feature) *ale#Has()* + + Return `1` if ALE supports a given feature, like |has()| for Vim features. + + ALE versions can be checked with version strings in the format + `ale#Has('ale-x.y.z')`, such as `ale#Has('ale-2.4.0')`. + + +ale#Pad(string) *ale#Pad()* + + Given a string or any |empty()| value, return either the string prefixed + with a single space, or an empty string. This function can be used to build + parts of a command from variables. + + +ale#Queue(delay, [linting_flag, buffer_number]) *ale#Queue()* + + Run linters for the current buffer, based on the filetype of the buffer, + with a given `delay`. A `delay` of `0` will run the linters immediately. + The linters will always be run in the background. Calling this function + again from the same buffer + + An optional `linting_flag` argument can be given. If `linting_flag` + is `'lint_file'`, then linters where the `lint_file` option is set to `1` will be + run. Linters with `lint_file` set to `1` are not run by default. + + An optional `buffer_number` argument can be given for specifying the buffer + to check. The active buffer (`bufnr('')`) will be checked by default. + + *ale-cool-down* + If an exception is thrown when queuing/running ALE linters, ALE will enter + a cool down period where it will stop checking anything for a short period + of time. This is to prevent ALE from seriously annoying users if a linter + is broken, or when developing ALE itself. + + +ale#command#CreateDirectory(buffer) *ale#command#CreateDirectory()* + + Create a new temporary directory with a unique name, and manage that + directory with |ale#command#ManageDirectory()|, so it will be removed as soon + as possible. + + It is advised to only call this function from a callback function for + returning a linter command to run. + + +ale#command#CreateFile(buffer) *ale#command#CreateFile()* + + Create a new temporary file with a unique name, and manage that file with + |ale#command#ManageFile()|, so it will be removed as soon as possible. + + It is advised to only call this function from a callback function for + returning a linter command to run. + + +ale#command#Run(buffer, command, callback, [options]) *ale#command#Run()* + + Start running a job in the background, and pass the results to the given + callback later. + + This function can be used for computing the results of ALE linter or fixer + functions asynchronously with jobs. `buffer` must match the buffer being + linted or fixed, `command` must be a |String| for a shell command to + execute, `callback` must be defined as a |Funcref| to call later with the + results, and an optional |Dictionary| of `options` can be provided. + + The `callback` will receive the arguments `(buffer, output, metadata)`, + where the `buffer` will match the buffer given to the function, the `output` + will be a `List` of lines of output from the job that was run, and the + `metadata` will be a |Dictionary| with additional information about the job + that was run, including: + + `exit_code` - A |Number| with the exit code for the program that was run. + + The result of this function is either a special |Dictionary| ALE will use + for waiting for the command to finish, or `0` if the job is not started. The + The return value of the `callback` will be used as the eventual result for + whatever value is being given to ALE. For example: > + + function! s:GetCommand(buffer, output, meta) abort + " Do something with a:output here, from the foo command. + + " This is used as the command to run for linting. + return 'final command' + endfunction + + " ... + + 'command': {b -> ale#command#Run(b, 'foo', function('s:GetCommand'))} +< + The result of a callback can also be the result of another call to this + function, so that several commands can be arbitrarily chained together. For + example: > + + function! s:GetAnotherCommand(buffer, output, meta) abort + " We can finally return this command. + return 'last command' + endfunction + + function! s:GetCommand(buffer, output, meta) abort + " We can return another deferred result. + return ale#command#Run( + \ a:buffer, + \ 'second command', + \ function('s:GetAnotherCommand') + \) + endfunction + + " ... + + 'command': {b -> ale#command#Run(b, 'foo', function('s:GetCommand'))} +< + + The following `options` can be provided. + + `output_stream` - Either `'stdout'`, `'stderr'`, `'both'`, or `'none`' for + selecting which output streams to read lines from. + + The default is `'stdout'` + + `executable` - An executable for formatting into `%e` in the command. + If this option is not provided, formatting commands with + `%e` will not work. + + `read_buffer` - If set to `1`, the buffer will be piped into the + command. + + The default is `0`. + + `input` - When creating temporary files with `%t` or piping text + into a command `input` can be set to a |List| of text to + use instead of the buffer's text. + + +ale#command#EscapeCommandPart(command_part) *ale#command#EscapeCommandPart()* + + Given a |String|, return a |String| with all `%` characters replaced with + `%%` instead. This function can be used to escape strings which are + dynamically generated for commands before handing them over to ALE, + so that ALE doesn't treat any strings with `%` formatting sequences + specially. + + +ale#command#ManageDirectory(buffer, directory) *ale#command#ManageDirectory()* + + Like |ale#command#ManageFile()|, but directories and all of their contents + will be deleted, akin to `rm -rf directory`, which could lead to loss of + data if mistakes are made. This command will also delete any temporary + filenames given to it. + + It is advised to use |ale#command#ManageFile()| instead for deleting single + files. + + +ale#command#ManageFile(buffer, filename) *ale#command#ManageFile()* + + Given a buffer number for a buffer currently running some linting or fixing + tasks and a filename, register a filename with ALE for automatic deletion + after linting or fixing is complete, or when Vim exits. + + If Vim exits suddenly, ALE will try its best to remove temporary files, but + ALE cannot guarantee with absolute certainty that the files will be removed. + It is advised to create temporary files in the operating system's managed + temporary file directory, such as with |tempname()|. + + Directory names should not be given to this function. ALE will only delete + files and symlinks given to this function. This is to prevent entire + directories from being accidentally deleted, say in cases of writing + `dir . '/' . filename` where `filename` is actually `''`, etc. ALE instead + manages directories separately with the |ale#command#ManageDirectory| function. + + +ale#completion#OmniFunc(findstart, base) *ale#completion#OmniFunc()* + + A completion function to use with 'omnifunc'. + + See |ale-completion|. + + +ale#engine#GetLoclist(buffer) *ale#engine#GetLoclist()* + + Given a buffer number, this function will return the list of problems + reported by ALE for a given buffer in the format accepted by |setqflist()|. + + A reference to the buffer's list of problems will be returned. The list must + be copied before applying |map()| or |filter()|. + + +ale#engine#IsCheckingBuffer(buffer) *ale#engine#IsCheckingBuffer()* + + Given a buffer number, returns `1` when ALE is busy checking that buffer. + + This function can be used for status lines, tab names, etc. + + +ale#fix#registry#Add(name, func, filetypes, desc, [aliases]) + *ale#fix#registry#Add()* + + Given a |String| `name` for a name to add to the registry, a |String| `func` + for a function name, a |List| `filetypes` for a list of filetypes to + set for suggestions, and a |String| `desc` for a short description of + the fixer, register a fixer in the registry. + + The `name` can then be used for |g:ale_fixers| in place of the function + name, and suggested for fixing files. + + An optional |List| of |String|s for aliases can be passed as the `aliases` + argument. These aliases can also be used for looking up a fixer function. + ALE will search for fixers in the registry first by `name`, then by their + `aliases`. + + +ale#linter#Define(filetype, linter) *ale#linter#Define()* + + Given a |String| for a filetype and a |Dictionary| Describing a linter + configuration, add a linter for the given filetype. The dictionaries each + offer the following options: + + `name` The name of the linter. These names will be used by + |g:ale_linters| option for enabling/disabling + particular linters. + + This argument is required. + + `callback` A |String| or |Funcref| for a callback function + accepting two arguments (buffer, lines), for a + buffer number the output is for, and the lines of + output from a linter. + + This callback function should return a |List| of + |Dictionary| objects in the format accepted by + |setqflist()|. The |List| will be sorted by line and + then column order so it can be searched with a binary + search by in future before being passed on to the + |loclist|, etc. + + This argument is required, unless the linter is an + LSP linter. In which case, this argument must not be + defined, as LSP linters handle diagnostics + automatically. See |ale-lsp-linters|. + + If the function named does not exist, including if + the function is later deleted, ALE will behave as if + the callback returned an empty list. + + The keys for each item in the List will be handled in + the following manner: + *ale-loclist-format* + `text` - This error message is required. + `detail` - An optional, more descriptive message. + This message can be displayed with the |ALEDetail| + command instead of the message for `text`, if set. + `lnum` - The line number is required. Any strings + will be automatically converted to numbers by + using `str2nr()`. + + Line 0 will be moved to line 1, and lines beyond + the end of the file will be moved to the end. + `col` - The column number is optional and will + default to `0`. Any strings will be automatically + converted to number using `str2nr()`. + `end_col` - An optional end column number. + This key can be set to specify the column problems + end on, for improved highlighting. + `end_lnum` - An optional end line number. + This key can set along with `end_col` for + highlighting multi-line problems. + `bufnr` - This key represents the buffer number the + problems are for. This value will default to + the buffer number being checked. + + The `filename` key can be set instead of this key, + and then the eventual `bufnr` value in the final + list will either represent the number for an open + buffer or `-1` for a file not open in any buffer. + `filename` - An optional filename for the file the + problems are for. This should be an absolute path to + a file. + + Problems for files which have not yet been opened + will be set in those files after they are opened + and have been checked at least once. + + Temporary files in directories used for Vim + temporary files with `tempname()` will be assumed + to be the buffer being checked, unless the `bufnr` + key is also set with a valid number for some other + buffer. + `vcol` - Defaults to `0`. + + If set to `1`, ALE will convert virtual column + positions for `col` and `end_col` to byte column + positions. If the buffer is changed in-between + checking it and displaying the results, the + calculated byte column positions will probably be + wrong. + `type` - Defaults to `'E'`. + `nr` - Defaults to `-1`. + + Numeric error code. If `nr` is not `-1`, `code` + likely should contain the string representation of + the same value. + `code` - No default; may be unset. + + Human-readable |String| error code. + + `executable` A |String| naming the executable itself which + will be run, or a |Funcref| for a function to call + for computing the executable, accepting a buffer + number. + + The result can be computed with |ale#command#Run()|. + + This value will be used to check if the program + requested is installed or not. + + If an `executable` is not defined, the command will + be run without checking if a program is executable + first. Defining an executable path is recommended to + avoid starting too many processes. + + `command` A |String| for a command to run asynchronously, or a + |Funcref| for a function to call for computing the + command, accepting a buffer number. + + The result can be computed with |ale#command#Run()|. + + This command will be fed the lines from the buffer to + check, and will produce the lines of output given to + the `callback`. + + `output_stream` A |String| for the output stream the lines of output + should be read from for the command which is run. The + accepted values are `'stdout'`, `'stderr'`, and + `'both'`. This argument defaults to `'stdout'`. This + argument can be set for linter programs which output + their errors and warnings to the stderr stream + instead of stdout. The option `'both'` will read + from both stder and stdout at the same time. + + `read_buffer` A |Number| (`0` or `1`) indicating whether a command + should read the Vim buffer as input via stdin. This + option is set to `1` by default, and can be disabled + if a command manually reads from a temporary file + instead, etc. + + *ale-lint-file* + `lint_file` A |Number| (`0` or `1`) indicating whether a command + should read the file instead of the Vim buffer. This + option can be used for linters which must check the + file on disk, and which cannot check a Vim buffer + instead. + + Linters set with this option will not be run as a + user types, per |g:ale_lint_on_text_changed|. Linters + will instead be run only when events occur against + the file on disk, including |g:ale_lint_on_enter| + and |g:ale_lint_on_save|. Linters with this option + set to `1` will also be run when linters are run + manually, per |ALELintPost-autocmd|. + + When this option is set to `1`, `read_buffer` will + be set automatically to `0`. The two options cannot + be used together. + + *ale-lsp-linters* + `lsp` A |String| for defining LSP (Language Server Protocol) + linters. + + This argument may be omitted or `''` when a linter + does not represent an LSP linter. + + When this argument is set to `'stdio'`, then the + linter will be defined as an LSP linter which keeps a + process for a language server running, and + communicates with it directly via a |channel|. + `executable` and `command` must be set. + + When this argument is set to `'socket'`, then the + linter will be defined as an LSP linter via a TCP + socket connection. `address` must be set. + + ALE will not start a server automatically. + + When this argument is not empty `project_root` must + be defined. + + `language` can be defined to describe the language + for a file. The filetype will be used as the language + by default. + + LSP linters handle diagnostics automatically, so + the `callback` argument must not be defined. + + An optional `completion_filter` callback may be + defined for filtering completion results. + + `initialization_options` may be defined to pass + initialization options to the LSP. + + `lsp_config` may be defined to pass configuration + settings to the LSP. + + `address` A |String| representing an address to connect to, + or a |Funcref| accepting a buffer number and + returning the |String|. + + The result can be computed with |ale#command#Run()|. + + This argument must only be set if the `lsp` argument + is set to `'socket'`. + + `project_root` A |String| representing a path to the project for + the file being checked with the language server, or + a |Funcref| accepting a buffer number and returning + the |String|. + + If an empty string is returned, the file will not be + checked at all. + + This argument must only be set if the `lsp` argument + is also set to a non-empty string. + + `language` A |String| representing the name of the language + being checked, or a |Funcref| accepting a buffer + number and returning the |String|. This string will + be sent to the LSP to tell it what type of language + is being checked. + + If a language isn't provided, the language will + default to the value of the filetype given to + |ale#linter#Define|. + + `completion_filter` A |String| or |Funcref| for a callback function + accepting a buffer number and a completion item. + + The completion item will be a |Dictionary| following + the Language Server Protocol `CompletionItem` + interface as described in the specification, + available online here: + https://microsoft.github.io/language-server-protocol + + `aliases` A |List| of aliases for the linter name. + + This argument can be set with alternative names for + selecting the linter with |g:ale_linters|. This + setting can make it easier to guess the linter name + by offering a few alternatives. + + `initialization_options` A |Dictionary| of initialization options for LSPs, + or a |Funcref| for a callback function accepting + a buffer number and returning the |Dictionary|. + + This will be fed (as JSON) to the LSP in the + initialize command. + + `lsp_config` A |Dictionary| for configuring a language server, + or a |Funcref| for a callback function accepting + a buffer number and returning the |Dictionary|. + + This will be fed (as JSON) to the LSP in the + workspace/didChangeConfiguration command. + + If temporary files or directories are created for commands run with + `command`, then these temporary files or directories can be managed by ALE, + for automatic deletion. See |ale#command#ManageFile()| and + |ale#command#ManageDirectory| for more information. + + *ale-command-format-strings* + + All command strings will be formatted for special character sequences. + Any substring `%s` will be replaced with the full path to the current file + being edited. This format option can be used to pass the exact filename + being edited to a program. + + For example: > + 'command': 'eslint -f unix --stdin --stdin-filename %s' +< + Any substring `%t` will be replaced with a path to a temporary file. Merely + adding `%t` will cause ALE to create a temporary file containing the + contents of the buffer being checked. All occurrences of `%t` in command + strings will reference the one temporary file. The temporary file will be + created inside a temporary directory, and the entire temporary directory + will be automatically deleted, following the behaviour of + |ale#command#ManageDirectory|. This option can be used for some linters which + do not support reading from stdin. + + For example: > + 'command': 'ghc -fno-code -v0 %t', +< + Any substring `%e` will be replaced with the escaped executable supplied + with `executable`. This provides a convenient way to define a command string + which needs to include a dynamic executable name, but which is otherwise + static. + + For example: > + 'command': '%e --some-argument', +< + The character sequence `%%` can be used to emit a literal `%` into a + command, so literal character sequences `%s` and `%t` can be escaped by + using `%%s` and `%%t` instead, etc. + + If a callback for a command generates part of a command string which might + possibly contain `%%`, `%s`, `%t`, or `%e`, where the special formatting + behavior is not desired, the |ale#command#EscapeCommandPart()| function can + be used to replace those characters to avoid formatting issues. + + *ale-linter-loading-behavior* + *ale-linter-loading-behaviour* + + Linters for ALE will be loaded by searching |runtimepath| in the following + format: > + + ale_linters//.vim +< + Any linters which exist anywhere in |runtimepath| with that directory + structure will be automatically loaded for the matching |filetype|. Filetypes + containing `.` characters will be split into individual parts, and files + will be loaded for each filetype between the `.` characters. + + Linters can be defined from vimrc and other files as long as this function + is loaded first. For example, the following code will define a Hello World + linter in vimrc in Vim 8: > + + " Plugins have to be loaded first. + " If you are using a plugin manager, run that first. + packloadall + + call ale#linter#Define('vim', { + \ 'name': 'echo-test', + \ 'executable': 'echo', + \ 'command': 'echo hello world', + \ 'callback': {buffer, lines -> map(lines, '{"text": v:val, "lnum": 1}')}, + \}) +< + +ale#linter#Get(filetype) *ale#linter#Get()* + + Return all of linters configured for a given filetype as a |List| of + |Dictionary| values in the format specified by |ale#linter#Define()|. + + Filetypes may be dot-separated to invoke linters for multiple filetypes: + for instance, the filetype `javascript.jsx` will return linters for both the + `javascript` and `jsx` filetype. + + Aliases may be defined in as described in |g:ale_linter_aliases|. Aliases + are applied after dot-separated filetypes are broken up into their + components. + + +ale#linter#PreventLoading(filetype) *ale#linter#PreventLoading()* + + Given a `filetype`, prevent any more linters from being loaded from + |runtimepath| for that filetype. This function can be called from vimrc or + similar to prevent ALE from loading linters. + + +ale#lsp_linter#SendRequest(buffer, linter_name, message, [Handler]) + *ale#lsp_linter#SendRequest()* + + Send a custom request to an LSP linter. The arguments are defined as + follows: + + `buffer` A valid buffer number. + + `linter_name` A |String| identifying an LSP linter that is available and + enabled for the |filetype| of `buffer`. + + `message` A |List| in the form `[is_notification, method, parameters]`, + containing three elements: + `is_notification` - an |Integer| that has value 1 if the + request is a notification, 0 otherwise; + `methdod` - a |String|, identifying an LSP method supported + by `linter`; + `parameters` - a |dictionary| of LSP parameters that are + applicable to `method`. + + `Handler` Optional argument, meaningful only when `message[0]` is 0. + A |Funcref| that is called when a response to the request is + received, and takes as unique argument a dictionary + representing the response obtained from the server. + + +ale#other_source#ShowResults(buffer, linter_name, loclist) + *ale#other_source#ShowResults()* + + Show results from another source of information. + + `buffer` must be a valid buffer number, and `linter_name` must be a unique + name for identifying another source of information. The `loclist` given + where the problems in a buffer are, and should be provided in the format ALE + uses for regular linter results. See |ale-loclist-format|. + + +ale#other_source#StartChecking(buffer, linter_name) + *ale#other_source#StartChecking()* + + Tell ALE that another source of information has started checking a buffer. + + `buffer` must be a valid buffer number, and `linter_name` must be a unique + name for identifying another source of information. + + +ale#statusline#Count(buffer) *ale#statusline#Count()* + + Given the number of a buffer which may have problems, return a |Dictionary| + containing information about the number of problems detected by ALE. The + following keys are supported: + + `error` -> The number of problems with type `E` and `sub_type != 'style'` + `warning` -> The number of problems with type `W` and `sub_type != 'style'` + `info` -> The number of problems with type `I` + `style_error` -> The number of problems with type `E` and `sub_type == 'style'` + `style_warning` -> The number of problems with type `W` and `sub_type == 'style'` + `total` -> The total number of problems. + + +ale#statusline#FirstProblem(buffer, type) *ale#statusline#FirstProblem()* + + Returns a copy of the first entry in the `loclist` that matches the supplied + buffer number and problem type. If there is no such entry, an empty dictionary + is returned. + Problem type should be one of the strings listed below: + + `error` -> Returns the first `loclist` item with type `E` and + `sub_type != 'style'` + `warning` -> First item with type `W` and `sub_type != 'style'` + `info` -> First item with type `I` + `style_error` -> First item with type `E` and `sub_type == 'style'` + `style_warning` -> First item with type `W` and `sub_type == 'style'` + + +b:ale_linted *b:ale_linted* + + `b:ale_linted` is set to the number of times a buffer has been checked by + ALE after all linters for one lint cycle have finished checking a buffer. + This variable may not be defined until ALE first checks a buffer, so it + should be accessed with |get()| or |getbufvar()|. For example: > + + " Print a message indicating how many times ALE has checked this buffer. + echo 'ALE has checked this buffer ' . get(b:, 'ale_linted') . ' time(s).' + " Print 'checked' using getbufvar() if a buffer has been checked. + echo getbufvar(bufnr(''), 'ale_linted', 0) > 0 ? 'checked' : 'not checked' +< + +g:ale_want_results_buffer *g:ale_want_results_buffer* + + `g:ale_want_results_buffer` is set to the number of the buffer being checked + when the |ALEWantResults| event is signaled. This variable should be read to + figure out which buffer other sources should lint. + + +ALELintPre *ALELintPre-autocmd* + *ALELintPre* +ALELintPost *ALELintPost-autocmd* + *ALELintPost* +ALEFixPre *ALEFixPre-autocmd* + *ALEFixPre* +ALEFixPost *ALEFixPost-autocmd* + *ALEFixPost* + + These |User| autocommands are triggered before and after every lint or fix + cycle. They can be used to update statuslines, send notifications, etc. + The autocmd commands are run with |:silent|, so |:unsilent| is required for + echoing messges. + + For example to change the color of the statusline while the linter is + running: +> + augroup ALEProgress + autocmd! + autocmd User ALELintPre hi Statusline ctermfg=darkgrey + autocmd User ALELintPost hi Statusline ctermfg=NONE + augroup END +< + Or to display the progress in the statusline: +> + let s:ale_running = 0 + let l:stl .= '%{s:ale_running ? "[linting]" : ""}' + augroup ALEProgress + autocmd! + autocmd User ALELintPre let s:ale_running = 1 | redrawstatus + autocmd User ALELintPost let s:ale_running = 0 | redrawstatus + augroup END + +< +ALEJobStarted *ALEJobStarted-autocmd* + *ALEJobStarted* + + This |User| autocommand is triggered immediately after a job is successfully + run. This provides better accuracy for checking linter status with + |ale#engine#IsCheckingBuffer()| over |ALELintPre-autocmd|, which is actually + triggered before any linters are executed. + + +ALEWantResults *ALEWantResults-autocmd* + *ALEWantResults* + + This |User| autocommand is triggered before ALE begins a lint cycle. Another + source can respond by calling |ale#other_source#StartChecking()|, and + |ALELintPre| will be signaled thereafter, to allow other plugins to know + that another source is checking the buffer. + + |g:ale_want_results_buffer| will be set to the number for a buffer being + checked when the event is signaled, and deleted after the event is done. + This variable should be read to know which buffer to check. + + Other plugins can use this event to start checking buffers when ALE events + for checking buffers are triggered. + + +=============================================================================== +10. Special Thanks *ale-special-thanks* + +Special thanks to Mark Grealish (https://www.bhalash.com/) for providing ALE's +snazzy looking ale glass logo. Cheers, Mark! + +=============================================================================== +11. Contact *ale-contact* + +If you like this plugin, and wish to get in touch, check out the GitHub +page for issues and more at https://github.com/w0rp/ale + +If you wish to contact the author of this plugin directly, please feel +free to send an email to devw0rp@gmail.com. + +Please drink responsibly, or not at all, which is ironically the preference +of w0rp, who is teetotal. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/pack/acp/start/ale/ftplugin/ale-fix-suggest.vim b/pack/acp/start/ale/ftplugin/ale-fix-suggest.vim new file mode 100644 index 0000000..189a4dc --- /dev/null +++ b/pack/acp/start/ale/ftplugin/ale-fix-suggest.vim @@ -0,0 +1,2 @@ +" Close the ALEFixSuggest window with the q key. +noremap q :q! diff --git a/pack/acp/start/ale/ftplugin/ale-preview-selection.vim b/pack/acp/start/ale/ftplugin/ale-preview-selection.vim new file mode 100644 index 0000000..d77b4f9 --- /dev/null +++ b/pack/acp/start/ale/ftplugin/ale-preview-selection.vim @@ -0,0 +1,16 @@ +" Close the ALEPreviewWindow window with the q key. +noremap q :q! +" Disable some keybinds for the selection window. +noremap v +noremap i +noremap I +noremap +noremap +noremap +noremap a +noremap A +noremap o +noremap O +" Keybinds for opening selection items. +noremap :call ale#preview#OpenSelectionInBuffer() +noremap t :call ale#preview#OpenSelectionInTab() diff --git a/pack/acp/start/ale/ftplugin/ale-preview.vim b/pack/acp/start/ale/ftplugin/ale-preview.vim new file mode 100644 index 0000000..ffbffbd --- /dev/null +++ b/pack/acp/start/ale/ftplugin/ale-preview.vim @@ -0,0 +1,2 @@ +" Close the ALEPreviewWindow window with the q key. +noremap q :q! diff --git a/pack/acp/start/ale/plugin/ale.vim b/pack/acp/start/ale/plugin/ale.vim new file mode 100644 index 0000000..7edf9a5 --- /dev/null +++ b/pack/acp/start/ale/plugin/ale.vim @@ -0,0 +1,274 @@ +" Author: w0rp +" Description: Main entry point for the plugin: sets up prefs and autocommands +" Preferences can be set in vimrc files and so on to configure ale + +" Sanity Checks + +if exists('g:loaded_ale_dont_use_this_in_other_plugins_please') + finish +endif + +" Set a special flag used only by this plugin for preventing doubly +" loading the script. +let g:loaded_ale_dont_use_this_in_other_plugins_please = 1 + +" A flag for detecting if the required features are set. +if has('nvim') + let s:has_features = has('timers') && has('nvim-0.2.0') +else + " Check if Job and Channel functions are available, instead of the + " features. This works better on old MacVim versions. + let s:has_features = has('timers') && exists('*job_start') && exists('*ch_close_in') +endif + +if !s:has_features + " Only output a warning if editing some special files. + if index(['', 'gitcommit'], &filetype) == -1 + execute 'echoerr ''ALE requires NeoVim >= 0.2.0 or Vim 8 with +timers +job +channel''' + execute 'echoerr ''Please update your editor appropriately.''' + endif + + " Stop here, as it won't work. + finish +endif + +" Set this flag so that other plugins can use it, like airline. +let g:loaded_ale = 1 + +" This global variable is used internally by ALE for tracking information for +" each buffer which linters are being run against. +let g:ale_buffer_info = {} +" This global Dictionary tracks data for fixing code. Don't mess with it. +let g:ale_fix_buffer_data = {} + +" User Configuration + +" This option prevents ALE autocmd commands from being run for particular +" filetypes which can cause issues. +let g:ale_filetype_blacklist = [ +\ 'dirvish', +\ 'nerdtree', +\ 'qf', +\ 'tags', +\ 'unite', +\] + +" This Dictionary configures which linters are enabled for which languages. +let g:ale_linters = get(g:, 'ale_linters', {}) +" This option can be changed to only enable explicitly selected linters. +let g:ale_linters_explicit = get(g:, 'ale_linters_explicit', 0) + +" This Dictionary configures which functions will be used for fixing problems. +let g:ale_fixers = get(g:, 'ale_fixers', {}) + +" This Dictionary allows users to set up filetype aliases for new filetypes. +let g:ale_linter_aliases = get(g:, 'ale_linter_aliases', {}) + +" This flag can be set with a number of milliseconds for delaying the +" execution of a linter when text is changed. The timeout will be set and +" cleared each time text is changed, so repeated edits won't trigger the +" jobs for linting until enough time has passed after editing is done. +let g:ale_lint_delay = get(g:, 'ale_lint_delay', 200) + +" This flag can be set to 'never' to disable linting when text is changed. +" This flag can also be set to 'always' or 'insert' to lint when text is +" changed in both normal and insert mode, or only in insert mode respectively. +let g:ale_lint_on_text_changed = get(g:, 'ale_lint_on_text_changed', 'normal') + +" This flag can be set to 1 to enable linting when leaving insert mode. +let g:ale_lint_on_insert_leave = get(g:, 'ale_lint_on_insert_leave', 1) + +" This flag can be set to 0 to disable linting when the buffer is entered. +let g:ale_lint_on_enter = get(g:, 'ale_lint_on_enter', 1) + +" This flag can be set to 1 to enable linting when a buffer is written. +let g:ale_lint_on_save = get(g:, 'ale_lint_on_save', 1) + +" This flag can be set to 1 to enable linting when the filetype is changed. +let g:ale_lint_on_filetype_changed = get(g:, 'ale_lint_on_filetype_changed', 1) + +" This Dictionary configures the default LSP roots for various linters. +let g:ale_lsp_root = get(g:, 'ale_lsp_root', {}) + +" This flag can be set to 1 to enable automatically fixing files on save. +let g:ale_fix_on_save = get(g:, 'ale_fix_on_save', 0) + +" This flag may be set to 0 to disable ale. After ale is loaded, :ALEToggle +" should be used instead. +let g:ale_enabled = get(g:, 'ale_enabled', 1) + +" These flags dictates if ale uses the quickfix or the loclist (loclist is the +" default, quickfix overrides loclist). +let g:ale_set_loclist = get(g:, 'ale_set_loclist', 1) +let g:ale_set_quickfix = get(g:, 'ale_set_quickfix', 0) + +" This flag can be set to 0 to disable setting signs. +" This is enabled by default only if the 'signs' feature exists. +let g:ale_set_signs = get(g:, 'ale_set_signs', has('signs')) + +" This flag can be set to 0 to disable setting error highlights. +let g:ale_set_highlights = get(g:, 'ale_set_highlights', has('syntax')) + +" This flag can be set to 0 to disable echoing when the cursor moves. +let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', 1) + +" This flag can be set to 1 to automatically show errors in the preview window. +let g:ale_cursor_detail = get(g:, 'ale_cursor_detail', 0) + +" This flag can be set to 1 to enable virtual text when the cursor moves. +let g:ale_virtualtext_cursor = get(g:, 'ale_virtualtext_cursor', 0) + +" This flag can be set to 1 to automatically close the preview window upon +" entering Insert Mode. +let g:ale_close_preview_on_insert = get(g:, 'ale_close_preview_on_insert', 0) + +" This flag can be set to 0 to disable balloon support. +let g:ale_set_balloons = get(g:, 'ale_set_balloons', has('balloon_eval') && has('gui_running')) + +" This flag can be set to 0 to disable warnings for trailing whitespace +let g:ale_warn_about_trailing_whitespace = get(g:, 'ale_warn_about_trailing_whitespace', 1) +" This flag can be set to 0 to disable warnings for trailing blank lines +let g:ale_warn_about_trailing_blank_lines = get(g:, 'ale_warn_about_trailing_blank_lines', 1) + +" A flag for enabling or disabling the command history. +let g:ale_history_enabled = get(g:, 'ale_history_enabled', 1) + +" A flag for storing the full output of commands in the history. +let g:ale_history_log_output = get(g:, 'ale_history_log_output', 1) + +" Enable automatic completion with LSP servers and tsserver +let g:ale_completion_enabled = get(g:, 'ale_completion_enabled', 0) + +" Enable automatic detection of pipenv for Python linters. +let g:ale_python_auto_pipenv = get(g:, 'ale_python_auto_pipenv', 0) + +if g:ale_set_balloons + call ale#balloon#Enable() +endif + +if g:ale_completion_enabled + call ale#completion#Enable() +endif + +" Define commands for moving through warnings and errors. +command! -bar -nargs=* ALEPrevious +\ :call ale#loclist_jumping#WrapJump('before', ) +command! -bar -nargs=* ALENext +\ :call ale#loclist_jumping#WrapJump('after', ) + +command! -bar ALEPreviousWrap :call ale#loclist_jumping#Jump('before', 1) +command! -bar ALENextWrap :call ale#loclist_jumping#Jump('after', 1) +command! -bar ALEFirst :call ale#loclist_jumping#JumpToIndex(0) +command! -bar ALELast :call ale#loclist_jumping#JumpToIndex(-1) + +" A command for showing error details. +command! -bar ALEDetail :call ale#cursor#ShowCursorDetail() + +" Define commands for turning ALE on or off. +command! -bar ALEToggle :call ale#toggle#Toggle() +command! -bar ALEEnable :call ale#toggle#Enable() +command! -bar ALEDisable :call ale#toggle#Disable() +command! -bar ALEReset :call ale#toggle#Reset() +" Commands for turning ALE on or off for a buffer. +command! -bar ALEToggleBuffer :call ale#toggle#ToggleBuffer(bufnr('')) +command! -bar ALEEnableBuffer :call ale#toggle#EnableBuffer(bufnr('')) +command! -bar ALEDisableBuffer :call ale#toggle#DisableBuffer(bufnr('')) +command! -bar ALEResetBuffer :call ale#toggle#ResetBuffer(bufnr('')) +" A command to stop all LSP-like clients, including tsserver. +command! -bar ALEStopAllLSPs :call ale#lsp#reset#StopAllLSPs() + +" A command for linting manually. +command! -bar ALELint :call ale#Queue(0, 'lint_file') + +" Define a command to get information about current filetype. +command! -bar ALEInfo :call ale#debugging#Info() +" The same, but copy output to your clipboard. +command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboard() +" Copy ALE information to a file. +command! -bar -nargs=1 ALEInfoToFile :call ale#debugging#InfoToFile() + +" Fix problems in files. +command! -bar -nargs=* -complete=customlist,ale#fix#registry#CompleteFixers ALEFix :call ale#fix#Fix(bufnr(''), '', ) +" Suggest registered functions to use for fixing problems. +command! -bar ALEFixSuggest :call ale#fix#registry#Suggest(&filetype) + +" Go to definition for tsserver and LSP +command! -bar ALEGoToDefinition :call ale#definition#GoTo({}) +command! -bar ALEGoToDefinitionInTab :call ale#definition#GoTo({'open_in': 'tab'}) +command! -bar ALEGoToDefinitionInSplit :call ale#definition#GoTo({'open_in': 'horizontal-split'}) +command! -bar ALEGoToDefinitionInVSplit :call ale#definition#GoTo({'open_in': 'vertical-split'}) + +" Go to type definition for tsserver and LSP +command! -bar ALEGoToTypeDefinition :call ale#definition#GoToType({}) +command! -bar ALEGoToTypeDefinitionInTab :call ale#definition#GoToType({'open_in': 'tab'}) +command! -bar ALEGoToTypeDefinitionInSplit :call ale#definition#GoToType({'open_in': 'horizontal-split'}) +command! -bar ALEGoToTypeDefinitionInVSplit :call ale#definition#GoToType({'open_in': 'vertical-split'}) + +" Find references for tsserver and LSP +command! -bar -nargs=* ALEFindReferences :call ale#references#Find() + +" Show summary information for the cursor. +command! -bar ALEHover :call ale#hover#ShowAtCursor() + +" Show documentation for the cursor. +command! -bar ALEDocumentation :call ale#hover#ShowDocumentationAtCursor() + +" Search for appearances of a symbol, such as a type name or function name. +command! -nargs=1 ALESymbolSearch :call ale#symbol#Search() + +command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual') + +" mappings for commands +nnoremap (ale_previous) :ALEPrevious +nnoremap (ale_previous_wrap) :ALEPreviousWrap +nnoremap (ale_previous_error) :ALEPrevious -error +nnoremap (ale_previous_wrap_error) :ALEPrevious -wrap -error +nnoremap (ale_previous_warning) :ALEPrevious -warning +nnoremap (ale_previous_wrap_warning) :ALEPrevious -wrap -warning +nnoremap (ale_next) :ALENext +nnoremap (ale_next_wrap) :ALENextWrap +nnoremap (ale_next_error) :ALENext -error +nnoremap (ale_next_wrap_error) :ALENext -wrap -error +nnoremap (ale_next_warning) :ALENext -warning +nnoremap (ale_next_wrap_warning) :ALENext -wrap -warning +nnoremap (ale_first) :ALEFirst +nnoremap (ale_last) :ALELast +nnoremap (ale_toggle) :ALEToggle +nnoremap (ale_enable) :ALEEnable +nnoremap (ale_disable) :ALEDisable +nnoremap (ale_reset) :ALEReset +nnoremap (ale_toggle_buffer) :ALEToggleBuffer +nnoremap (ale_enable_buffer) :ALEEnableBuffer +nnoremap (ale_disable_buffer) :ALEDisableBuffer +nnoremap (ale_reset_buffer) :ALEResetBuffer +nnoremap (ale_lint) :ALELint +nnoremap (ale_detail) :ALEDetail +nnoremap (ale_fix) :ALEFix +nnoremap (ale_go_to_definition) :ALEGoToDefinition +nnoremap (ale_go_to_definition_in_tab) :ALEGoToDefinitionInTab +nnoremap (ale_go_to_definition_in_split) :ALEGoToDefinitionInSplit +nnoremap (ale_go_to_definition_in_vsplit) :ALEGoToDefinitionInVSplit +nnoremap (ale_go_to_type_definition) :ALEGoToTypeDefinition +nnoremap (ale_go_to_type_definition_in_tab) :ALEGoToTypeDefinitionInTab +nnoremap (ale_go_to_type_definition_in_split) :ALEGoToTypeDefinitionInSplit +nnoremap (ale_go_to_type_definition_in_vsplit) :ALEGoToTypeDefinitionInVSplit +nnoremap (ale_find_references) :ALEFindReferences +nnoremap (ale_hover) :ALEHover +nnoremap (ale_documentation) :ALEDocumentation +inoremap (ale_complete) :ALEComplete + +" Set up autocmd groups now. +call ale#events#Init() + +" Housekeeping + +augroup ALECleanupGroup + autocmd! + " Clean up buffers automatically when they are unloaded. + autocmd BufDelete * if exists('*ale#engine#Cleanup') | call ale#engine#Cleanup(str2nr(expand(''))) | endif + autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand(''))) + + if exists('##VimSuspend') + autocmd VimSuspend * if exists('*ale#engine#CleanupEveryBuffer') | call ale#engine#CleanupEveryBuffer() | endif + endif +augroup END diff --git a/pack/acp/start/ale/rplugin/python3/deoplete/sources/ale.py b/pack/acp/start/ale/rplugin/python3/deoplete/sources/ale.py new file mode 100644 index 0000000..7ed2f6c --- /dev/null +++ b/pack/acp/start/ale/rplugin/python3/deoplete/sources/ale.py @@ -0,0 +1,54 @@ +""" +A Deoplete source for ALE completion via tsserver and LSP. +""" +__author__ = 'Joao Paulo, w0rp' + +try: + from deoplete.source.base import Base +except ImportError: + # Mock the Base class if deoplete isn't available, as mock isn't available + # in the Docker image. + class Base(object): + def __init__(self, vim): + pass + + +# Make sure this code is valid in Python 2, used for running unit tests. +class Source(Base): + + def __init__(self, vim): + super(Source, self).__init__(vim) + + self.name = 'ale' + self.mark = '[L]' + self.rank = 100 + self.is_bytepos = True + self.min_pattern_length = 1 + + # Returns an integer for the start position, as with omnifunc. + def get_completion_position(self): + return self.vim.call('ale#completion#GetCompletionPosition') + + def gather_candidates(self, context): + # Stop early if ALE can't provide completion data for this buffer. + if not self.vim.call('ale#completion#CanProvideCompletions'): + return None + + if context.get('is_refresh'): + context['is_async'] = False + + if context['is_async']: + # Result is the same as for omnifunc, or None. + result = self.vim.call('ale#completion#GetCompletionResult') + + if result is not None: + context['is_async'] = False + + return result + else: + context['is_async'] = True + + # Request some completion results. + self.vim.call('ale#completion#GetCompletions', 'deoplete') + + return [] diff --git a/pack/acp/start/ale/supported-tools.md b/pack/acp/start/ale/supported-tools.md new file mode 100644 index 0000000..8af79f7 --- /dev/null +++ b/pack/acp/start/ale/supported-tools.md @@ -0,0 +1,497 @@ +# ALE 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. + + + +**Legend** + +| Key | Definition | +| ------------- | -------------------------------- | +| :floppy_disk: | Only checked when saved to disk | +| :warning: | Disabled by default | + +--- + +* Ada + * [gcc](https://gcc.gnu.org) +* Ansible + * [ansible-lint](https://github.com/willthames/ansible-lint) +* API Blueprint + * [drafter](https://github.com/apiaryio/drafter) +* AsciiDoc + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [proselint](http://proselint.com/) + * [redpen](http://redpen.cc/) + * [textlint](https://textlint.github.io/) + * [vale](https://github.com/ValeLint/vale) + * [write-good](https://github.com/btford/write-good) +* ASM + * [gcc](https://gcc.gnu.org) +* Awk + * [gawk](https://www.gnu.org/software/gawk/) +* Bash + * [language-server](https://github.com/mads-hartmann/bash-language-server) + * shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set) + * [shellcheck](https://www.shellcheck.net/) + * [shfmt](https://github.com/mvdan/sh) +* BibTeX + * [bibclean](http://ftp.math.utah.edu/pub/bibclean/) +* Bourne Shell + * shell [-n flag](http://linux.die.net/man/1/sh) + * [shellcheck](https://www.shellcheck.net/) + * [shfmt](https://github.com/mvdan/sh) +* C + * [ccls](https://github.com/MaskRay/ccls) + * [clang](http://clang.llvm.org/) + * [clangd](https://clang.llvm.org/extra/clangd.html) + * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) + * [clangtidy](http://clang.llvm.org/extra/clang-tidy/) :floppy_disk: + * [cppcheck](http://cppcheck.sourceforge.net) + * [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) + * [cquery](https://github.com/cquery-project/cquery) + * [flawfinder](https://www.dwheeler.com/flawfinder/) + * [gcc](https://gcc.gnu.org/) + * [uncrustify](https://github.com/uncrustify/uncrustify) +* C# + * [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details + * [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) :floppy_disk: see:`help ale-cs-mcsc` for details and configuration + * [uncrustify](https://github.com/uncrustify/uncrustify) +* C++ (filetype cpp) + * [ccls](https://github.com/MaskRay/ccls) + * [clang](http://clang.llvm.org/) + * [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) :floppy_disk: + * [clangd](https://clang.llvm.org/extra/clangd.html) + * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) + * [clangtidy](http://clang.llvm.org/extra/clang-tidy/) :floppy_disk: + * [clazy](https://github.com/KDE/clazy) :floppy_disk: + * [cppcheck](http://cppcheck.sourceforge.net) + * [cpplint](https://github.com/google/styleguide/tree/gh-pages/cpplint) :floppy_disk: + * [cquery](https://github.com/cquery-project/cquery) + * [flawfinder](https://www.dwheeler.com/flawfinder/) + * [gcc](https://gcc.gnu.org/) + * [uncrustify](https://github.com/uncrustify/uncrustify) +* Chef + * [cookstyle](https://docs.chef.io/cookstyle.html) + * [foodcritic](http://www.foodcritic.io/) +* Clojure + * [clj-kondo](https://github.com/borkdude/clj-kondo) + * [joker](https://github.com/candid82/joker) +* CloudFormation + * [cfn-python-lint](https://github.com/awslabs/cfn-python-lint) +* CMake + * [cmake-format](https://github.com/cheshirekow/cmake_format) + * [cmakelint](https://github.com/richq/cmake-lint) +* CoffeeScript + * [coffee](http://coffeescript.org/) + * [coffeelint](https://www.npmjs.com/package/coffeelint) +* Crystal + * [ameba](https://github.com/veelenga/ameba) :floppy_disk: + * [crystal](https://crystal-lang.org/) :floppy_disk: +* CSS + * [csslint](http://csslint.net/) + * [fecs](http://fecs.baidu.com/) + * [prettier](https://github.com/prettier/prettier) + * [stylelint](https://github.com/stylelint/stylelint) +* Cucumber + * [cucumber](https://cucumber.io/) +* CUDA + * [nvcc](http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html) +* Cypher + * [cypher-lint](https://github.com/cleishm/libcypher-parser) +* Cython (pyrex filetype) + * [cython](http://cython.org/) +* D + * [dls](https://github.com/d-language-server/dls) + * [dmd](https://dlang.org/dmd-linux.html) + * [uncrustify](https://github.com/uncrustify/uncrustify) +* Dafny + * [dafny](https://rise4fun.com/Dafny) :floppy_disk: +* Dart + * [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) :floppy_disk: + * [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) + * [language_server](https://github.com/natebosch/dart_language_server) +* Dockerfile + * [dockerfile_lint](https://github.com/projectatomic/dockerfile_lint) + * [hadolint](https://github.com/hadolint/hadolint) +* Elixir + * [credo](https://github.com/rrrene/credo) + * [dialyxir](https://github.com/jeremyjh/dialyxir) + * [dogma](https://github.com/lpil/dogma) + * [elixir-ls](https://github.com/JakeBecker/elixir-ls) :warning: + * [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk: +* Elm + * [elm-format](https://github.com/avh4/elm-format) + * [elm-lsp](https://github.com/antew/elm-lsp) + * [elm-make](https://github.com/elm-lang/elm-make) +* Erb + * [erb](https://apidock.com/ruby/ERB) + * [erubi](https://github.com/jeremyevans/erubi) + * [erubis](https://github.com/kwatch/erubis) + * [ruumba](https://github.com/ericqweinstein/ruumba) +* Erlang + * [erlc](http://erlang.org/doc/man/erlc.html) + * [SyntaxErl](https://github.com/ten0s/syntaxerl) +* Fish + * fish [-n flag](https://linux.die.net/man/1/fish) +* Fortran + * [gcc](https://gcc.gnu.org/) + * [language_server](https://github.com/hansec/fortran-language-server) +* Fountain + * [proselint](http://proselint.com/) +* FusionScript + * [fusion-lint](https://github.com/RyanSquared/fusionscript) +* Git Commit Messages + * [gitlint](https://github.com/jorisroovers/gitlint) +* GLSL + * [glslang](https://github.com/KhronosGroup/glslang) + * [glslls](https://github.com/svenstaro/glsl-language-server) +* Go + * [bingo](https://github.com/saibing/bingo) :warning: + * [go build](https://golang.org/cmd/go/) :warning: :floppy_disk: + * [gofmt](https://golang.org/cmd/gofmt/) + * [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) :warning: + * [golangci-lint](https://github.com/golangci/golangci-lint) :warning: :floppy_disk: + * [golangserver](https://github.com/sourcegraph/go-langserver) :warning: + * [golint](https://godoc.org/github.com/golang/lint) + * [gometalinter](https://github.com/alecthomas/gometalinter) :warning: :floppy_disk: + * [go mod](https://golang.org/cmd/go/) :warning: :floppy_disk: + * [gopls](https://github.com/golang/go/wiki/gopls) :warning: + * [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) :warning: :floppy_disk: + * [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) :warning: :floppy_disk: + * [go vet](https://golang.org/cmd/vet/) :floppy_disk: + * [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) :warning: :floppy_disk: +* GraphQL + * [eslint](http://eslint.org/) + * [gqlint](https://github.com/happylinks/gqlint) + * [prettier](https://github.com/prettier/prettier) +* Hack + * [hack](http://hacklang.org/) + * [hackfmt](https://github.com/facebook/hhvm/tree/master/hphp/hack/hackfmt) + * [hhast](https://github.com/hhvm/hhast) :warning: (see `:help ale-integration-hack`) +* Haml + * [haml-lint](https://github.com/brigade/haml-lint) +* Handlebars + * [ember-template-lint](https://github.com/rwjblue/ember-template-lint) +* Haskell + * [brittany](https://github.com/lspitzner/brittany) + * [cabal-ghc](https://www.haskell.org/cabal/) + * [floskell](https://github.com/ennocramer/floskell) + * [ghc](https://www.haskell.org/ghc/) + * [ghc-mod](https://github.com/DanielG/ghc-mod) + * [hdevtools](https://hackage.haskell.org/package/hdevtools) + * [hfmt](https://github.com/danstiner/hfmt) + * [hie](https://github.com/haskell/haskell-ide-engine) + * [hlint](https://hackage.haskell.org/package/hlint) + * [stack-build](https://haskellstack.org/) :floppy_disk: + * [stack-ghc](https://haskellstack.org/) + * [stylish-haskell](https://github.com/jaspervdj/stylish-haskell) +* HCL + * [terraform-fmt](https://github.com/hashicorp/terraform) +* HTML + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [fecs](http://fecs.baidu.com/) + * [HTMLHint](http://htmlhint.com/) + * [prettier](https://github.com/prettier/prettier) + * [proselint](http://proselint.com/) + * [tidy](http://www.html-tidy.org/) + * [write-good](https://github.com/btford/write-good) +* Idris + * [idris](http://www.idris-lang.org/) +* ISPC + * [ispc](https://ispc.github.io/) :floppy_disk: +* Java + * [checkstyle](http://checkstyle.sourceforge.net) + * [eclipselsp](https://github.com/eclipse/eclipse.jdt.ls) + * [google-java-format](https://github.com/google/google-java-format) + * [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html) + * [javalsp](https://github.com/georgewfraser/vscode-javac) + * [PMD](https://pmd.github.io/) + * [uncrustify](https://github.com/uncrustify/uncrustify) +* JavaScript + * [eslint](http://eslint.org/) + * [fecs](http://fecs.baidu.com/) + * [flow](https://flowtype.org/) + * [jscs](http://jscs.info/) + * [jshint](http://jshint.com/) + * [prettier](https://github.com/prettier/prettier) + * [prettier-eslint](https://github.com/prettier/prettier-eslint-cli) + * [prettier-standard](https://github.com/sheerun/prettier-standard) + * [standard](http://standardjs.com/) + * [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29) + * [xo](https://github.com/sindresorhus/xo) +* JSON + * [fixjson](https://github.com/rhysd/fixjson) + * [jq](https://stedolan.github.io/jq/) + * [jsonlint](http://zaa.ch/jsonlint/) + * [prettier](https://github.com/prettier/prettier) +* Julia + * [languageserver](https://github.com/JuliaEditorSupport/LanguageServer.jl) +* Kotlin + * [kotlinc](https://kotlinlang.org) :floppy_disk: + * [ktlint](https://ktlint.github.io) :floppy_disk: + * [languageserver](https://github.com/fwcd/KotlinLanguageServer) see `:help ale-integration-kotlin` for configuration instructions +* LaTeX + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [chktex](http://www.nongnu.org/chktex/) + * [lacheck](https://www.ctan.org/pkg/lacheck) + * [proselint](http://proselint.com/) + * [redpen](http://redpen.cc/) + * [texlab](https://texlab.netlify.com) ([Rust rewrite](https://github.com/latex-lsp/texlab/tree/rust)) + * [textlint](https://textlint.github.io/) + * [vale](https://github.com/ValeLint/vale) + * [write-good](https://github.com/btford/write-good) +* Less + * [lessc](https://www.npmjs.com/package/less) + * [prettier](https://github.com/prettier/prettier) + * [stylelint](https://github.com/stylelint/stylelint) +* LLVM + * [llc](https://llvm.org/docs/CommandGuide/llc.html) +* Lua + * [luac](https://www.lua.org/manual/5.1/luac.html) + * [luacheck](https://github.com/mpeterv/luacheck) +* Mail + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [languagetool](https://languagetool.org/) :floppy_disk: + * [proselint](http://proselint.com/) + * [vale](https://github.com/ValeLint/vale) +* Make + * [checkmake](https://github.com/mrtazz/checkmake) +* Markdown + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [languagetool](https://languagetool.org/) :floppy_disk: + * [markdownlint](https://github.com/DavidAnson/markdownlint) :floppy_disk: + * [mdl](https://github.com/mivok/markdownlint) + * [prettier](https://github.com/prettier/prettier) + * [proselint](http://proselint.com/) + * [redpen](http://redpen.cc/) + * [remark-lint](https://github.com/wooorm/remark-lint) + * [textlint](https://textlint.github.io/) + * [vale](https://github.com/ValeLint/vale) + * [write-good](https://github.com/btford/write-good) +* MATLAB + * [mlint](https://www.mathworks.com/help/matlab/ref/mlint.html) +* Mercury + * [mmc](http://mercurylang.org) :floppy_disk: +* NASM + * [nasm](https://www.nasm.us/) :floppy_disk: +* Nim + * [nim check](https://nim-lang.org/docs/nimc.html) :floppy_disk: +* nix + * [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) +* nroff + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [proselint](http://proselint.com/) + * [write-good](https://github.com/btford/write-good) +* Objective-C + * [ccls](https://github.com/MaskRay/ccls) + * [clang](http://clang.llvm.org/) + * [clangd](https://clang.llvm.org/extra/clangd.html) + * [uncrustify](https://github.com/uncrustify/uncrustify) +* Objective-C++ + * [clang](http://clang.llvm.org/) + * [clangd](https://clang.llvm.org/extra/clangd.html) + * [uncrustify](https://github.com/uncrustify/uncrustify) +* OCaml + * [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions + * [ocamlformat](https://github.com/ocaml-ppx/ocamlformat) + * [ocp-indent](https://github.com/OCamlPro/ocp-indent) + * [ols](https://github.com/freebroccolo/ocaml-language-server) +* Pawn + * [uncrustify](https://github.com/uncrustify/uncrustify) +* Perl + * [perl -c](https://perl.org/) :warning: + * [perl-critic](https://metacpan.org/pod/Perl::Critic) + * [perltidy](https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy) +* Perl6 + * [perl6 -c](https://perl6.org) :warning: +* PHP + * [langserver](https://github.com/felixfbecker/php-language-server) + * [phan](https://github.com/phan/phan) see `:help ale-php-phan` to instructions + * [phpcbf](https://github.com/squizlabs/PHP_CodeSniffer) + * [phpcs](https://github.com/squizlabs/PHP_CodeSniffer) + * [php-cs-fixer](http://cs.sensiolabs.org/) + * [php -l](https://secure.php.net/) + * [phpmd](https://phpmd.org) + * [phpstan](https://github.com/phpstan/phpstan) + * [psalm](https://getpsalm.org) :floppy_disk: +* PO + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html) + * [proselint](http://proselint.com/) + * [write-good](https://github.com/btford/write-good) +* Pod + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [proselint](http://proselint.com/) + * [write-good](https://github.com/btford/write-good) +* Pony + * [ponyc](https://github.com/ponylang/ponyc) +* PowerShell + * [powershell](https://github.com/PowerShell/PowerShell) :floppy_disk + * [psscriptanalyzer](https://github.com/PowerShell/PSScriptAnalyzer) :floppy_disk +* Prolog + * [swipl](https://github.com/SWI-Prolog/swipl-devel) +* proto + * [protoc-gen-lint](https://github.com/ckaznocha/protoc-gen-lint) +* Pug + * [pug-lint](https://github.com/pugjs/pug-lint) +* Puppet + * [languageserver](https://github.com/lingua-pupuli/puppet-editor-services) + * [puppet](https://puppet.com) + * [puppet-lint](https://puppet-lint.com) +* Python + * [autopep8](https://github.com/hhatto/autopep8) + * [bandit](https://github.com/PyCQA/bandit) :warning: + * [black](https://github.com/ambv/black) + * [flake8](http://flake8.pycqa.org/en/latest/) + * [isort](https://github.com/timothycrosley/isort) + * [mypy](http://mypy-lang.org/) + * [prospector](https://github.com/PyCQA/prospector) :warning: + * [pycodestyle](https://github.com/PyCQA/pycodestyle) :warning: + * [pydocstyle](https://www.pydocstyle.org/) :warning: + * [pyflakes](https://github.com/PyCQA/pyflakes) + * [pylama](https://github.com/klen/pylama) :floppy_disk: + * [pylint](https://www.pylint.org/) :floppy_disk: + * [pyls](https://github.com/palantir/python-language-server) :warning: + * [pyre](https://github.com/facebook/pyre-check) :warning: + * [reorder-python-imports](https://github.com/asottile/reorder_python_imports) + * [vulture](https://github.com/jendrikseipp/vulture) :warning: :floppy_disk: + * [yapf](https://github.com/google/yapf) +* QML + * [qmlfmt](https://github.com/jesperhh/qmlfmt) + * [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) +* R + * [lintr](https://github.com/jimhester/lintr) + * [styler](https://github.com/r-lib/styler) +* Racket + * [raco](https://docs.racket-lang.org/raco/) +* ReasonML + * [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions + * [ols](https://github.com/freebroccolo/ocaml-language-server) + * [reason-language-server](https://github.com/jaredly/reason-language-server) + * [refmt](https://github.com/reasonml/reason-cli) +* reStructuredText + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [proselint](http://proselint.com/) + * [redpen](http://redpen.cc/) + * [rstcheck](https://github.com/myint/rstcheck) + * [textlint](https://textlint.github.io/) + * [vale](https://github.com/ValeLint/vale) + * [write-good](https://github.com/btford/write-good) +* Re:VIEW + * [redpen](http://redpen.cc/) +* RPM spec + * [rpmlint](https://github.com/rpm-software-management/rpmlint) :warning: (see `:help ale-integration-spec`) +* Ruby + * [brakeman](http://brakemanscanner.org/) :floppy_disk: + * [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) :floppy_disk: + * [reek](https://github.com/troessner/reek) + * [rubocop](https://github.com/bbatsov/rubocop) + * [ruby](https://www.ruby-lang.org) + * [rufo](https://github.com/ruby-formatter/rufo) + * [solargraph](https://solargraph.org) + * [standardrb](https://github.com/testdouble/standard) +* Rust + * [cargo](https://github.com/rust-lang/cargo) :floppy_disk: (see `:help ale-integration-rust` for configuration instructions) + * [rls](https://github.com/rust-lang-nursery/rls) :warning: + * [rustc](https://www.rust-lang.org/) :warning: + * [rustfmt](https://github.com/rust-lang-nursery/rustfmt) +* Sass + * [sass-lint](https://www.npmjs.com/package/sass-lint) + * [stylelint](https://github.com/stylelint/stylelint) +* Scala + * [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html) + * [sbtserver](https://www.scala-sbt.org/1.x/docs/sbt-server.html) + * [scalac](http://scala-lang.org) + * [scalafmt](https://scalameta.org/scalafmt/) + * [scalastyle](http://www.scalastyle.org) +* SCSS + * [prettier](https://github.com/prettier/prettier) + * [sass-lint](https://www.npmjs.com/package/sass-lint) + * [scss-lint](https://github.com/brigade/scss-lint) + * [stylelint](https://github.com/stylelint/stylelint) +* Slim + * [slim-lint](https://github.com/sds/slim-lint) +* SML + * [smlnj](http://www.smlnj.org/) +* Solidity + * [solhint](https://github.com/protofire/solhint) + * [solium](https://github.com/duaraghav8/Solium) +* SQL + * [pgformatter](https://github.com/darold/pgFormatter) + * [sqlfmt](https://github.com/jackc/sqlfmt) + * [sqlint](https://github.com/purcell/sqlint) +* Stylus + * [stylelint](https://github.com/stylelint/stylelint) +* SugarSS + * [stylelint](https://github.com/stylelint/stylelint) +* Swift + * [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) + * [swiftformat](https://github.com/nicklockwood/SwiftFormat) + * [swiftlint](https://github.com/realm/SwiftLint) +* Tcl + * [nagelfar](http://nagelfar.sourceforge.net) :floppy_disk: +* Terraform + * [fmt](https://github.com/hashicorp/terraform) + * [tflint](https://github.com/wata727/tflint) +* Texinfo + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [proselint](http://proselint.com/) + * [write-good](https://github.com/btford/write-good) +* Text + * [alex](https://github.com/wooorm/alex) :warning: :floppy_disk: + * [languagetool](https://languagetool.org/) :floppy_disk: + * [proselint](http://proselint.com/) :warning: + * [redpen](http://redpen.cc/) :warning: + * [textlint](https://textlint.github.io/) :warning: + * [vale](https://github.com/ValeLint/vale) :warning: + * [write-good](https://github.com/btford/write-good) :warning: +* Thrift + * [thrift](http://thrift.apache.org/) +* TypeScript + * [eslint](http://eslint.org/) + * [fecs](http://fecs.baidu.com/) + * [prettier](https://github.com/prettier/prettier) + * [tslint](https://github.com/palantir/tslint) + * [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29) + * typecheck +* VALA + * [uncrustify](https://github.com/uncrustify/uncrustify) +* Verilog + * [iverilog](https://github.com/steveicarus/iverilog) + * [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) + * [vlog](https://www.mentor.com/products/fv/questa/) + * [xvlog](https://www.xilinx.com/products/design-tools/vivado.html) +* VHDL + * [ghdl](https://github.com/ghdl/ghdl) + * [vcom](https://www.mentor.com/products/fv/questa/) + * [xvhdl](https://www.xilinx.com/products/design-tools/vivado.html) +* Vim + * [vint](https://github.com/Kuniwak/vint) +* Vim help + * [alex](https://github.com/wooorm/alex) :warning: :floppy_disk: + * [proselint](http://proselint.com/) :warning: + * [write-good](https://github.com/btford/write-good) :warning: +* Vue + * [prettier](https://github.com/prettier/prettier) + * [vls](https://github.com/vuejs/vetur/tree/master/server) +* XHTML + * [alex](https://github.com/wooorm/alex) :floppy_disk: + * [proselint](http://proselint.com/) + * [write-good](https://github.com/btford/write-good) +* XML + * [xmllint](http://xmlsoft.org/xmllint.html) +* YAML + * [prettier](https://github.com/prettier/prettier) + * [swaglint](https://github.com/byCedric/swaglint) + * [yamllint](https://yamllint.readthedocs.io/) +* YANG + * [yang-lsp](https://github.com/theia-ide/yang-lsp) diff --git a/pack/acp/start/ale/syntax/ale-fix-suggest.vim b/pack/acp/start/ale/syntax/ale-fix-suggest.vim new file mode 100644 index 0000000..b112f5b --- /dev/null +++ b/pack/acp/start/ale/syntax/ale-fix-suggest.vim @@ -0,0 +1,13 @@ +if exists('b:current_syntax') + finish +endif + +syn match aleFixerComment /^.*$/ +syn match aleFixerName /\(^\|, \)'[^']*'/ +syn match aleFixerHelp /^See :help ale-fix-configuration/ + +hi def link aleFixerComment Comment +hi def link aleFixerName String +hi def link aleFixerHelp Statement + +let b:current_syntax = 'ale-fix-suggest' diff --git a/pack/acp/start/ale/syntax/ale-preview-selection.vim b/pack/acp/start/ale/syntax/ale-preview-selection.vim new file mode 100644 index 0000000..879ba09 --- /dev/null +++ b/pack/acp/start/ale/syntax/ale-preview-selection.vim @@ -0,0 +1,11 @@ +if exists('b:current_syntax') + finish +endif + +syn match alePreviewSelectionFilename /\v^([a-zA-Z]?:?[^:]+)/ +syn match alPreviewNumber /\v:\d+:\d+$/ + +hi def link alePreviewSelectionFilename String +hi def link alePreviewNumber Number + +let b:current_syntax = 'ale-preview-selection' diff --git a/plugins.md b/plugins.md index 36634f7..42944f4 100644 --- a/plugins.md +++ b/plugins.md @@ -8,6 +8,7 @@ Git submodules are slow, so handle this manually. ## pack/acp/start/ +* [ale](https://github.com/dense-analysis/ale) * [goyo.vim](https://github.com/junegunn/goyo.vim) * [gruvbox](https://github.com/morhetz/gruvbox) * [limelight.vim](https://github.com/junegunn/limelight.vim) diff --git a/vimrc b/vimrc index b393481..b26a343 100644 --- a/vimrc +++ b/vimrc @@ -43,7 +43,6 @@ set autoread set background=dark set backspace=indent,eol,start set colorcolumn=79 -set complete-=i set directory=$TEMP//,/tmp//,. set display+=lastline set encoding=utf-8 @@ -61,7 +60,6 @@ set noexpandtab set nomodeline set nrformats-=octal set numberwidth=8 -set omnifunc=syntaxcomplete#Complete set relativenumber set ruler set sessionoptions-=options @@ -86,6 +84,8 @@ if has("eval") command W w command WQ wq filetype plugin indent on + let g:ale_completion_enabled=1 + let g:ale_sign_column_always=1 let g:go_version_warning=0 let g:netrw_altv=1 let g:netrw_banner=0